1*8259fdebSStanislav Fomichev // SPDX-License-Identifier: GPL-2.0 2*8259fdebSStanislav Fomichev 3*8259fdebSStanislav Fomichev #include <linux/stddef.h> 4*8259fdebSStanislav Fomichev #include <linux/bpf.h> 5*8259fdebSStanislav Fomichev #include <sys/types.h> 6*8259fdebSStanislav Fomichev #include <sys/socket.h> 7*8259fdebSStanislav Fomichev #include <bpf/bpf_helpers.h> 8*8259fdebSStanislav Fomichev #include <bpf/bpf_endian.h> 9*8259fdebSStanislav Fomichev bind_prog(struct bpf_sock_addr * ctx,int family)10*8259fdebSStanislav Fomichevstatic __always_inline int bind_prog(struct bpf_sock_addr *ctx, int family) 11*8259fdebSStanislav Fomichev { 12*8259fdebSStanislav Fomichev struct bpf_sock *sk; 13*8259fdebSStanislav Fomichev 14*8259fdebSStanislav Fomichev sk = ctx->sk; 15*8259fdebSStanislav Fomichev if (!sk) 16*8259fdebSStanislav Fomichev return 0; 17*8259fdebSStanislav Fomichev 18*8259fdebSStanislav Fomichev if (sk->family != family) 19*8259fdebSStanislav Fomichev return 0; 20*8259fdebSStanislav Fomichev 21*8259fdebSStanislav Fomichev if (ctx->type != SOCK_STREAM) 22*8259fdebSStanislav Fomichev return 0; 23*8259fdebSStanislav Fomichev 24*8259fdebSStanislav Fomichev /* Return 1 OR'ed with the first bit set to indicate 25*8259fdebSStanislav Fomichev * that CAP_NET_BIND_SERVICE should be bypassed. 26*8259fdebSStanislav Fomichev */ 27*8259fdebSStanislav Fomichev if (ctx->user_port == bpf_htons(111)) 28*8259fdebSStanislav Fomichev return (1 | 2); 29*8259fdebSStanislav Fomichev 30*8259fdebSStanislav Fomichev return 1; 31*8259fdebSStanislav Fomichev } 32*8259fdebSStanislav Fomichev 33*8259fdebSStanislav Fomichev SEC("cgroup/bind4") bind_v4_prog(struct bpf_sock_addr * ctx)34*8259fdebSStanislav Fomichevint bind_v4_prog(struct bpf_sock_addr *ctx) 35*8259fdebSStanislav Fomichev { 36*8259fdebSStanislav Fomichev return bind_prog(ctx, AF_INET); 37*8259fdebSStanislav Fomichev } 38*8259fdebSStanislav Fomichev 39*8259fdebSStanislav Fomichev SEC("cgroup/bind6") bind_v6_prog(struct bpf_sock_addr * ctx)40*8259fdebSStanislav Fomichevint bind_v6_prog(struct bpf_sock_addr *ctx) 41*8259fdebSStanislav Fomichev { 42*8259fdebSStanislav Fomichev return bind_prog(ctx, AF_INET6); 43*8259fdebSStanislav Fomichev } 44*8259fdebSStanislav Fomichev 45*8259fdebSStanislav Fomichev char _license[] SEC("license") = "GPL"; 46