Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'ila-csum-neutral'

Tom Herbert says:

====================
ila: Support for checksum neutral translations

This patch set updates ILA to support draft-herbert-nvo3-ila-02. The
primary addition is support checksum neutral ILA translation.
This allows address to be performed and still keep any transport
layer checksums that include the addresses in their pseudo header to
still be correct without the translator needing to parse L4.

Other items are:
- Structures for ILA addresses, identifiers, locators
- Disallow translation on non-ILA addresses (check by
type in identifier).
- Change xlat (nf_input) to translates solely based
on matching locators not identifiers (since identifiers
are not obfuscated by checksum neutral).
- Side effect if above is that multiple ILA domains are
supported. Each local locator can map to a different
SIR address (ILA domain), and each domain defines its
own identifier space.

Tested: Ran TCP_RR with 200 cnxs. ILA performance is slightly better
than previously since we are not longer parsing L4 for checksum
handling. I amd seeing about 1% performance overhead. Also ran
TCP_STREAM and tested non-ILA address (type=0) are not translated.

v2: Fix compilation errors
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+259 -118
+7
include/uapi/linux/ila.h
··· 15 15 ILA_ATTR_IFINDEX, /* s32 */ 16 16 ILA_ATTR_DIR, /* u32 */ 17 17 ILA_ATTR_PAD, 18 + ILA_ATTR_CSUM_MODE, /* u8 */ 18 19 19 20 __ILA_ATTR_MAX, 20 21 }; ··· 35 34 36 35 #define ILA_DIR_IN (1 << 0) 37 36 #define ILA_DIR_OUT (1 << 1) 37 + 38 + enum { 39 + ILA_CSUM_ADJUST_TRANSPORT, 40 + ILA_CSUM_NEUTRAL_MAP, 41 + ILA_CSUM_NO_ACTION, 42 + }; 38 43 39 44 #endif /* _UAPI_LINUX_ILA_H */
+76 -3
net/ipv6/ila/ila.h
··· 23 23 #include <net/protocol.h> 24 24 #include <uapi/linux/ila.h> 25 25 26 + struct ila_locator { 27 + union { 28 + __u8 v8[8]; 29 + __be16 v16[4]; 30 + __be32 v32[2]; 31 + __be64 v64; 32 + }; 33 + }; 34 + 35 + struct ila_identifier { 36 + union { 37 + struct { 38 + #if defined(__LITTLE_ENDIAN_BITFIELD) 39 + u8 __space:4; 40 + u8 csum_neutral:1; 41 + u8 type:3; 42 + #elif defined(__BIG_ENDIAN_BITFIELD) 43 + u8 type:3; 44 + u8 csum_neutral:1; 45 + u8 __space:4; 46 + #else 47 + #error "Adjust your <asm/byteorder.h> defines" 48 + #endif 49 + u8 __space2[7]; 50 + }; 51 + __u8 v8[8]; 52 + __be16 v16[4]; 53 + __be32 v32[2]; 54 + __be64 v64; 55 + }; 56 + }; 57 + 58 + enum { 59 + ILA_ATYPE_IID = 0, 60 + ILA_ATYPE_LUID, 61 + ILA_ATYPE_VIRT_V4, 62 + ILA_ATYPE_VIRT_UNI_V6, 63 + ILA_ATYPE_VIRT_MULTI_V6, 64 + ILA_ATYPE_RSVD_1, 65 + ILA_ATYPE_RSVD_2, 66 + ILA_ATYPE_RSVD_3, 67 + }; 68 + 69 + #define CSUM_NEUTRAL_FLAG htonl(0x10000000) 70 + 71 + struct ila_addr { 72 + union { 73 + struct in6_addr addr; 74 + struct { 75 + struct ila_locator loc; 76 + struct ila_identifier ident; 77 + }; 78 + }; 79 + }; 80 + 81 + static inline struct ila_addr *ila_a2i(struct in6_addr *addr) 82 + { 83 + return (struct ila_addr *)addr; 84 + } 85 + 86 + static inline bool ila_addr_is_ila(struct ila_addr *iaddr) 87 + { 88 + return (iaddr->ident.type != ILA_ATYPE_IID); 89 + } 90 + 26 91 struct ila_params { 27 - __be64 locator; 28 - __be64 locator_match; 92 + struct ila_locator locator; 93 + struct ila_locator locator_match; 29 94 __wsum csum_diff; 95 + u8 csum_mode; 30 96 }; 31 97 32 98 static inline __wsum compute_csum_diff8(const __be32 *from, const __be32 *to) ··· 104 38 return csum_partial(diff, sizeof(diff), 0); 105 39 } 106 40 107 - void update_ipv6_locator(struct sk_buff *skb, struct ila_params *p); 41 + static inline bool ila_csum_neutral_set(struct ila_identifier ident) 42 + { 43 + return !!(ident.csum_neutral); 44 + } 45 + 46 + void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p); 47 + 48 + void ila_init_saved_csum(struct ila_params *p); 108 49 109 50 int ila_lwt_init(void); 110 51 void ila_lwt_fini(void);
+76 -5
net/ipv6/ila/ila_common.c
··· 15 15 16 16 static __wsum get_csum_diff(struct ipv6hdr *ip6h, struct ila_params *p) 17 17 { 18 - if (*(__be64 *)&ip6h->daddr == p->locator_match) 18 + struct ila_addr *iaddr = ila_a2i(&ip6h->daddr); 19 + 20 + if (p->locator_match.v64) 19 21 return p->csum_diff; 20 22 else 21 - return compute_csum_diff8((__be32 *)&ip6h->daddr, 23 + return compute_csum_diff8((__be32 *)&iaddr->loc, 22 24 (__be32 *)&p->locator); 23 25 } 24 26 25 - void update_ipv6_locator(struct sk_buff *skb, struct ila_params *p) 27 + static void ila_csum_do_neutral(struct ila_addr *iaddr, 28 + struct ila_params *p) 29 + { 30 + __sum16 *adjust = (__force __sum16 *)&iaddr->ident.v16[3]; 31 + __wsum diff, fval; 32 + 33 + /* Check if checksum adjust value has been cached */ 34 + if (p->locator_match.v64) { 35 + diff = p->csum_diff; 36 + } else { 37 + diff = compute_csum_diff8((__be32 *)iaddr, 38 + (__be32 *)&p->locator); 39 + } 40 + 41 + fval = (__force __wsum)(ila_csum_neutral_set(iaddr->ident) ? 42 + ~CSUM_NEUTRAL_FLAG : CSUM_NEUTRAL_FLAG); 43 + 44 + diff = csum_add(diff, fval); 45 + 46 + *adjust = ~csum_fold(csum_add(diff, csum_unfold(*adjust))); 47 + 48 + /* Flip the csum-neutral bit. Either we are doing a SIR->ILA 49 + * translation with ILA_CSUM_NEUTRAL_MAP as the csum_method 50 + * and the C-bit is not set, or we are doing an ILA-SIR 51 + * tranlsation and the C-bit is set. 52 + */ 53 + iaddr->ident.csum_neutral ^= 1; 54 + } 55 + 56 + static void ila_csum_adjust_transport(struct sk_buff *skb, 57 + struct ila_params *p) 26 58 { 27 59 __wsum diff; 28 60 struct ipv6hdr *ip6h = ipv6_hdr(skb); 61 + struct ila_addr *iaddr = ila_a2i(&ip6h->daddr); 29 62 size_t nhoff = sizeof(struct ipv6hdr); 30 63 31 - /* First update checksum */ 32 64 switch (ip6h->nexthdr) { 33 65 case NEXTHDR_TCP: 34 66 if (likely(pskb_may_pull(skb, nhoff + sizeof(struct tcphdr)))) { ··· 100 68 } 101 69 102 70 /* Now change destination address */ 103 - *(__be64 *)&ip6h->daddr = p->locator; 71 + iaddr->loc = p->locator; 72 + } 73 + 74 + void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p) 75 + { 76 + struct ipv6hdr *ip6h = ipv6_hdr(skb); 77 + struct ila_addr *iaddr = ila_a2i(&ip6h->daddr); 78 + 79 + /* First deal with the transport checksum */ 80 + if (ila_csum_neutral_set(iaddr->ident)) { 81 + /* C-bit is set in the locator indicating that this 82 + * is a locator being translated to a SIR address. 83 + * Perform (receiver) checksum-neutral translation. 84 + */ 85 + ila_csum_do_neutral(iaddr, p); 86 + } else { 87 + switch (p->csum_mode) { 88 + case ILA_CSUM_ADJUST_TRANSPORT: 89 + ila_csum_adjust_transport(skb, p); 90 + break; 91 + case ILA_CSUM_NEUTRAL_MAP: 92 + ila_csum_do_neutral(iaddr, p); 93 + break; 94 + case ILA_CSUM_NO_ACTION: 95 + break; 96 + } 97 + } 98 + 99 + /* Now change destination address */ 100 + iaddr->loc = p->locator; 101 + } 102 + 103 + void ila_init_saved_csum(struct ila_params *p) 104 + { 105 + if (!p->locator_match.v64) 106 + return; 107 + 108 + p->csum_diff = compute_csum_diff8( 109 + (__be32 *)&p->locator_match, 110 + (__be32 *)&p->locator); 104 111 } 105 112 106 113 static int __init ila_init(void)
+36 -13
net/ipv6/ila/ila_lwt.c
··· 26 26 if (skb->protocol != htons(ETH_P_IPV6)) 27 27 goto drop; 28 28 29 - update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate)); 29 + ila_update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate)); 30 30 31 31 return dst->lwtstate->orig_output(net, sk, skb); 32 32 ··· 42 42 if (skb->protocol != htons(ETH_P_IPV6)) 43 43 goto drop; 44 44 45 - update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate)); 45 + ila_update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate)); 46 46 47 47 return dst->lwtstate->orig_input(skb); 48 48 ··· 53 53 54 54 static struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = { 55 55 [ILA_ATTR_LOCATOR] = { .type = NLA_U64, }, 56 + [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, }, 56 57 }; 57 58 58 59 static int ila_build_state(struct net_device *dev, struct nlattr *nla, ··· 65 64 size_t encap_len = sizeof(*p); 66 65 struct lwtunnel_state *newts; 67 66 const struct fib6_config *cfg6 = cfg; 67 + struct ila_addr *iaddr; 68 68 int ret; 69 69 70 70 if (family != AF_INET6) 71 71 return -EINVAL; 72 + 73 + if (cfg6->fc_dst_len < sizeof(struct ila_locator) + 1) { 74 + /* Need to have full locator and at least type field 75 + * included in destination 76 + */ 77 + return -EINVAL; 78 + } 79 + 80 + iaddr = (struct ila_addr *)&cfg6->fc_dst; 81 + 82 + if (!ila_addr_is_ila(iaddr) || ila_csum_neutral_set(iaddr->ident)) { 83 + /* Don't allow translation for a non-ILA address or checksum 84 + * neutral flag to be set. 85 + */ 86 + return -EINVAL; 87 + } 72 88 73 89 ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla, 74 90 ila_nl_policy); ··· 102 84 newts->len = encap_len; 103 85 p = ila_params_lwtunnel(newts); 104 86 105 - p->locator = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]); 87 + p->locator.v64 = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]); 106 88 107 - if (cfg6->fc_dst_len > sizeof(__be64)) { 108 - /* Precompute checksum difference for translation since we 109 - * know both the old locator and the new one. 110 - */ 111 - p->locator_match = *(__be64 *)&cfg6->fc_dst; 112 - p->csum_diff = compute_csum_diff8( 113 - (__be32 *)&p->locator_match, (__be32 *)&p->locator); 114 - } 89 + /* Precompute checksum difference for translation since we 90 + * know both the old locator and the new one. 91 + */ 92 + p->locator_match = iaddr->loc; 93 + p->csum_diff = compute_csum_diff8( 94 + (__be32 *)&p->locator_match, (__be32 *)&p->locator); 95 + 96 + if (tb[ILA_ATTR_CSUM_MODE]) 97 + p->csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]); 98 + 99 + ila_init_saved_csum(p); 115 100 116 101 newts->type = LWTUNNEL_ENCAP_ILA; 117 102 newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT | ··· 130 109 { 131 110 struct ila_params *p = ila_params_lwtunnel(lwtstate); 132 111 133 - if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator, 112 + if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator.v64, 134 113 ILA_ATTR_PAD)) 114 + goto nla_put_failure; 115 + if (nla_put_u64(skb, ILA_ATTR_CSUM_MODE, (__force u8)p->csum_mode)) 135 116 goto nla_put_failure; 136 117 137 118 return 0; ··· 153 130 struct ila_params *a_p = ila_params_lwtunnel(a); 154 131 struct ila_params *b_p = ila_params_lwtunnel(b); 155 132 156 - return (a_p->locator != b_p->locator); 133 + return (a_p->locator.v64 != b_p->locator.v64); 157 134 } 158 135 159 136 static const struct lwtunnel_encap_ops ila_encap_ops = {
+64 -97
net/ipv6/ila/ila_xlat.c
··· 11 11 12 12 struct ila_xlat_params { 13 13 struct ila_params ip; 14 - __be64 identifier; 15 14 int ifindex; 16 - unsigned int dir; 17 15 }; 18 16 19 17 struct ila_map { 20 - struct ila_xlat_params p; 18 + struct ila_xlat_params xp; 21 19 struct rhash_head node; 22 20 struct ila_map __rcu *next; 23 21 struct rcu_head rcu; ··· 64 66 net_get_random_once(&hashrnd, sizeof(hashrnd)); 65 67 } 66 68 67 - static inline u32 ila_identifier_hash(__be64 identifier) 69 + static inline u32 ila_locator_hash(struct ila_locator loc) 68 70 { 69 - u32 *v = (u32 *)&identifier; 71 + u32 *v = (u32 *)loc.v32; 70 72 71 73 return jhash_2words(v[0], v[1], hashrnd); 72 74 } 73 75 74 - static inline spinlock_t *ila_get_lock(struct ila_net *ilan, __be64 identifier) 76 + static inline spinlock_t *ila_get_lock(struct ila_net *ilan, 77 + struct ila_locator loc) 75 78 { 76 - return &ilan->locks[ila_identifier_hash(identifier) & ilan->locks_mask]; 79 + return &ilan->locks[ila_locator_hash(loc) & ilan->locks_mask]; 77 80 } 78 81 79 - static inline int ila_cmp_wildcards(struct ila_map *ila, __be64 loc, 80 - int ifindex, unsigned int dir) 82 + static inline int ila_cmp_wildcards(struct ila_map *ila, 83 + struct ila_addr *iaddr, int ifindex) 81 84 { 82 - return (ila->p.ip.locator_match && ila->p.ip.locator_match != loc) || 83 - (ila->p.ifindex && ila->p.ifindex != ifindex) || 84 - !(ila->p.dir & dir); 85 + return (ila->xp.ifindex && ila->xp.ifindex != ifindex); 85 86 } 86 87 87 - static inline int ila_cmp_params(struct ila_map *ila, struct ila_xlat_params *p) 88 + static inline int ila_cmp_params(struct ila_map *ila, 89 + struct ila_xlat_params *xp) 88 90 { 89 - return (ila->p.ip.locator_match != p->ip.locator_match) || 90 - (ila->p.ifindex != p->ifindex) || 91 - (ila->p.dir != p->dir); 91 + return (ila->xp.ifindex != xp->ifindex); 92 92 } 93 93 94 94 static int ila_cmpfn(struct rhashtable_compare_arg *arg, ··· 94 98 { 95 99 const struct ila_map *ila = obj; 96 100 97 - return (ila->p.identifier != *(__be64 *)arg->key); 101 + return (ila->xp.ip.locator_match.v64 != *(__be64 *)arg->key); 98 102 } 99 103 100 104 static inline int ila_order(struct ila_map *ila) 101 105 { 102 106 int score = 0; 103 107 104 - if (ila->p.ip.locator_match) 105 - score += 1 << 0; 106 - 107 - if (ila->p.ifindex) 108 + if (ila->xp.ifindex) 108 109 score += 1 << 1; 109 110 110 111 return score; ··· 110 117 static const struct rhashtable_params rht_params = { 111 118 .nelem_hint = 1024, 112 119 .head_offset = offsetof(struct ila_map, node), 113 - .key_offset = offsetof(struct ila_map, p.identifier), 120 + .key_offset = offsetof(struct ila_map, xp.ip.locator_match), 114 121 .key_len = sizeof(u64), /* identifier */ 115 122 .max_size = 1048576, 116 123 .min_size = 256, ··· 129 136 }; 130 137 131 138 static struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = { 132 - [ILA_ATTR_IDENTIFIER] = { .type = NLA_U64, }, 133 139 [ILA_ATTR_LOCATOR] = { .type = NLA_U64, }, 134 140 [ILA_ATTR_LOCATOR_MATCH] = { .type = NLA_U64, }, 135 141 [ILA_ATTR_IFINDEX] = { .type = NLA_U32, }, 136 - [ILA_ATTR_DIR] = { .type = NLA_U32, }, 142 + [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, }, 137 143 }; 138 144 139 145 static int parse_nl_config(struct genl_info *info, 140 - struct ila_xlat_params *p) 146 + struct ila_xlat_params *xp) 141 147 { 142 - memset(p, 0, sizeof(*p)); 143 - 144 - if (info->attrs[ILA_ATTR_IDENTIFIER]) 145 - p->identifier = (__force __be64)nla_get_u64( 146 - info->attrs[ILA_ATTR_IDENTIFIER]); 148 + memset(xp, 0, sizeof(*xp)); 147 149 148 150 if (info->attrs[ILA_ATTR_LOCATOR]) 149 - p->ip.locator = (__force __be64)nla_get_u64( 151 + xp->ip.locator.v64 = (__force __be64)nla_get_u64( 150 152 info->attrs[ILA_ATTR_LOCATOR]); 151 153 152 154 if (info->attrs[ILA_ATTR_LOCATOR_MATCH]) 153 - p->ip.locator_match = (__force __be64)nla_get_u64( 155 + xp->ip.locator_match.v64 = (__force __be64)nla_get_u64( 154 156 info->attrs[ILA_ATTR_LOCATOR_MATCH]); 155 157 156 - if (info->attrs[ILA_ATTR_IFINDEX]) 157 - p->ifindex = nla_get_s32(info->attrs[ILA_ATTR_IFINDEX]); 158 + if (info->attrs[ILA_ATTR_CSUM_MODE]) 159 + xp->ip.csum_mode = nla_get_u8(info->attrs[ILA_ATTR_CSUM_MODE]); 158 160 159 - if (info->attrs[ILA_ATTR_DIR]) 160 - p->dir = nla_get_u32(info->attrs[ILA_ATTR_DIR]); 161 + if (info->attrs[ILA_ATTR_IFINDEX]) 162 + xp->ifindex = nla_get_s32(info->attrs[ILA_ATTR_IFINDEX]); 161 163 162 164 return 0; 163 165 } 164 166 165 167 /* Must be called with rcu readlock */ 166 - static inline struct ila_map *ila_lookup_wildcards(__be64 id, __be64 loc, 168 + static inline struct ila_map *ila_lookup_wildcards(struct ila_addr *iaddr, 167 169 int ifindex, 168 - unsigned int dir, 169 170 struct ila_net *ilan) 170 171 { 171 172 struct ila_map *ila; 172 173 173 - ila = rhashtable_lookup_fast(&ilan->rhash_table, &id, rht_params); 174 + ila = rhashtable_lookup_fast(&ilan->rhash_table, &iaddr->loc, 175 + rht_params); 174 176 while (ila) { 175 - if (!ila_cmp_wildcards(ila, loc, ifindex, dir)) 177 + if (!ila_cmp_wildcards(ila, iaddr, ifindex)) 176 178 return ila; 177 179 ila = rcu_access_pointer(ila->next); 178 180 } ··· 176 188 } 177 189 178 190 /* Must be called with rcu readlock */ 179 - static inline struct ila_map *ila_lookup_by_params(struct ila_xlat_params *p, 191 + static inline struct ila_map *ila_lookup_by_params(struct ila_xlat_params *xp, 180 192 struct ila_net *ilan) 181 193 { 182 194 struct ila_map *ila; 183 195 184 - ila = rhashtable_lookup_fast(&ilan->rhash_table, &p->identifier, 196 + ila = rhashtable_lookup_fast(&ilan->rhash_table, 197 + &xp->ip.locator_match, 185 198 rht_params); 186 199 while (ila) { 187 - if (!ila_cmp_params(ila, p)) 200 + if (!ila_cmp_params(ila, xp)) 188 201 return ila; 189 202 ila = rcu_access_pointer(ila->next); 190 203 } ··· 210 221 } 211 222 } 212 223 213 - static int ila_xlat_addr(struct sk_buff *skb, int dir); 224 + static int ila_xlat_addr(struct sk_buff *skb); 214 225 215 226 static unsigned int 216 227 ila_nf_input(void *priv, 217 228 struct sk_buff *skb, 218 229 const struct nf_hook_state *state) 219 230 { 220 - ila_xlat_addr(skb, ILA_DIR_IN); 231 + ila_xlat_addr(skb); 221 232 return NF_ACCEPT; 222 233 } 223 234 ··· 230 241 }, 231 242 }; 232 243 233 - static int ila_add_mapping(struct net *net, struct ila_xlat_params *p) 244 + static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) 234 245 { 235 246 struct ila_net *ilan = net_generic(net, ila_net_id); 236 247 struct ila_map *ila, *head; 237 - spinlock_t *lock = ila_get_lock(ilan, p->identifier); 248 + spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match); 238 249 int err = 0, order; 239 250 240 251 if (!ilan->hooks_registered) { ··· 253 264 if (!ila) 254 265 return -ENOMEM; 255 266 256 - ila->p = *p; 267 + ila_init_saved_csum(&xp->ip); 257 268 258 - if (p->ip.locator_match) { 259 - /* Precompute checksum difference for translation since we 260 - * know both the old identifier and the new one. 261 - */ 262 - ila->p.ip.csum_diff = compute_csum_diff8( 263 - (__be32 *)&p->ip.locator_match, 264 - (__be32 *)&p->ip.locator); 265 - } 269 + ila->xp = *xp; 266 270 267 271 order = ila_order(ila); 268 272 269 273 spin_lock(lock); 270 274 271 - head = rhashtable_lookup_fast(&ilan->rhash_table, &p->identifier, 275 + head = rhashtable_lookup_fast(&ilan->rhash_table, 276 + &xp->ip.locator_match, 272 277 rht_params); 273 278 if (!head) { 274 279 /* New entry for the rhash_table */ ··· 272 289 struct ila_map *tila = head, *prev = NULL; 273 290 274 291 do { 275 - if (!ila_cmp_params(tila, p)) { 292 + if (!ila_cmp_params(tila, xp)) { 276 293 err = -EEXIST; 277 294 goto out; 278 295 } ··· 309 326 return err; 310 327 } 311 328 312 - static int ila_del_mapping(struct net *net, struct ila_xlat_params *p) 329 + static int ila_del_mapping(struct net *net, struct ila_xlat_params *xp) 313 330 { 314 331 struct ila_net *ilan = net_generic(net, ila_net_id); 315 332 struct ila_map *ila, *head, *prev; 316 - spinlock_t *lock = ila_get_lock(ilan, p->identifier); 333 + spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match); 317 334 int err = -ENOENT; 318 335 319 336 spin_lock(lock); 320 337 321 338 head = rhashtable_lookup_fast(&ilan->rhash_table, 322 - &p->identifier, rht_params); 339 + &xp->ip.locator_match, rht_params); 323 340 ila = head; 324 341 325 342 prev = NULL; 326 343 327 344 while (ila) { 328 - if (ila_cmp_params(ila, p)) { 345 + if (ila_cmp_params(ila, xp)) { 329 346 prev = ila; 330 347 ila = rcu_dereference_protected(ila->next, 331 348 lockdep_is_held(lock)); ··· 387 404 static int ila_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info) 388 405 { 389 406 struct net *net = genl_info_net(info); 390 - struct ila_xlat_params p; 407 + struct ila_xlat_params xp; 391 408 int err; 392 409 393 - err = parse_nl_config(info, &p); 410 + err = parse_nl_config(info, &xp); 394 411 if (err) 395 412 return err; 396 413 397 - ila_del_mapping(net, &p); 414 + ila_del_mapping(net, &xp); 398 415 399 416 return 0; 400 417 } 401 418 402 419 static int ila_fill_info(struct ila_map *ila, struct sk_buff *msg) 403 420 { 404 - if (nla_put_u64_64bit(msg, ILA_ATTR_IDENTIFIER, 405 - (__force u64)ila->p.identifier, 406 - ILA_ATTR_PAD) || 407 - nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR, 408 - (__force u64)ila->p.ip.locator, 421 + if (nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR, 422 + (__force u64)ila->xp.ip.locator.v64, 409 423 ILA_ATTR_PAD) || 410 424 nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR_MATCH, 411 - (__force u64)ila->p.ip.locator_match, 425 + (__force u64)ila->xp.ip.locator_match.v64, 412 426 ILA_ATTR_PAD) || 413 - nla_put_s32(msg, ILA_ATTR_IFINDEX, ila->p.ifindex) || 414 - nla_put_u32(msg, ILA_ATTR_DIR, ila->p.dir)) 427 + nla_put_s32(msg, ILA_ATTR_IFINDEX, ila->xp.ifindex) || 428 + nla_put_u32(msg, ILA_ATTR_CSUM_MODE, ila->xp.ip.csum_mode)) 415 429 return -1; 416 430 417 431 return 0; ··· 440 460 struct net *net = genl_info_net(info); 441 461 struct ila_net *ilan = net_generic(net, ila_net_id); 442 462 struct sk_buff *msg; 443 - struct ila_xlat_params p; 463 + struct ila_xlat_params xp; 444 464 struct ila_map *ila; 445 465 int ret; 446 466 447 - ret = parse_nl_config(info, &p); 467 + ret = parse_nl_config(info, &xp); 448 468 if (ret) 449 469 return ret; 450 470 ··· 454 474 455 475 rcu_read_lock(); 456 476 457 - ila = ila_lookup_by_params(&p, ilan); 477 + ila = ila_lookup_by_params(&xp, ilan); 458 478 if (ila) { 459 479 ret = ila_dump_info(ila, 460 480 info->snd_portid, ··· 597 617 .size = sizeof(struct ila_net), 598 618 }; 599 619 600 - static int ila_xlat_addr(struct sk_buff *skb, int dir) 620 + static int ila_xlat_addr(struct sk_buff *skb) 601 621 { 602 622 struct ila_map *ila; 603 623 struct ipv6hdr *ip6h = ipv6_hdr(skb); 604 624 struct net *net = dev_net(skb->dev); 605 625 struct ila_net *ilan = net_generic(net, ila_net_id); 606 - __be64 identifier, locator_match; 607 - size_t nhoff; 626 + struct ila_addr *iaddr = ila_a2i(&ip6h->daddr); 608 627 609 628 /* Assumes skb contains a valid IPv6 header that is pulled */ 610 629 611 - identifier = *(__be64 *)&ip6h->daddr.in6_u.u6_addr8[8]; 612 - locator_match = *(__be64 *)&ip6h->daddr.in6_u.u6_addr8[0]; 613 - nhoff = sizeof(struct ipv6hdr); 630 + if (!ila_addr_is_ila(iaddr)) { 631 + /* Type indicates this is not an ILA address */ 632 + return 0; 633 + } 614 634 615 635 rcu_read_lock(); 616 636 617 - ila = ila_lookup_wildcards(identifier, locator_match, 618 - skb->dev->ifindex, dir, ilan); 637 + ila = ila_lookup_wildcards(iaddr, skb->dev->ifindex, ilan); 619 638 if (ila) 620 - update_ipv6_locator(skb, &ila->p.ip); 639 + ila_update_ipv6_locator(skb, &ila->xp.ip); 621 640 622 641 rcu_read_unlock(); 623 642 624 643 return 0; 625 644 } 626 - 627 - int ila_xlat_incoming(struct sk_buff *skb) 628 - { 629 - return ila_xlat_addr(skb, ILA_DIR_IN); 630 - } 631 - EXPORT_SYMBOL(ila_xlat_incoming); 632 - 633 - int ila_xlat_outgoing(struct sk_buff *skb) 634 - { 635 - return ila_xlat_addr(skb, ILA_DIR_OUT); 636 - } 637 - EXPORT_SYMBOL(ila_xlat_outgoing); 638 645 639 646 int ila_xlat_init(void) 640 647 {