sock: make cookie generation global instead of per netns
authorDaniel Borkmann <daniel@iogearbox.net>
Thu, 8 Aug 2019 11:57:25 +0000 (13:57 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 9 Aug 2019 20:14:46 +0000 (13:14 -0700)
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>
include/net/net_namespace.h
include/uapi/linux/bpf.h
net/core/sock_diag.c

index 4a9da951a794efbf9183c0a2e3d3ca94ec88f9d5..cb668bc2692db22e4639fcd3e95b21ed55f00410 100644 (file)
@@ -61,7 +61,6 @@ struct net {
        spinlock_t              rules_mod_lock;
 
        u32                     hash_mix;
-       atomic64_t              cookie_gen;
 
        struct list_head        list;           /* list of network namespaces */
        struct list_head        exit_list;      /* To linked to call pernet exit
index fa1c753dcdbc7f170a65dbaa8b01683de5e6e942..a5aa7d3ac6a116a7a8d3c08d840c37a70e42e7a4 100644 (file)
@@ -1466,8 +1466,8 @@ union bpf_attr {
  *             If no cookie has been set yet, generate a new cookie. Once
  *             generated, the socket cookie remains stable for the life of the
  *             socket. This helper can be useful for monitoring per socket
- *             networking traffic statistics as it provides a unique socket
- *             identifier per namespace.
+ *             networking traffic statistics as it provides a global socket
+ *             identifier that can be assumed unique.
  *     Return
  *             A 8-byte long non-decreasing number on success, or 0 if the
  *             socket field is missing inside *skb*.
index 3312a5849a974e372a49164abca8f7067a2ed7e7..c13ffbd33d8d6ad4f591571325aaee321df5b242 100644 (file)
@@ -19,6 +19,7 @@ static const struct sock_diag_handler *sock_diag_handlers[AF_MAX];
 static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh);
 static DEFINE_MUTEX(sock_diag_table_mutex);
 static struct workqueue_struct *broadcast_wq;
+static atomic64_t cookie_gen;
 
 u64 sock_gen_cookie(struct sock *sk)
 {
@@ -27,7 +28,7 @@ u64 sock_gen_cookie(struct sock *sk)
 
                if (res)
                        return res;
-               res = atomic64_inc_return(&sock_net(sk)->cookie_gen);
+               res = atomic64_inc_return(&cookie_gen);
                atomic64_cmpxchg(&sk->sk_cookie, 0, res);
        }
 }