aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ila
diff options
context:
space:
mode:
authorTom Herbert <tom@herbertland.com>2016-04-23 14:46:55 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-26 01:25:22 -0400
commit351596aad54a7e07de63fde38496656514661b07 (patch)
tree215bc1012eddca60324250cb6d384a549babde50 /net/ipv6/ila
parenta843311d87b69540641d491b97b328309d3a28a1 (diff)
ila: Add struct definitions and helpers
Add structures for identifiers, locators, and an ila address which is composed of a locator and identifier and in6_addr can be cast to it. This includes a three bit type field and enums for the types defined in ILA I-D. In ILA lwt don't allow user to set a translation for a non-ILA address (type of identifier is zero meaning it is an IID). This also requires that the destination prefix is at least 65 bytes (64 bit locator and first byte of identifier). Signed-off-by: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ila')
-rw-r--r--net/ipv6/ila/ila.h67
-rw-r--r--net/ipv6/ila/ila_common.c11
-rw-r--r--net/ipv6/ila/ila_lwt.c39
-rw-r--r--net/ipv6/ila/ila_xlat.c126
4 files changed, 161 insertions, 82 deletions
diff --git a/net/ipv6/ila/ila.h b/net/ipv6/ila/ila.h
index 28542cb2b387..f532967d9ed7 100644
--- a/net/ipv6/ila/ila.h
+++ b/net/ipv6/ila/ila.h
@@ -23,9 +23,70 @@
23#include <net/protocol.h> 23#include <net/protocol.h>
24#include <uapi/linux/ila.h> 24#include <uapi/linux/ila.h>
25 25
26struct ila_locator {
27 union {
28 __u8 v8[8];
29 __be16 v16[4];
30 __be32 v32[2];
31 __be64 v64;
32 };
33};
34
35struct ila_identifier {
36 union {
37 struct {
38#if defined(__LITTLE_ENDIAN_BITFIELD)
39 u8 __space:5;
40 u8 type:3;
41#elif defined(__BIG_ENDIAN_BITFIELD)
42 u8 type:3;
43 u8 __space:5;
44#else
45#error "Adjust your <asm/byteorder.h> defines"
46#endif
47 u8 __space2[7];
48 };
49 __u8 v8[8];
50 __be16 v16[4];
51 __be32 v32[2];
52 __be64 v64;
53 };
54};
55
56enum {
57 ILA_ATYPE_IID = 0,
58 ILA_ATYPE_LUID,
59 ILA_ATYPE_VIRT_V4,
60 ILA_ATYPE_VIRT_UNI_V6,
61 ILA_ATYPE_VIRT_MULTI_V6,
62 ILA_ATYPE_RSVD_1,
63 ILA_ATYPE_RSVD_2,
64 ILA_ATYPE_RSVD_3,
65};
66
67struct ila_addr {
68 union {
69 struct in6_addr addr;
70 struct {
71 struct ila_locator loc;
72 struct ila_identifier ident;
73 };
74 };
75};
76
77static inline struct ila_addr *ila_a2i(struct in6_addr *addr)
78{
79 return (struct ila_addr *)addr;
80}
81
82static inline bool ila_addr_is_ila(struct ila_addr *iaddr)
83{
84 return (iaddr->ident.type != ILA_ATYPE_IID);
85}
86
26struct ila_params { 87struct ila_params {
27 __be64 locator; 88 struct ila_locator locator;
28 __be64 locator_match; 89 struct ila_locator locator_match;
29 __wsum csum_diff; 90 __wsum csum_diff;
30}; 91};
31 92
@@ -38,7 +99,7 @@ static inline __wsum compute_csum_diff8(const __be32 *from, const __be32 *to)
38 return csum_partial(diff, sizeof(diff), 0); 99 return csum_partial(diff, sizeof(diff), 0);
39} 100}
40 101
41void update_ipv6_locator(struct sk_buff *skb, struct ila_params *p); 102void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p);
42 103
43int ila_lwt_init(void); 104int ila_lwt_init(void);
44void ila_lwt_fini(void); 105void ila_lwt_fini(void);
diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c
index 30613050e4ca..c3078d0b64e1 100644
--- a/net/ipv6/ila/ila_common.c
+++ b/net/ipv6/ila/ila_common.c
@@ -15,17 +15,20 @@
15 15
16static __wsum get_csum_diff(struct ipv6hdr *ip6h, struct ila_params *p) 16static __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 (iaddr->loc.v64 == p->locator_match.v64)
19 return p->csum_diff; 21 return p->csum_diff;
20 else 22 else
21 return compute_csum_diff8((__be32 *)&ip6h->daddr, 23 return compute_csum_diff8((__be32 *)&iaddr->loc,
22 (__be32 *)&p->locator); 24 (__be32 *)&p->locator);
23} 25}
24 26
25void update_ipv6_locator(struct sk_buff *skb, struct ila_params *p) 27void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p)
26{ 28{
27 __wsum diff; 29 __wsum diff;
28 struct ipv6hdr *ip6h = ipv6_hdr(skb); 30 struct ipv6hdr *ip6h = ipv6_hdr(skb);
31 struct ila_addr *iaddr = ila_a2i(&ip6h->daddr);
29 size_t nhoff = sizeof(struct ipv6hdr); 32 size_t nhoff = sizeof(struct ipv6hdr);
30 33
31 /* First update checksum */ 34 /* First update checksum */
@@ -68,7 +71,7 @@ void update_ipv6_locator(struct sk_buff *skb, struct ila_params *p)
68 } 71 }
69 72
70 /* Now change destination address */ 73 /* Now change destination address */
71 *(__be64 *)&ip6h->daddr = p->locator; 74 iaddr->loc = p->locator;
72} 75}
73 76
74static int __init ila_init(void) 77static int __init ila_init(void)
diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c
index 9db3621b2126..de7f6d76e928 100644
--- a/net/ipv6/ila/ila_lwt.c
+++ b/net/ipv6/ila/ila_lwt.c
@@ -26,7 +26,7 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
26 if (skb->protocol != htons(ETH_P_IPV6)) 26 if (skb->protocol != htons(ETH_P_IPV6))
27 goto drop; 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 return dst->lwtstate->orig_output(net, sk, skb); 31 return dst->lwtstate->orig_output(net, sk, skb);
32 32
@@ -42,7 +42,7 @@ static int ila_input(struct sk_buff *skb)
42 if (skb->protocol != htons(ETH_P_IPV6)) 42 if (skb->protocol != htons(ETH_P_IPV6))
43 goto drop; 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 return dst->lwtstate->orig_input(skb); 47 return dst->lwtstate->orig_input(skb);
48 48
@@ -64,11 +64,26 @@ static int ila_build_state(struct net_device *dev, struct nlattr *nla,
64 size_t encap_len = sizeof(*p); 64 size_t encap_len = sizeof(*p);
65 struct lwtunnel_state *newts; 65 struct lwtunnel_state *newts;
66 const struct fib6_config *cfg6 = cfg; 66 const struct fib6_config *cfg6 = cfg;
67 struct ila_addr *iaddr;
67 int ret; 68 int ret;
68 69
69 if (family != AF_INET6) 70 if (family != AF_INET6)
70 return -EINVAL; 71 return -EINVAL;
71 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)) {
83 /* Don't allow setting a translation for a non-ILA address */
84 return -EINVAL;
85 }
86
72 ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla, 87 ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla,
73 ila_nl_policy); 88 ila_nl_policy);
74 if (ret < 0) 89 if (ret < 0)
@@ -84,16 +99,14 @@ static int ila_build_state(struct net_device *dev, struct nlattr *nla,
84 newts->len = encap_len; 99 newts->len = encap_len;
85 p = ila_params_lwtunnel(newts); 100 p = ila_params_lwtunnel(newts);
86 101
87 p->locator = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]); 102 p->locator.v64 = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]);
88 103
89 if (cfg6->fc_dst_len > sizeof(__be64)) { 104 /* Precompute checksum difference for translation since we
90 /* Precompute checksum difference for translation since we 105 * know both the old locator and the new one.
91 * know both the old locator and the new one. 106 */
92 */ 107 p->locator_match = iaddr->loc;
93 p->locator_match = *(__be64 *)&cfg6->fc_dst; 108 p->csum_diff = compute_csum_diff8(
94 p->csum_diff = compute_csum_diff8( 109 (__be32 *)&p->locator_match, (__be32 *)&p->locator);
95 (__be32 *)&p->locator_match, (__be32 *)&p->locator);
96 }
97 110
98 newts->type = LWTUNNEL_ENCAP_ILA; 111 newts->type = LWTUNNEL_ENCAP_ILA;
99 newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT | 112 newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT |
@@ -109,7 +122,7 @@ static int ila_fill_encap_info(struct sk_buff *skb,
109{ 122{
110 struct ila_params *p = ila_params_lwtunnel(lwtstate); 123 struct ila_params *p = ila_params_lwtunnel(lwtstate);
111 124
112 if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator, 125 if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator.v64,
113 ILA_ATTR_PAD)) 126 ILA_ATTR_PAD))
114 goto nla_put_failure; 127 goto nla_put_failure;
115 128
@@ -130,7 +143,7 @@ static int ila_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b)
130 struct ila_params *a_p = ila_params_lwtunnel(a); 143 struct ila_params *a_p = ila_params_lwtunnel(a);
131 struct ila_params *b_p = ila_params_lwtunnel(b); 144 struct ila_params *b_p = ila_params_lwtunnel(b);
132 145
133 return (a_p->locator != b_p->locator); 146 return (a_p->locator.v64 != b_p->locator.v64);
134} 147}
135 148
136static const struct lwtunnel_encap_ops ila_encap_ops = { 149static const struct lwtunnel_encap_ops ila_encap_ops = {
diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index 0e9e579410da..020153bc47f5 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -11,13 +11,13 @@
11 11
12struct ila_xlat_params { 12struct ila_xlat_params {
13 struct ila_params ip; 13 struct ila_params ip;
14 __be64 identifier; 14 struct ila_identifier identifier;
15 int ifindex; 15 int ifindex;
16 unsigned int dir; 16 unsigned int dir;
17}; 17};
18 18
19struct ila_map { 19struct ila_map {
20 struct ila_xlat_params p; 20 struct ila_xlat_params xp;
21 struct rhash_head node; 21 struct rhash_head node;
22 struct ila_map __rcu *next; 22 struct ila_map __rcu *next;
23 struct rcu_head rcu; 23 struct rcu_head rcu;
@@ -66,31 +66,35 @@ static __always_inline void __ila_hash_secret_init(void)
66 net_get_random_once(&hashrnd, sizeof(hashrnd)); 66 net_get_random_once(&hashrnd, sizeof(hashrnd));
67} 67}
68 68
69static inline u32 ila_identifier_hash(__be64 identifier) 69static inline u32 ila_identifier_hash(struct ila_identifier ident)
70{ 70{
71 u32 *v = (u32 *)&identifier; 71 u32 *v = (u32 *)ident.v32;
72 72
73 return jhash_2words(v[0], v[1], hashrnd); 73 return jhash_2words(v[0], v[1], hashrnd);
74} 74}
75 75
76static inline spinlock_t *ila_get_lock(struct ila_net *ilan, __be64 identifier) 76static inline spinlock_t *ila_get_lock(struct ila_net *ilan,
77 struct ila_identifier ident)
77{ 78{
78 return &ilan->locks[ila_identifier_hash(identifier) & ilan->locks_mask]; 79 return &ilan->locks[ila_identifier_hash(ident) & ilan->locks_mask];
79} 80}
80 81
81static inline int ila_cmp_wildcards(struct ila_map *ila, __be64 loc, 82static inline int ila_cmp_wildcards(struct ila_map *ila,
82 int ifindex, unsigned int dir) 83 struct ila_addr *iaddr, int ifindex,
84 unsigned int dir)
83{ 85{
84 return (ila->p.ip.locator_match && ila->p.ip.locator_match != loc) || 86 return (ila->xp.ip.locator_match.v64 &&
85 (ila->p.ifindex && ila->p.ifindex != ifindex) || 87 ila->xp.ip.locator_match.v64 != iaddr->loc.v64) ||
86 !(ila->p.dir & dir); 88 (ila->xp.ifindex && ila->xp.ifindex != ifindex) ||
89 !(ila->xp.dir & dir);
87} 90}
88 91
89static inline int ila_cmp_params(struct ila_map *ila, struct ila_xlat_params *p) 92static inline int ila_cmp_params(struct ila_map *ila,
93 struct ila_xlat_params *xp)
90{ 94{
91 return (ila->p.ip.locator_match != p->ip.locator_match) || 95 return (ila->xp.ip.locator_match.v64 != xp->ip.locator_match.v64) ||
92 (ila->p.ifindex != p->ifindex) || 96 (ila->xp.ifindex != xp->ifindex) ||
93 (ila->p.dir != p->dir); 97 (ila->xp.dir != xp->dir);
94} 98}
95 99
96static int ila_cmpfn(struct rhashtable_compare_arg *arg, 100static int ila_cmpfn(struct rhashtable_compare_arg *arg,
@@ -98,17 +102,17 @@ static int ila_cmpfn(struct rhashtable_compare_arg *arg,
98{ 102{
99 const struct ila_map *ila = obj; 103 const struct ila_map *ila = obj;
100 104
101 return (ila->p.identifier != *(__be64 *)arg->key); 105 return (ila->xp.identifier.v64 != *(__be64 *)arg->key);
102} 106}
103 107
104static inline int ila_order(struct ila_map *ila) 108static inline int ila_order(struct ila_map *ila)
105{ 109{
106 int score = 0; 110 int score = 0;
107 111
108 if (ila->p.ip.locator_match) 112 if (ila->xp.ip.locator_match.v64)
109 score += 1 << 0; 113 score += 1 << 0;
110 114
111 if (ila->p.ifindex) 115 if (ila->xp.ifindex)
112 score += 1 << 1; 116 score += 1 << 1;
113 117
114 return score; 118 return score;
@@ -117,7 +121,7 @@ static inline int ila_order(struct ila_map *ila)
117static const struct rhashtable_params rht_params = { 121static const struct rhashtable_params rht_params = {
118 .nelem_hint = 1024, 122 .nelem_hint = 1024,
119 .head_offset = offsetof(struct ila_map, node), 123 .head_offset = offsetof(struct ila_map, node),
120 .key_offset = offsetof(struct ila_map, p.identifier), 124 .key_offset = offsetof(struct ila_map, xp.identifier),
121 .key_len = sizeof(u64), /* identifier */ 125 .key_len = sizeof(u64), /* identifier */
122 .max_size = 1048576, 126 .max_size = 1048576,
123 .min_size = 256, 127 .min_size = 256,
@@ -144,42 +148,43 @@ static struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
144}; 148};
145 149
146static int parse_nl_config(struct genl_info *info, 150static int parse_nl_config(struct genl_info *info,
147 struct ila_xlat_params *p) 151 struct ila_xlat_params *xp)
148{ 152{
149 memset(p, 0, sizeof(*p)); 153 memset(xp, 0, sizeof(*xp));
150 154
151 if (info->attrs[ILA_ATTR_IDENTIFIER]) 155 if (info->attrs[ILA_ATTR_IDENTIFIER])
152 p->identifier = (__force __be64)nla_get_u64( 156 xp->identifier.v64 = (__force __be64)nla_get_u64(
153 info->attrs[ILA_ATTR_IDENTIFIER]); 157 info->attrs[ILA_ATTR_IDENTIFIER]);
154 158
155 if (info->attrs[ILA_ATTR_LOCATOR]) 159 if (info->attrs[ILA_ATTR_LOCATOR])
156 p->ip.locator = (__force __be64)nla_get_u64( 160 xp->ip.locator.v64 = (__force __be64)nla_get_u64(
157 info->attrs[ILA_ATTR_LOCATOR]); 161 info->attrs[ILA_ATTR_LOCATOR]);
158 162
159 if (info->attrs[ILA_ATTR_LOCATOR_MATCH]) 163 if (info->attrs[ILA_ATTR_LOCATOR_MATCH])
160 p->ip.locator_match = (__force __be64)nla_get_u64( 164 xp->ip.locator_match.v64 = (__force __be64)nla_get_u64(
161 info->attrs[ILA_ATTR_LOCATOR_MATCH]); 165 info->attrs[ILA_ATTR_LOCATOR_MATCH]);
162 166
163 if (info->attrs[ILA_ATTR_IFINDEX]) 167 if (info->attrs[ILA_ATTR_IFINDEX])
164 p->ifindex = nla_get_s32(info->attrs[ILA_ATTR_IFINDEX]); 168 xp->ifindex = nla_get_s32(info->attrs[ILA_ATTR_IFINDEX]);
165 169
166 if (info->attrs[ILA_ATTR_DIR]) 170 if (info->attrs[ILA_ATTR_DIR])
167 p->dir = nla_get_u32(info->attrs[ILA_ATTR_DIR]); 171 xp->dir = nla_get_u32(info->attrs[ILA_ATTR_DIR]);
168 172
169 return 0; 173 return 0;
170} 174}
171 175
172/* Must be called with rcu readlock */ 176/* Must be called with rcu readlock */
173static inline struct ila_map *ila_lookup_wildcards(__be64 id, __be64 loc, 177static inline struct ila_map *ila_lookup_wildcards(struct ila_addr *iaddr,
174 int ifindex, 178 int ifindex,
175 unsigned int dir, 179 unsigned int dir,
176 struct ila_net *ilan) 180 struct ila_net *ilan)
177{ 181{
178 struct ila_map *ila; 182 struct ila_map *ila;
179 183
180 ila = rhashtable_lookup_fast(&ilan->rhash_table, &id, rht_params); 184 ila = rhashtable_lookup_fast(&ilan->rhash_table, &iaddr->ident,
185 rht_params);
181 while (ila) { 186 while (ila) {
182 if (!ila_cmp_wildcards(ila, loc, ifindex, dir)) 187 if (!ila_cmp_wildcards(ila, iaddr, ifindex, dir))
183 return ila; 188 return ila;
184 ila = rcu_access_pointer(ila->next); 189 ila = rcu_access_pointer(ila->next);
185 } 190 }
@@ -188,15 +193,15 @@ static inline struct ila_map *ila_lookup_wildcards(__be64 id, __be64 loc,
188} 193}
189 194
190/* Must be called with rcu readlock */ 195/* Must be called with rcu readlock */
191static inline struct ila_map *ila_lookup_by_params(struct ila_xlat_params *p, 196static inline struct ila_map *ila_lookup_by_params(struct ila_xlat_params *xp,
192 struct ila_net *ilan) 197 struct ila_net *ilan)
193{ 198{
194 struct ila_map *ila; 199 struct ila_map *ila;
195 200
196 ila = rhashtable_lookup_fast(&ilan->rhash_table, &p->identifier, 201 ila = rhashtable_lookup_fast(&ilan->rhash_table, &xp->identifier,
197 rht_params); 202 rht_params);
198 while (ila) { 203 while (ila) {
199 if (!ila_cmp_params(ila, p)) 204 if (!ila_cmp_params(ila, xp))
200 return ila; 205 return ila;
201 ila = rcu_access_pointer(ila->next); 206 ila = rcu_access_pointer(ila->next);
202 } 207 }
@@ -241,11 +246,11 @@ static struct nf_hook_ops ila_nf_hook_ops[] __read_mostly = {
241 }, 246 },
242}; 247};
243 248
244static int ila_add_mapping(struct net *net, struct ila_xlat_params *p) 249static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp)
245{ 250{
246 struct ila_net *ilan = net_generic(net, ila_net_id); 251 struct ila_net *ilan = net_generic(net, ila_net_id);
247 struct ila_map *ila, *head; 252 struct ila_map *ila, *head;
248 spinlock_t *lock = ila_get_lock(ilan, p->identifier); 253 spinlock_t *lock = ila_get_lock(ilan, xp->identifier);
249 int err = 0, order; 254 int err = 0, order;
250 255
251 if (!ilan->hooks_registered) { 256 if (!ilan->hooks_registered) {
@@ -264,22 +269,22 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *p)
264 if (!ila) 269 if (!ila)
265 return -ENOMEM; 270 return -ENOMEM;
266 271
267 ila->p = *p; 272 ila->xp = *xp;
268 273
269 if (p->ip.locator_match) { 274 if (xp->ip.locator_match.v64) {
270 /* Precompute checksum difference for translation since we 275 /* Precompute checksum difference for translation since we
271 * know both the old identifier and the new one. 276 * know both the old identifier and the new one.
272 */ 277 */
273 ila->p.ip.csum_diff = compute_csum_diff8( 278 ila->xp.ip.csum_diff = compute_csum_diff8(
274 (__be32 *)&p->ip.locator_match, 279 (__be32 *)&xp->ip.locator_match,
275 (__be32 *)&p->ip.locator); 280 (__be32 *)&xp->ip.locator);
276 } 281 }
277 282
278 order = ila_order(ila); 283 order = ila_order(ila);
279 284
280 spin_lock(lock); 285 spin_lock(lock);
281 286
282 head = rhashtable_lookup_fast(&ilan->rhash_table, &p->identifier, 287 head = rhashtable_lookup_fast(&ilan->rhash_table, &xp->identifier,
283 rht_params); 288 rht_params);
284 if (!head) { 289 if (!head) {
285 /* New entry for the rhash_table */ 290 /* New entry for the rhash_table */
@@ -289,7 +294,7 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *p)
289 struct ila_map *tila = head, *prev = NULL; 294 struct ila_map *tila = head, *prev = NULL;
290 295
291 do { 296 do {
292 if (!ila_cmp_params(tila, p)) { 297 if (!ila_cmp_params(tila, xp)) {
293 err = -EEXIST; 298 err = -EEXIST;
294 goto out; 299 goto out;
295 } 300 }
@@ -326,23 +331,23 @@ out:
326 return err; 331 return err;
327} 332}
328 333
329static int ila_del_mapping(struct net *net, struct ila_xlat_params *p) 334static int ila_del_mapping(struct net *net, struct ila_xlat_params *xp)
330{ 335{
331 struct ila_net *ilan = net_generic(net, ila_net_id); 336 struct ila_net *ilan = net_generic(net, ila_net_id);
332 struct ila_map *ila, *head, *prev; 337 struct ila_map *ila, *head, *prev;
333 spinlock_t *lock = ila_get_lock(ilan, p->identifier); 338 spinlock_t *lock = ila_get_lock(ilan, xp->identifier);
334 int err = -ENOENT; 339 int err = -ENOENT;
335 340
336 spin_lock(lock); 341 spin_lock(lock);
337 342
338 head = rhashtable_lookup_fast(&ilan->rhash_table, 343 head = rhashtable_lookup_fast(&ilan->rhash_table,
339 &p->identifier, rht_params); 344 &xp->identifier, rht_params);
340 ila = head; 345 ila = head;
341 346
342 prev = NULL; 347 prev = NULL;
343 348
344 while (ila) { 349 while (ila) {
345 if (ila_cmp_params(ila, p)) { 350 if (ila_cmp_params(ila, xp)) {
346 prev = ila; 351 prev = ila;
347 ila = rcu_dereference_protected(ila->next, 352 ila = rcu_dereference_protected(ila->next,
348 lockdep_is_held(lock)); 353 lockdep_is_held(lock));
@@ -404,14 +409,14 @@ static int ila_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info)
404static int ila_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info) 409static int ila_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info)
405{ 410{
406 struct net *net = genl_info_net(info); 411 struct net *net = genl_info_net(info);
407 struct ila_xlat_params p; 412 struct ila_xlat_params xp;
408 int err; 413 int err;
409 414
410 err = parse_nl_config(info, &p); 415 err = parse_nl_config(info, &xp);
411 if (err) 416 if (err)
412 return err; 417 return err;
413 418
414 ila_del_mapping(net, &p); 419 ila_del_mapping(net, &xp);
415 420
416 return 0; 421 return 0;
417} 422}
@@ -419,16 +424,16 @@ static int ila_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info)
419static int ila_fill_info(struct ila_map *ila, struct sk_buff *msg) 424static int ila_fill_info(struct ila_map *ila, struct sk_buff *msg)
420{ 425{
421 if (nla_put_u64_64bit(msg, ILA_ATTR_IDENTIFIER, 426 if (nla_put_u64_64bit(msg, ILA_ATTR_IDENTIFIER,
422 (__force u64)ila->p.identifier, 427 (__force u64)ila->xp.identifier.v64,
423 ILA_ATTR_PAD) || 428 ILA_ATTR_PAD) ||
424 nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR, 429 nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR,
425 (__force u64)ila->p.ip.locator, 430 (__force u64)ila->xp.ip.locator.v64,
426 ILA_ATTR_PAD) || 431 ILA_ATTR_PAD) ||
427 nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR_MATCH, 432 nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR_MATCH,
428 (__force u64)ila->p.ip.locator_match, 433 (__force u64)ila->xp.ip.locator_match.v64,
429 ILA_ATTR_PAD) || 434 ILA_ATTR_PAD) ||
430 nla_put_s32(msg, ILA_ATTR_IFINDEX, ila->p.ifindex) || 435 nla_put_s32(msg, ILA_ATTR_IFINDEX, ila->xp.ifindex) ||
431 nla_put_u32(msg, ILA_ATTR_DIR, ila->p.dir)) 436 nla_put_u32(msg, ILA_ATTR_DIR, ila->xp.dir))
432 return -1; 437 return -1;
433 438
434 return 0; 439 return 0;
@@ -460,11 +465,11 @@ static int ila_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info)
460 struct net *net = genl_info_net(info); 465 struct net *net = genl_info_net(info);
461 struct ila_net *ilan = net_generic(net, ila_net_id); 466 struct ila_net *ilan = net_generic(net, ila_net_id);
462 struct sk_buff *msg; 467 struct sk_buff *msg;
463 struct ila_xlat_params p; 468 struct ila_xlat_params xp;
464 struct ila_map *ila; 469 struct ila_map *ila;
465 int ret; 470 int ret;
466 471
467 ret = parse_nl_config(info, &p); 472 ret = parse_nl_config(info, &xp);
468 if (ret) 473 if (ret)
469 return ret; 474 return ret;
470 475
@@ -474,7 +479,7 @@ static int ila_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info)
474 479
475 rcu_read_lock(); 480 rcu_read_lock();
476 481
477 ila = ila_lookup_by_params(&p, ilan); 482 ila = ila_lookup_by_params(&xp, ilan);
478 if (ila) { 483 if (ila) {
479 ret = ila_dump_info(ila, 484 ret = ila_dump_info(ila,
480 info->snd_portid, 485 info->snd_portid,
@@ -623,21 +628,18 @@ static int ila_xlat_addr(struct sk_buff *skb, int dir)
623 struct ipv6hdr *ip6h = ipv6_hdr(skb); 628 struct ipv6hdr *ip6h = ipv6_hdr(skb);
624 struct net *net = dev_net(skb->dev); 629 struct net *net = dev_net(skb->dev);
625 struct ila_net *ilan = net_generic(net, ila_net_id); 630 struct ila_net *ilan = net_generic(net, ila_net_id);
626 __be64 identifier, locator_match; 631 struct ila_addr *iaddr = ila_a2i(&ip6h->daddr);
627 size_t nhoff; 632 size_t nhoff;
628 633
629 /* Assumes skb contains a valid IPv6 header that is pulled */ 634 /* Assumes skb contains a valid IPv6 header that is pulled */
630 635
631 identifier = *(__be64 *)&ip6h->daddr.in6_u.u6_addr8[8];
632 locator_match = *(__be64 *)&ip6h->daddr.in6_u.u6_addr8[0];
633 nhoff = sizeof(struct ipv6hdr); 636 nhoff = sizeof(struct ipv6hdr);
634 637
635 rcu_read_lock(); 638 rcu_read_lock();
636 639
637 ila = ila_lookup_wildcards(identifier, locator_match, 640 ila = ila_lookup_wildcards(iaddr, skb->dev->ifindex, dir, ilan);
638 skb->dev->ifindex, dir, ilan);
639 if (ila) 641 if (ila)
640 update_ipv6_locator(skb, &ila->p.ip); 642 ila_update_ipv6_locator(skb, &ila->xp.ip);
641 643
642 rcu_read_unlock(); 644 rcu_read_unlock();
643 645