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 static unsigned int ila_net_id
;
28 struct rhashtable rhash_table
;
29 spinlock_t
*locks
; /* Bucket locks for entry manipulation */
30 unsigned int locks_mask
;
31 bool hooks_registered
;
34 #define LOCKS_PER_CPU 10
36 static int alloc_ila_locks(struct ila_net
*ilan
)
39 unsigned int nr_pcpus
= num_possible_cpus();
41 nr_pcpus
= min_t(unsigned int, nr_pcpus
, 32UL);
42 size
= roundup_pow_of_two(nr_pcpus
* LOCKS_PER_CPU
);
44 if (sizeof(spinlock_t
) != 0) {
45 ilan
->locks
= kvmalloc(size
* sizeof(spinlock_t
), GFP_KERNEL
);
48 for (i
= 0; i
< size
; i
++)
49 spin_lock_init(&ilan
->locks
[i
]);
51 ilan
->locks_mask
= size
- 1;
56 static u32 hashrnd __read_mostly
;
57 static __always_inline
void __ila_hash_secret_init(void)
59 net_get_random_once(&hashrnd
, sizeof(hashrnd
));
62 static inline u32
ila_locator_hash(struct ila_locator loc
)
64 u32
*v
= (u32
*)loc
.v32
;
66 __ila_hash_secret_init();
67 return jhash_2words(v
[0], v
[1], hashrnd
);
70 static inline spinlock_t
*ila_get_lock(struct ila_net
*ilan
,
71 struct ila_locator loc
)
73 return &ilan
->locks
[ila_locator_hash(loc
) & ilan
->locks_mask
];
76 static inline int ila_cmp_wildcards(struct ila_map
*ila
,
77 struct ila_addr
*iaddr
, int ifindex
)
79 return (ila
->xp
.ifindex
&& ila
->xp
.ifindex
!= ifindex
);
82 static inline int ila_cmp_params(struct ila_map
*ila
,
83 struct ila_xlat_params
*xp
)
85 return (ila
->xp
.ifindex
!= xp
->ifindex
);
88 static int ila_cmpfn(struct rhashtable_compare_arg
*arg
,
91 const struct ila_map
*ila
= obj
;
93 return (ila
->xp
.ip
.locator_match
.v64
!= *(__be64
*)arg
->key
);
96 static inline int ila_order(struct ila_map
*ila
)
106 static const struct rhashtable_params rht_params
= {
108 .head_offset
= offsetof(struct ila_map
, node
),
109 .key_offset
= offsetof(struct ila_map
, xp
.ip
.locator_match
),
110 .key_len
= sizeof(u64
), /* identifier */
113 .automatic_shrinking
= true,
114 .obj_cmpfn
= ila_cmpfn
,
117 static struct genl_family ila_nl_family
;
119 static const struct nla_policy ila_nl_policy
[ILA_ATTR_MAX
+ 1] = {
120 [ILA_ATTR_LOCATOR
] = { .type
= NLA_U64
, },
121 [ILA_ATTR_LOCATOR_MATCH
] = { .type
= NLA_U64
, },
122 [ILA_ATTR_IFINDEX
] = { .type
= NLA_U32
, },
123 [ILA_ATTR_CSUM_MODE
] = { .type
= NLA_U8
, },
124 [ILA_ATTR_IDENT_TYPE
] = { .type
= NLA_U8
, },
127 static int parse_nl_config(struct genl_info
*info
,
128 struct ila_xlat_params
*xp
)
130 memset(xp
, 0, sizeof(*xp
));
132 if (info
->attrs
[ILA_ATTR_LOCATOR
])
133 xp
->ip
.locator
.v64
= (__force __be64
)nla_get_u64(
134 info
->attrs
[ILA_ATTR_LOCATOR
]);
136 if (info
->attrs
[ILA_ATTR_LOCATOR_MATCH
])
137 xp
->ip
.locator_match
.v64
= (__force __be64
)nla_get_u64(
138 info
->attrs
[ILA_ATTR_LOCATOR_MATCH
]);
140 if (info
->attrs
[ILA_ATTR_CSUM_MODE
])
141 xp
->ip
.csum_mode
= nla_get_u8(info
->attrs
[ILA_ATTR_CSUM_MODE
]);
143 xp
->ip
.csum_mode
= ILA_CSUM_NO_ACTION
;
145 if (info
->attrs
[ILA_ATTR_IDENT_TYPE
])
146 xp
->ip
.ident_type
= nla_get_u8(
147 info
->attrs
[ILA_ATTR_IDENT_TYPE
]);
149 xp
->ip
.ident_type
= ILA_ATYPE_USE_FORMAT
;
151 if (info
->attrs
[ILA_ATTR_IFINDEX
])
152 xp
->ifindex
= nla_get_s32(info
->attrs
[ILA_ATTR_IFINDEX
]);
157 /* Must be called with rcu readlock */
158 static inline struct ila_map
*ila_lookup_wildcards(struct ila_addr
*iaddr
,
160 struct ila_net
*ilan
)
164 ila
= rhashtable_lookup_fast(&ilan
->rhash_table
, &iaddr
->loc
,
167 if (!ila_cmp_wildcards(ila
, iaddr
, ifindex
))
169 ila
= rcu_access_pointer(ila
->next
);
175 /* Must be called with rcu readlock */
176 static inline struct ila_map
*ila_lookup_by_params(struct ila_xlat_params
*xp
,
177 struct ila_net
*ilan
)
181 ila
= rhashtable_lookup_fast(&ilan
->rhash_table
,
182 &xp
->ip
.locator_match
,
185 if (!ila_cmp_params(ila
, xp
))
187 ila
= rcu_access_pointer(ila
->next
);
193 static inline void ila_release(struct ila_map
*ila
)
198 static void ila_free_cb(void *ptr
, void *arg
)
200 struct ila_map
*ila
= (struct ila_map
*)ptr
, *next
;
202 /* Assume rcu_readlock held */
204 next
= rcu_access_pointer(ila
->next
);
210 static int ila_xlat_addr(struct sk_buff
*skb
, bool sir2ila
);
213 ila_nf_input(void *priv
,
215 const struct nf_hook_state
*state
)
217 ila_xlat_addr(skb
, false);
221 static const struct nf_hook_ops ila_nf_hook_ops
[] = {
223 .hook
= ila_nf_input
,
225 .hooknum
= NF_INET_PRE_ROUTING
,
230 static int ila_add_mapping(struct net
*net
, struct ila_xlat_params
*xp
)
232 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
233 struct ila_map
*ila
, *head
;
234 spinlock_t
*lock
= ila_get_lock(ilan
, xp
->ip
.locator_match
);
237 if (!ilan
->hooks_registered
) {
238 /* We defer registering net hooks in the namespace until the
239 * first mapping is added.
241 err
= nf_register_net_hooks(net
, ila_nf_hook_ops
,
242 ARRAY_SIZE(ila_nf_hook_ops
));
246 ilan
->hooks_registered
= true;
249 ila
= kzalloc(sizeof(*ila
), GFP_KERNEL
);
253 ila_init_saved_csum(&xp
->ip
);
257 order
= ila_order(ila
);
261 head
= rhashtable_lookup_fast(&ilan
->rhash_table
,
262 &xp
->ip
.locator_match
,
265 /* New entry for the rhash_table */
266 err
= rhashtable_lookup_insert_fast(&ilan
->rhash_table
,
267 &ila
->node
, rht_params
);
269 struct ila_map
*tila
= head
, *prev
= NULL
;
272 if (!ila_cmp_params(tila
, xp
)) {
277 if (order
> ila_order(tila
))
281 tila
= rcu_dereference_protected(tila
->next
,
282 lockdep_is_held(lock
));
286 /* Insert in sub list of head */
287 RCU_INIT_POINTER(ila
->next
, tila
);
288 rcu_assign_pointer(prev
->next
, ila
);
290 /* Make this ila new head */
291 RCU_INIT_POINTER(ila
->next
, head
);
292 err
= rhashtable_replace_fast(&ilan
->rhash_table
,
294 &ila
->node
, rht_params
);
309 static int ila_del_mapping(struct net
*net
, struct ila_xlat_params
*xp
)
311 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
312 struct ila_map
*ila
, *head
, *prev
;
313 spinlock_t
*lock
= ila_get_lock(ilan
, xp
->ip
.locator_match
);
318 head
= rhashtable_lookup_fast(&ilan
->rhash_table
,
319 &xp
->ip
.locator_match
, rht_params
);
325 if (ila_cmp_params(ila
, xp
)) {
327 ila
= rcu_dereference_protected(ila
->next
,
328 lockdep_is_held(lock
));
335 /* Not head, just delete from list */
336 rcu_assign_pointer(prev
->next
, ila
->next
);
338 /* It is the head. If there is something in the
339 * sublist we need to make a new head.
341 head
= rcu_dereference_protected(ila
->next
,
342 lockdep_is_held(lock
));
344 /* Put first entry in the sublist into the
347 err
= rhashtable_replace_fast(
348 &ilan
->rhash_table
, &ila
->node
,
349 &head
->node
, rht_params
);
353 /* Entry no longer used */
354 err
= rhashtable_remove_fast(&ilan
->rhash_table
,
371 static int ila_nl_cmd_add_mapping(struct sk_buff
*skb
, struct genl_info
*info
)
373 struct net
*net
= genl_info_net(info
);
374 struct ila_xlat_params p
;
377 err
= parse_nl_config(info
, &p
);
381 return ila_add_mapping(net
, &p
);
384 static int ila_nl_cmd_del_mapping(struct sk_buff
*skb
, struct genl_info
*info
)
386 struct net
*net
= genl_info_net(info
);
387 struct ila_xlat_params xp
;
390 err
= parse_nl_config(info
, &xp
);
394 ila_del_mapping(net
, &xp
);
399 static int ila_fill_info(struct ila_map
*ila
, struct sk_buff
*msg
)
401 if (nla_put_u64_64bit(msg
, ILA_ATTR_LOCATOR
,
402 (__force u64
)ila
->xp
.ip
.locator
.v64
,
404 nla_put_u64_64bit(msg
, ILA_ATTR_LOCATOR_MATCH
,
405 (__force u64
)ila
->xp
.ip
.locator_match
.v64
,
407 nla_put_s32(msg
, ILA_ATTR_IFINDEX
, ila
->xp
.ifindex
) ||
408 nla_put_u8(msg
, ILA_ATTR_CSUM_MODE
, ila
->xp
.ip
.csum_mode
) ||
409 nla_put_u8(msg
, ILA_ATTR_IDENT_TYPE
, ila
->xp
.ip
.ident_type
))
415 static int ila_dump_info(struct ila_map
*ila
,
416 u32 portid
, u32 seq
, u32 flags
,
417 struct sk_buff
*skb
, u8 cmd
)
421 hdr
= genlmsg_put(skb
, portid
, seq
, &ila_nl_family
, flags
, cmd
);
425 if (ila_fill_info(ila
, skb
) < 0)
426 goto nla_put_failure
;
428 genlmsg_end(skb
, hdr
);
432 genlmsg_cancel(skb
, hdr
);
436 static int ila_nl_cmd_get_mapping(struct sk_buff
*skb
, struct genl_info
*info
)
438 struct net
*net
= genl_info_net(info
);
439 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
441 struct ila_xlat_params xp
;
445 ret
= parse_nl_config(info
, &xp
);
449 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
455 ila
= ila_lookup_by_params(&xp
, ilan
);
457 ret
= ila_dump_info(ila
,
459 info
->snd_seq
, 0, msg
,
468 return genlmsg_reply(msg
, info
);
475 struct ila_dump_iter
{
476 struct rhashtable_iter rhiter
;
479 static int ila_nl_dump_start(struct netlink_callback
*cb
)
481 struct net
*net
= sock_net(cb
->skb
->sk
);
482 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
483 struct ila_dump_iter
*iter
= (struct ila_dump_iter
*)cb
->args
[0];
486 iter
= kmalloc(sizeof(*iter
), GFP_KERNEL
);
490 cb
->args
[0] = (long)iter
;
493 return rhashtable_walk_init(&ilan
->rhash_table
, &iter
->rhiter
,
497 static int ila_nl_dump_done(struct netlink_callback
*cb
)
499 struct ila_dump_iter
*iter
= (struct ila_dump_iter
*)cb
->args
[0];
501 rhashtable_walk_exit(&iter
->rhiter
);
508 static int ila_nl_dump(struct sk_buff
*skb
, struct netlink_callback
*cb
)
510 struct ila_dump_iter
*iter
= (struct ila_dump_iter
*)cb
->args
[0];
511 struct rhashtable_iter
*rhiter
= &iter
->rhiter
;
515 rhashtable_walk_start(rhiter
);
518 ila
= rhashtable_walk_next(rhiter
);
521 if (PTR_ERR(ila
) == -EAGAIN
)
530 ret
= ila_dump_info(ila
, NETLINK_CB(cb
->skb
).portid
,
531 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
536 ila
= rcu_access_pointer(ila
->next
);
543 rhashtable_walk_stop(rhiter
);
547 static const struct genl_ops ila_nl_ops
[] = {
550 .doit
= ila_nl_cmd_add_mapping
,
551 .policy
= ila_nl_policy
,
552 .flags
= GENL_ADMIN_PERM
,
556 .doit
= ila_nl_cmd_del_mapping
,
557 .policy
= ila_nl_policy
,
558 .flags
= GENL_ADMIN_PERM
,
562 .doit
= ila_nl_cmd_get_mapping
,
563 .start
= ila_nl_dump_start
,
564 .dumpit
= ila_nl_dump
,
565 .done
= ila_nl_dump_done
,
566 .policy
= ila_nl_policy
,
570 static struct genl_family ila_nl_family __ro_after_init
= {
572 .name
= ILA_GENL_NAME
,
573 .version
= ILA_GENL_VERSION
,
574 .maxattr
= ILA_ATTR_MAX
,
576 .parallel_ops
= true,
577 .module
= THIS_MODULE
,
579 .n_ops
= ARRAY_SIZE(ila_nl_ops
),
582 #define ILA_HASH_TABLE_SIZE 1024
584 static __net_init
int ila_init_net(struct net
*net
)
587 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
589 err
= alloc_ila_locks(ilan
);
593 rhashtable_init(&ilan
->rhash_table
, &rht_params
);
598 static __net_exit
void ila_exit_net(struct net
*net
)
600 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
602 rhashtable_free_and_destroy(&ilan
->rhash_table
, ila_free_cb
, NULL
);
606 if (ilan
->hooks_registered
)
607 nf_unregister_net_hooks(net
, ila_nf_hook_ops
,
608 ARRAY_SIZE(ila_nf_hook_ops
));
611 static struct pernet_operations ila_net_ops
= {
612 .init
= ila_init_net
,
613 .exit
= ila_exit_net
,
615 .size
= sizeof(struct ila_net
),
618 static int ila_xlat_addr(struct sk_buff
*skb
, bool sir2ila
)
621 struct ipv6hdr
*ip6h
= ipv6_hdr(skb
);
622 struct net
*net
= dev_net(skb
->dev
);
623 struct ila_net
*ilan
= net_generic(net
, ila_net_id
);
624 struct ila_addr
*iaddr
= ila_a2i(&ip6h
->daddr
);
626 /* Assumes skb contains a valid IPv6 header that is pulled */
628 /* No check here that ILA type in the mapping matches what is in the
629 * address. We assume that whatever sender gaves us can be translated.
630 * The checksum mode however is relevant.
635 ila
= ila_lookup_wildcards(iaddr
, skb
->dev
->ifindex
, ilan
);
637 ila_update_ipv6_locator(skb
, &ila
->xp
.ip
, sir2ila
);
644 int __init
ila_xlat_init(void)
648 ret
= register_pernet_device(&ila_net_ops
);
652 ret
= genl_register_family(&ila_nl_family
);
659 unregister_pernet_device(&ila_net_ops
);
664 void ila_xlat_fini(void)
666 genl_unregister_family(&ila_nl_family
);
667 unregister_pernet_device(&ila_net_ops
);