diff options
| author | Alexei Starovoitov <ast@kernel.org> | 2022-08-18 17:06:14 -0700 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2022-08-18 17:06:14 -0700 |
| commit | 75179e2b7f9a9b6dbca735a5ca7420a7e983c7e2 (patch) | |
| tree | 9edc14833091c2cc1a414ee87585df31e45d36a9 /include | |
| parent | fb8d784b531e363171c7e22f4f0980b4b128a607 (diff) | |
| parent | 31123c0360e01ee0389aee3a7b2ad32f13136662 (diff) | |
Merge branch 'bpf: net: Remove duplicated code from bpf_setsockopt()'
Martin KaFai Lau says:
====================
The code in bpf_setsockopt() is mostly a copy-and-paste from
the sock_setsockopt(), do_tcp_setsockopt(), do_ipv6_setsockopt(),
and do_ip_setsockopt(). As the allowed optnames in bpf_setsockopt()
grows, so are the duplicated code. The code between the copies
also slowly drifted.
This set is an effort to clean this up and reuse the existing
{sock,do_tcp,do_ipv6,do_ip}_setsockopt() as much as possible.
After the clean up, this set also adds a few allowed optnames
that we need to the bpf_setsockopt().
The initial attempt was to clean up both bpf_setsockopt() and
bpf_getsockopt() together. However, the patch set was getting
too long. It is beneficial to leave the bpf_getsockopt()
out for another patch set. Thus, this set is focusing
on the bpf_setsockopt().
v4:
- This set now depends on the commit f574f7f839fc ("net: bpf: Use the protocol's set_rcvlowat behavior if there is one")
in the net-next tree. The commit calls a specific protocol's
set_rcvlowat and it changed the bpf_setsockopt
which this set has also changed.
Because of this, patch 9 of this set has also adjusted
and a 'sock' NULL check is added to the sk_setsockopt()
because some of the bpf hooks have a NULL sk->sk_socket.
This removes more dup code from the bpf_setsockopt() side.
- Avoid mentioning specific prog types in the comment of
the has_current_bpf_ctx(). (Andrii)
- Replace signed with unsigned int bitfield in the
patch 15 selftest. (Daniel)
v3:
- s/in_bpf/has_current_bpf_ctx/ (Andrii)
- Add comment to has_current_bpf_ctx() and sockopt_lock_sock()
(Stanislav)
- Use vmlinux.h in selftest and add defines to bpf_tracing_net.h
(Stanislav)
- Use bpf_getsockopt(SO_MARK) in selftest (Stanislav)
- Use BPF_CORE_READ_BITFIELD in selftest (Yonghong)
v2:
- A major change is to use in_bpf() to test if a setsockopt()
is called by a bpf prog and use in_bpf() to skip capable
check. Suggested by Stanislav.
- Instead of passing is_locked through sockptr_t or through an extra
argument to sk_setsockopt, v2 uses in_bpf() to skip the lock_sock()
also because bpf prog has the lock acquired.
- No change to the current sockptr_t in this revision
- s/codes/code/
====================
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/bpf.h | 13 | ||||
| -rw-r--r-- | include/net/ip.h | 2 | ||||
| -rw-r--r-- | include/net/ipv6.h | 2 | ||||
| -rw-r--r-- | include/net/ipv6_stubs.h | 2 | ||||
| -rw-r--r-- | include/net/sock.h | 7 | ||||
| -rw-r--r-- | include/net/tcp.h | 2 |
6 files changed, 28 insertions, 0 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index a627a02cf8ab..39bd36359c1e 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1966,6 +1966,15 @@ static inline bool unprivileged_ebpf_enabled(void) return !sysctl_unprivileged_bpf_disabled; } +/* Not all bpf prog type has the bpf_ctx. + * For the bpf prog type that has initialized the bpf_ctx, + * this function can be used to decide if a kernel function + * is called by a bpf program. + */ +static inline bool has_current_bpf_ctx(void) +{ + return !!current->bpf_ctx; +} #else /* !CONFIG_BPF_SYSCALL */ static inline struct bpf_prog *bpf_prog_get(u32 ufd) { @@ -2175,6 +2184,10 @@ static inline bool unprivileged_ebpf_enabled(void) return false; } +static inline bool has_current_bpf_ctx(void) +{ + return false; +} #endif /* CONFIG_BPF_SYSCALL */ void __bpf_free_used_btfs(struct bpf_prog_aux *aux, diff --git a/include/net/ip.h b/include/net/ip.h index 1c979fd1904c..34fa5b0f0a0e 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -743,6 +743,8 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc, bool allow_ipv6); DECLARE_STATIC_KEY_FALSE(ip4_min_ttl); +int do_ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, + unsigned int optlen); int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, unsigned int optlen); int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, diff --git a/include/net/ipv6.h b/include/net/ipv6.h index de9dcc5652c4..c110d9032083 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -1156,6 +1156,8 @@ struct in6_addr *fl6_update_dst(struct flowi6 *fl6, */ DECLARE_STATIC_KEY_FALSE(ip6_min_hopcount); +int do_ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, + unsigned int optlen); int ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, unsigned int optlen); int ipv6_getsockopt(struct sock *sk, int level, int optname, diff --git a/include/net/ipv6_stubs.h b/include/net/ipv6_stubs.h index 45e0339be6fa..8692698b01cf 100644 --- a/include/net/ipv6_stubs.h +++ b/include/net/ipv6_stubs.h @@ -81,6 +81,8 @@ struct ipv6_bpf_stub { const struct in6_addr *daddr, __be16 dport, int dif, int sdif, struct udp_table *tbl, struct sk_buff *skb); + int (*ipv6_setsockopt)(struct sock *sk, int level, int optname, + sockptr_t optval, unsigned int optlen); }; extern const struct ipv6_bpf_stub *ipv6_bpf_stub __read_mostly; diff --git a/include/net/sock.h b/include/net/sock.h index 05a1bbdf5805..ee44b424d952 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1749,6 +1749,11 @@ static inline void unlock_sock_fast(struct sock *sk, bool slow) } } +void sockopt_lock_sock(struct sock *sk); +void sockopt_release_sock(struct sock *sk); +bool sockopt_ns_capable(struct user_namespace *ns, int cap); +bool sockopt_capable(int cap); + /* Used by processes to "lock" a socket state, so that * interrupts and bottom half handlers won't change it * from under us. It essentially blocks any incoming @@ -1823,6 +1828,8 @@ void sock_pfree(struct sk_buff *skb); #define sock_edemux sock_efree #endif +int sk_setsockopt(struct sock *sk, int level, int optname, + sockptr_t optval, unsigned int optlen); int sock_setsockopt(struct socket *sock, int level, int op, sockptr_t optval, unsigned int optlen); diff --git a/include/net/tcp.h b/include/net/tcp.h index d10962b9f0d0..c03a50c72f40 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -405,6 +405,8 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); bool tcp_bpf_bypass_getsockopt(int level, int optname); +int do_tcp_setsockopt(struct sock *sk, int level, int optname, + sockptr_t optval, unsigned int optlen); int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, unsigned int optlen); void tcp_set_keepalive(struct sock *sk, int val); |
