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

Add a helper function to get socket cookie in eBPF

Retrieve the socket cookie generated by sock_gen_cookie() from a sk_buff
with a known socket. Generates a new cookie if one was not yet set.If
the socket pointer inside sk_buff is NULL, 0 is returned. The helper
function coud be useful in monitoring per socket networking traffic
statistics and provide a unique socket identifier per namespace.

Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Chenbo Feng <fengc@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Chenbo Feng and committed by
David S. Miller
91b8270f 16ae1f22

+29 -3
+1
include/linux/sock_diag.h
··· 24 24 void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)); 25 25 void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)); 26 26 27 + u64 sock_gen_cookie(struct sock *sk); 27 28 int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie); 28 29 void sock_diag_save_cookie(struct sock *sk, __u32 *cookie); 29 30
+8 -1
include/uapi/linux/bpf.h
··· 459 459 * Return: 460 460 * > 0 length of the string including the trailing NUL on success 461 461 * < 0 error 462 + * 463 + * u64 bpf_bpf_get_socket_cookie(skb) 464 + * Get the cookie for the socket stored inside sk_buff. 465 + * @skb: pointer to skb 466 + * Return: 8 Bytes non-decreasing number on success or 0 if the socket 467 + * field is missing inside sk_buff 462 468 */ 463 469 #define __BPF_FUNC_MAPPER(FN) \ 464 470 FN(unspec), \ ··· 512 506 FN(get_numa_node_id), \ 513 507 FN(skb_change_head), \ 514 508 FN(xdp_adjust_head), \ 515 - FN(probe_read_str), 509 + FN(probe_read_str), \ 510 + FN(get_socket_cookie), 516 511 517 512 /* integer value in 'imm' field of BPF_CALL instruction selects which helper 518 513 * function eBPF program intends to call
+17
net/core/filter.c
··· 26 26 #include <linux/mm.h> 27 27 #include <linux/fcntl.h> 28 28 #include <linux/socket.h> 29 + #include <linux/sock_diag.h> 29 30 #include <linux/in.h> 30 31 #include <linux/inet.h> 31 32 #include <linux/netdevice.h> ··· 2607 2606 .arg5_type = ARG_CONST_SIZE, 2608 2607 }; 2609 2608 2609 + BPF_CALL_1(bpf_get_socket_cookie, struct sk_buff *, skb) 2610 + { 2611 + return skb->sk ? sock_gen_cookie(skb->sk) : 0; 2612 + } 2613 + 2614 + static const struct bpf_func_proto bpf_get_socket_cookie_proto = { 2615 + .func = bpf_get_socket_cookie, 2616 + .gpl_only = false, 2617 + .ret_type = RET_INTEGER, 2618 + .arg1_type = ARG_PTR_TO_CTX, 2619 + }; 2620 + 2610 2621 static const struct bpf_func_proto * 2611 2622 bpf_base_func_proto(enum bpf_func_id func_id) 2612 2623 { ··· 2653 2640 switch (func_id) { 2654 2641 case BPF_FUNC_skb_load_bytes: 2655 2642 return &bpf_skb_load_bytes_proto; 2643 + case BPF_FUNC_get_socket_cookie: 2644 + return &bpf_get_socket_cookie_proto; 2656 2645 default: 2657 2646 return bpf_base_func_proto(func_id); 2658 2647 } ··· 2714 2699 return &bpf_get_smp_processor_id_proto; 2715 2700 case BPF_FUNC_skb_under_cgroup: 2716 2701 return &bpf_skb_under_cgroup_proto; 2702 + case BPF_FUNC_get_socket_cookie: 2703 + return &bpf_get_socket_cookie_proto; 2717 2704 default: 2718 2705 return bpf_base_func_proto(func_id); 2719 2706 }
+1 -1
net/core/sock_diag.c
··· 19 19 static DEFINE_MUTEX(sock_diag_table_mutex); 20 20 static struct workqueue_struct *broadcast_wq; 21 21 22 - static u64 sock_gen_cookie(struct sock *sk) 22 + u64 sock_gen_cookie(struct sock *sk) 23 23 { 24 24 while (1) { 25 25 u64 res = atomic64_read(&sk->sk_cookie);
+2 -1
tools/include/uapi/linux/bpf.h
··· 506 506 FN(get_numa_node_id), \ 507 507 FN(skb_change_head), \ 508 508 FN(xdp_adjust_head), \ 509 - FN(probe_read_str), 509 + FN(probe_read_str), \ 510 + FN(get_socket_cookie), 510 511 511 512 /* integer value in 'imm' field of BPF_CALL instruction selects which helper 512 513 * function eBPF program intends to call