1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/jhash.h>
3 #include <linux/netfilter.h>
4 #include <linux/rcupdate.h>
5 #include <linux/rhashtable.h>
6 #include <linux/vmalloc.h>
7 #include <net/genetlink.h>
9 #include <net/netns/generic.h>
10 #include <uapi/linux/genetlink.h>
13 struct ila_xlat_params
{
19 struct ila_xlat_params xp
;
20 struct rhash_head node
;
21 struct ila_map __rcu
*next
;
25 #define MAX_LOCKS 1024
26 #define LOCKS_PER_CPU 10
28 static int alloc_ila_locks(struct ila_net
*ilan
)
30 return alloc_bucket_spinlocks(&ilan
->xlat
.locks
, &ilan
->xlat
.locks_mask
,
31 MAX_LOCKS
, LOCKS_PER_CPU
,
35 static u32 hashrnd __read_mostly
;
36 static __always_inline
void __ila_hash_secret_init(void)
38 net_get_random_once(&hashrnd
, sizeof(hashrnd
));
41 static inline u32
ila_locator_hash(struct ila_locator loc
)
43 u32
*v
= (u32
*)loc
.v32
;
45 __ila_hash_secret_init();
46 return jhash_2words(v
[0], v
[1], hashrnd
);
49 static inline spinlock_t
*ila_get_lock(struct ila_net
*ilan
,
50 struct ila_locator loc
)
52 return &ilan
->xlat
.locks
[ila_locator_hash(loc
) & ilan
->xlat
.locks_mask
];
55 static inline int ila_cmp_wildcards(struct ila_map
*ila
,
56 struct ila_addr
*iaddr
, int ifindex
)
58 return (ila
->xp
.ifindex
&& ila
->xp
.ifindex
!= ifindex
);
61 static inline int ila_cmp_params(struct ila_map
*ila
,
62 struct ila_xlat_params
*xp
)
64 return (ila
->xp
.ifindex
!= xp
->ifindex
);
67 static int ila_cmpfn(struct rhashtable_compare_arg
*arg
,
70 const struct ila_map
*ila
= obj
;
72 return (ila
->xp
.ip
.locator_match
.v64
!= *(__be64
*)arg
->key
);
75 static inline int ila_order(struct ila_map
*ila
)
85 static const struct rhashtable_params rht_params
= {
87 .head_offset
= offsetof(struct ila_map
, node
),
88 .key_offset
= offsetof(struct ila_map
, xp
.ip
.locator_match
),
89 .key_len
= sizeof(u64
), /* identifier */
92 .automatic_shrinking
= true,
93 .obj_cmpfn
= ila_cmpfn
,
96 static int parse_nl_config(struct genl_info
*info
,
97 struct ila_xlat_params
*xp
)
99 memset(xp
, 0, sizeof(*xp
));
101 if (info
->attrs
[ILA_ATTR_LOCATOR
])
102 xp
->ip
.locator
.v64
= (__force __be64
)nla_get_u64(
103 info
->attrs
[ILA_ATTR_LOCATOR
]);
105 if (info
->attrs
[ILA_ATTR_LOCATOR_MATCH
])
106 xp
->ip
.locator_match
.v64
= (__force __be64
)nla_get_u64(
107 info
->attrs
[ILA_ATTR_LOCATOR_MATCH
]);
109 if (info
->attrs
[ILA_ATTR_CSUM_MODE
])
110 xp
->ip
.csum_mode
= nla_get_u8(info
->attrs
[ILA_ATTR_CSUM_MODE
]);
112 xp
->ip
.csum_mode
= ILA_CSUM_NO_ACTION
;
114 if (info
->attrs
[ILA_ATTR_IDENT_TYPE
])
115 xp
->ip
.ident_type
= nla_get_u8(
116 info
->attrs
[ILA_ATTR_IDENT_TYPE
]);
118 xp
->ip
.ident_type
= ILA_ATYPE_USE_FORMAT
;
120 if (info
->attrs
[ILA_ATTR_IFINDEX
])
121 xp
->ifindex
= nla_get_s32(info
->attrs
[ILA_ATTR_IFINDEX
]);
126 /* Must be called with rcu readlock */
127 static inline struct ila_map
*ila_lookup_wildcards(struct ila_addr
*iaddr
,
129 struct ila_net
*ilan
)
133 ila
= rhashtable_lookup_fast(&ilan
->xlat
.rhash_table
, &iaddr
->loc
,
136 if (!ila_cmp_wildcards(ila
, iaddr
, ifindex
))
138 ila
= rcu_access_pointer(ila
->next
);
144 /* Must be called with rcu readlock */
145 static inline struct ila_map
*ila_lookup_by_params(struct ila_xlat_params
*xp
,
146 struct ila_net
*ilan
)
150 ila
= rhashtable_lookup_fast(&ilan
->xlat
.rhash_table
,
151 &xp
->ip
.locator_match
,
154 if (!ila_cmp_params(ila
, xp
))
156 ila
= rcu_access_pointer(ila
->next
);
162 static inline void ila_release(struct ila_map
*ila
)
167 static void ila_free_node(struct ila_map
*ila
)
169 struct ila_map
*next
;
171 /* Assume rcu_readlock held */
173 next
= rcu_access_pointer(ila
->next
);
179 static void ila_free_cb(void *ptr
, void *arg
)
181 ila_free_node((struct ila_map
*)ptr
);
184 static int ila_xlat_addr(struct sk_buff
*skb
, bool sir2ila
);
187 ila_nf_input(void *priv
,
189 const struct nf_hook_state
*state
)
191 ila_xlat_addr(skb
, false);
195 static const struct nf_hook_ops ila_nf_hook_ops
[] = {
197 .hook
= ila_nf_input
,
199 .hooknum
= NF_INET_PRE_ROUTING
,
204 static int ila_add_mapping(struct net
*net
, struct ila_xlat_params
*xp
)
206 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
207 struct ila_map
*ila
, *head
;
208 spinlock_t
*lock
= ila_get_lock(ilan
, xp
->ip
.locator_match
);
211 if (!ilan
->xlat
.hooks_registered
) {
212 /* We defer registering net hooks in the namespace until the
213 * first mapping is added.
215 err
= nf_register_net_hooks(net
, ila_nf_hook_ops
,
216 ARRAY_SIZE(ila_nf_hook_ops
));
220 ilan
->xlat
.hooks_registered
= true;
223 ila
= kzalloc(sizeof(*ila
), GFP_KERNEL
);
227 ila_init_saved_csum(&xp
->ip
);
231 order
= ila_order(ila
);
235 head
= rhashtable_lookup_fast(&ilan
->xlat
.rhash_table
,
236 &xp
->ip
.locator_match
,
239 /* New entry for the rhash_table */
240 err
= rhashtable_lookup_insert_fast(&ilan
->xlat
.rhash_table
,
241 &ila
->node
, rht_params
);
243 struct ila_map
*tila
= head
, *prev
= NULL
;
246 if (!ila_cmp_params(tila
, xp
)) {
251 if (order
> ila_order(tila
))
255 tila
= rcu_dereference_protected(tila
->next
,
256 lockdep_is_held(lock
));
260 /* Insert in sub list of head */
261 RCU_INIT_POINTER(ila
->next
, tila
);
262 rcu_assign_pointer(prev
->next
, ila
);
264 /* Make this ila new head */
265 RCU_INIT_POINTER(ila
->next
, head
);
266 err
= rhashtable_replace_fast(&ilan
->xlat
.rhash_table
,
268 &ila
->node
, rht_params
);
283 static int ila_del_mapping(struct net
*net
, struct ila_xlat_params
*xp
)
285 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
286 struct ila_map
*ila
, *head
, *prev
;
287 spinlock_t
*lock
= ila_get_lock(ilan
, xp
->ip
.locator_match
);
292 head
= rhashtable_lookup_fast(&ilan
->xlat
.rhash_table
,
293 &xp
->ip
.locator_match
, rht_params
);
299 if (ila_cmp_params(ila
, xp
)) {
301 ila
= rcu_dereference_protected(ila
->next
,
302 lockdep_is_held(lock
));
309 /* Not head, just delete from list */
310 rcu_assign_pointer(prev
->next
, ila
->next
);
312 /* It is the head. If there is something in the
313 * sublist we need to make a new head.
315 head
= rcu_dereference_protected(ila
->next
,
316 lockdep_is_held(lock
));
318 /* Put first entry in the sublist into the
321 err
= rhashtable_replace_fast(
322 &ilan
->xlat
.rhash_table
, &ila
->node
,
323 &head
->node
, rht_params
);
327 /* Entry no longer used */
328 err
= rhashtable_remove_fast(
329 &ilan
->xlat
.rhash_table
,
330 &ila
->node
, rht_params
);
345 int ila_xlat_nl_cmd_add_mapping(struct sk_buff
*skb
, struct genl_info
*info
)
347 struct net
*net
= genl_info_net(info
);
348 struct ila_xlat_params p
;
351 err
= parse_nl_config(info
, &p
);
355 return ila_add_mapping(net
, &p
);
358 int ila_xlat_nl_cmd_del_mapping(struct sk_buff
*skb
, struct genl_info
*info
)
360 struct net
*net
= genl_info_net(info
);
361 struct ila_xlat_params xp
;
364 err
= parse_nl_config(info
, &xp
);
368 ila_del_mapping(net
, &xp
);
373 static inline spinlock_t
*lock_from_ila_map(struct ila_net
*ilan
,
376 return ila_get_lock(ilan
, ila
->xp
.ip
.locator_match
);
379 int ila_xlat_nl_cmd_flush(struct sk_buff
*skb
, struct genl_info
*info
)
381 struct net
*net
= genl_info_net(info
);
382 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
383 struct rhashtable_iter iter
;
388 rhashtable_walk_enter(&ilan
->xlat
.rhash_table
, &iter
);
389 rhashtable_walk_start(&iter
);
392 ila
= rhashtable_walk_next(&iter
);
395 if (PTR_ERR(ila
) == -EAGAIN
)
403 lock
= lock_from_ila_map(ilan
, ila
);
407 ret
= rhashtable_remove_fast(&ilan
->xlat
.rhash_table
,
408 &ila
->node
, rht_params
);
419 rhashtable_walk_stop(&iter
);
420 rhashtable_walk_exit(&iter
);
424 static int ila_fill_info(struct ila_map
*ila
, struct sk_buff
*msg
)
426 if (nla_put_u64_64bit(msg
, ILA_ATTR_LOCATOR
,
427 (__force u64
)ila
->xp
.ip
.locator
.v64
,
429 nla_put_u64_64bit(msg
, ILA_ATTR_LOCATOR_MATCH
,
430 (__force u64
)ila
->xp
.ip
.locator_match
.v64
,
432 nla_put_s32(msg
, ILA_ATTR_IFINDEX
, ila
->xp
.ifindex
) ||
433 nla_put_u8(msg
, ILA_ATTR_CSUM_MODE
, ila
->xp
.ip
.csum_mode
) ||
434 nla_put_u8(msg
, ILA_ATTR_IDENT_TYPE
, ila
->xp
.ip
.ident_type
))
440 static int ila_dump_info(struct ila_map
*ila
,
441 u32 portid
, u32 seq
, u32 flags
,
442 struct sk_buff
*skb
, u8 cmd
)
446 hdr
= genlmsg_put(skb
, portid
, seq
, &ila_nl_family
, flags
, cmd
);
450 if (ila_fill_info(ila
, skb
) < 0)
451 goto nla_put_failure
;
453 genlmsg_end(skb
, hdr
);
457 genlmsg_cancel(skb
, hdr
);
461 int ila_xlat_nl_cmd_get_mapping(struct sk_buff
*skb
, struct genl_info
*info
)
463 struct net
*net
= genl_info_net(info
);
464 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
466 struct ila_xlat_params xp
;
470 ret
= parse_nl_config(info
, &xp
);
474 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
480 ila
= ila_lookup_by_params(&xp
, ilan
);
482 ret
= ila_dump_info(ila
,
484 info
->snd_seq
, 0, msg
,
493 return genlmsg_reply(msg
, info
);
500 struct ila_dump_iter
{
501 struct rhashtable_iter rhiter
;
505 int ila_xlat_nl_dump_start(struct netlink_callback
*cb
)
507 struct net
*net
= sock_net(cb
->skb
->sk
);
508 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
509 struct ila_dump_iter
*iter
;
511 iter
= kmalloc(sizeof(*iter
), GFP_KERNEL
);
515 rhashtable_walk_enter(&ilan
->xlat
.rhash_table
, &iter
->rhiter
);
518 cb
->args
[0] = (long)iter
;
523 int ila_xlat_nl_dump_done(struct netlink_callback
*cb
)
525 struct ila_dump_iter
*iter
= (struct ila_dump_iter
*)cb
->args
[0];
527 rhashtable_walk_exit(&iter
->rhiter
);
534 int ila_xlat_nl_dump(struct sk_buff
*skb
, struct netlink_callback
*cb
)
536 struct ila_dump_iter
*iter
= (struct ila_dump_iter
*)cb
->args
[0];
537 struct rhashtable_iter
*rhiter
= &iter
->rhiter
;
538 int skip
= iter
->skip
;
542 rhashtable_walk_start(rhiter
);
544 /* Get first entry */
545 ila
= rhashtable_walk_peek(rhiter
);
547 if (ila
&& !IS_ERR(ila
) && skip
) {
548 /* Skip over visited entries */
550 while (ila
&& skip
) {
551 /* Skip over any ila entries in this list that we
552 * have already dumped.
554 ila
= rcu_access_pointer(ila
->next
);
564 if (ret
== -EAGAIN
) {
565 /* Table has changed and iter has reset. Return
566 * -EAGAIN to the application even if we have
567 * written data to the skb. The application
568 * needs to deal with this.
581 ret
= ila_dump_info(ila
, NETLINK_CB(cb
->skb
).portid
,
582 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
588 ila
= rcu_access_pointer(ila
->next
);
592 ila
= rhashtable_walk_next(rhiter
);
597 ret
= (skb
->len
? : ret
);
600 rhashtable_walk_stop(rhiter
);
604 #define ILA_HASH_TABLE_SIZE 1024
606 int ila_xlat_init_net(struct net
*net
)
608 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
611 err
= alloc_ila_locks(ilan
);
615 rhashtable_init(&ilan
->xlat
.rhash_table
, &rht_params
);
620 void ila_xlat_exit_net(struct net
*net
)
622 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
624 rhashtable_free_and_destroy(&ilan
->xlat
.rhash_table
, ila_free_cb
, NULL
);
626 free_bucket_spinlocks(ilan
->xlat
.locks
);
628 if (ilan
->xlat
.hooks_registered
)
629 nf_unregister_net_hooks(net
, ila_nf_hook_ops
,
630 ARRAY_SIZE(ila_nf_hook_ops
));
633 static int ila_xlat_addr(struct sk_buff
*skb
, bool sir2ila
)
636 struct ipv6hdr
*ip6h
= ipv6_hdr(skb
);
637 struct net
*net
= dev_net(skb
->dev
);
638 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
639 struct ila_addr
*iaddr
= ila_a2i(&ip6h
->daddr
);
641 /* Assumes skb contains a valid IPv6 header that is pulled */
643 /* No check here that ILA type in the mapping matches what is in the
644 * address. We assume that whatever sender gaves us can be translated.
645 * The checksum mode however is relevant.
650 ila
= ila_lookup_wildcards(iaddr
, skb
->dev
->ifindex
, ilan
);
652 ila_update_ipv6_locator(skb
, &ila
->xp
.ip
, sir2ila
);