On Sat, Jun 20, 2020 at 10:55:10PM -0700, Yonghong Song wrote: > The helper is used in tracing programs to cast a socket > pointer to a udp6_sock pointer. > The return value could be NULL if the casting is illegal. > > Signed-off-by: Yonghong Song <yhs@xxxxxx> > --- > include/linux/bpf.h | 1 + > include/uapi/linux/bpf.h | 9 ++++++++- > kernel/trace/bpf_trace.c | 2 ++ > net/core/filter.c | 22 ++++++++++++++++++++++ > scripts/bpf_helpers_doc.py | 2 ++ > tools/include/uapi/linux/bpf.h | 9 ++++++++- > 6 files changed, 43 insertions(+), 2 deletions(-) > > diff --git a/include/linux/bpf.h b/include/linux/bpf.h > index b17e682454e5..378b6748a8ec 100644 > --- a/include/linux/bpf.h > +++ b/include/linux/bpf.h > @@ -1640,6 +1640,7 @@ extern const struct bpf_func_proto bpf_skc_to_tcp6_sock_proto; > extern const struct bpf_func_proto bpf_skc_to_tcp_sock_proto; > extern const struct bpf_func_proto bpf_skc_to_tcp_timewait_sock_proto; > extern const struct bpf_func_proto bpf_skc_to_tcp_request_sock_proto; > +extern const struct bpf_func_proto bpf_skc_to_udp6_sock_proto; > > const struct bpf_func_proto *bpf_tracing_func_proto( > enum bpf_func_id func_id, const struct bpf_prog *prog); > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index e256417d94c2..3f4b12c5c563 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -3276,6 +3276,12 @@ union bpf_attr { > * Dynamically cast a *sk* pointer to a *tcp_request_sock* pointer. > * Return > * *sk* if casting is valid, or NULL otherwise. > + * > + * struct udp6_sock *bpf_skc_to_udp6_sock(void *sk) > + * Description > + * Dynamically cast a *sk* pointer to a *udp6_sock* pointer. > + * Return > + * *sk* if casting is valid, or NULL otherwise. > */ > #define __BPF_FUNC_MAPPER(FN) \ > FN(unspec), \ > @@ -3417,7 +3423,8 @@ union bpf_attr { > FN(skc_to_tcp6_sock), \ > FN(skc_to_tcp_sock), \ > FN(skc_to_tcp_timewait_sock), \ > - FN(skc_to_tcp_request_sock), > + FN(skc_to_tcp_request_sock), \ > + FN(skc_to_udp6_sock), > > /* integer value in 'imm' field of BPF_CALL instruction selects which helper > * function eBPF program intends to call > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c > index de5fbe66e1ca..d10ab16c4a2f 100644 > --- a/kernel/trace/bpf_trace.c > +++ b/kernel/trace/bpf_trace.c > @@ -1523,6 +1523,8 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) > return &bpf_skc_to_tcp_timewait_sock_proto; > case BPF_FUNC_skc_to_tcp_request_sock: > return &bpf_skc_to_tcp_request_sock_proto; > + case BPF_FUNC_skc_to_udp6_sock: > + return &bpf_skc_to_udp6_sock_proto; > #endif > case BPF_FUNC_seq_printf: > return prog->expected_attach_type == BPF_TRACE_ITER ? > diff --git a/net/core/filter.c b/net/core/filter.c > index d26ce3b5e3d5..4ecdadc4aee9 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -9322,3 +9322,25 @@ const struct bpf_func_proto bpf_skc_to_tcp_request_sock_proto = { > .check_btf_id = check_arg_btf_id, > .ret_btf_id = &sock_cast_btf_ids[SOCK_CAST_TCP_REQ_SOCK], > }; > + > +BPF_CALL_1(bpf_skc_to_udp6_sock, struct sock *, sk) > +{ > + /* udp6_sock type is not generated in dwarf and hence btf, > + * trigger an explicit type generation here. > + */ > + BTF_TYPE_EMIT(struct udp6_sock); > + if (sk_fullsock(sk) && sk->sk_protocol == IPPROTO_UDP && > + sk->sk_family == AF_INET6) > + return (unsigned long)sk; > + > + return (unsigned long)NULL; > +} > + > +const struct bpf_func_proto bpf_skc_to_udp6_sock_proto = { > + .func = bpf_skc_to_udp6_sock, > + .gpl_only = true, Same gpl_only change is needed. Acked-by: Martin KaFai Lau <kafai@xxxxxx>