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

sock: make cookie generation global instead of per netns

Generating and retrieving socket cookies are a useful feature that is
exposed to BPF for various program types through bpf_get_socket_cookie()
helper.

The fact that the cookie counter is per netns is quite a limitation
for BPF in practice in particular for programs in host namespace that
use socket cookies as part of a map lookup key since they will be
causing socket cookie collisions e.g. when attached to BPF cgroup hooks
or cls_bpf on tc egress in host namespace handling container traffic
from veth or ipvlan devices with peer in different netns. Change the
counter to be global instead.

Socket cookie consumers must assume the value as opqaue in any case.
Not every socket must have a cookie generated and knowledge of the
counter value itself does not provide much value either way hence
conversion to global is fine.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Martynas Pumputis <m@lambda.lt>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Daniel Borkmann and committed by
David S. Miller
cd48bdda 7bac762d

+4 -4
-1
include/net/net_namespace.h
··· 61 61 spinlock_t rules_mod_lock; 62 62 63 63 u32 hash_mix; 64 - atomic64_t cookie_gen; 65 64 66 65 struct list_head list; /* list of network namespaces */ 67 66 struct list_head exit_list; /* To linked to call pernet exit
+2 -2
include/uapi/linux/bpf.h
··· 1466 1466 * If no cookie has been set yet, generate a new cookie. Once 1467 1467 * generated, the socket cookie remains stable for the life of the 1468 1468 * socket. This helper can be useful for monitoring per socket 1469 - * networking traffic statistics as it provides a unique socket 1470 - * identifier per namespace. 1469 + * networking traffic statistics as it provides a global socket 1470 + * identifier that can be assumed unique. 1471 1471 * Return 1472 1472 * A 8-byte long non-decreasing number on success, or 0 if the 1473 1473 * socket field is missing inside *skb*.
+2 -1
net/core/sock_diag.c
··· 19 19 static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh); 20 20 static DEFINE_MUTEX(sock_diag_table_mutex); 21 21 static struct workqueue_struct *broadcast_wq; 22 + static atomic64_t cookie_gen; 22 23 23 24 u64 sock_gen_cookie(struct sock *sk) 24 25 { ··· 28 27 29 28 if (res) 30 29 return res; 31 - res = atomic64_inc_return(&sock_net(sk)->cookie_gen); 30 + res = atomic64_inc_return(&cookie_gen); 32 31 atomic64_cmpxchg(&sk->sk_cookie, 0, res); 33 32 } 34 33 }