Skip to content

Commit 6a5a313

Browse files
committed
Merge: bpf: Add bpf_sock_destroy kfunc
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6255 JIRA: https://issues.redhat.com/browse/RHEL-65787 Backporting bpf_sock_destroy() kfunc, and associated BPF selftests Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> Approved-by: Viktor Malik <vmalik@redhat.com> Approved-by: Felix Maurer <fmaurer@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Patrick Talbert <ptalbert@redhat.com>
2 parents 02e631b + ade92ad commit 6a5a313

File tree

15 files changed

+805
-100
lines changed

15 files changed

+805
-100
lines changed

include/net/netns/ipv4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct netns_ipv4 {
8282

8383
/* Please keep tcp_death_row at first field in netns_ipv4 */
8484
struct inet_timewait_death_row tcp_death_row ____cacheline_aligned_in_smp;
85+
struct udp_table *udp_table;
8586

8687
#ifdef CONFIG_SYSCTL
8788
struct ctl_table_header *forw_hdr;

include/net/udp.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,6 @@ struct udp_seq_afinfo {
431431
struct udp_iter_state {
432432
struct seq_net_private p;
433433
int bucket;
434-
struct udp_seq_afinfo *bpf_seq_afinfo;
435434
};
436435

437436
void *udp_seq_start(struct seq_file *seq, loff_t *pos);

net/core/filter.c

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6597,7 +6597,7 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
65976597
else
65986598
sk = __udp4_lib_lookup(net, src4, tuple->ipv4.sport,
65996599
dst4, tuple->ipv4.dport,
6600-
dif, sdif, &udp_table, NULL);
6600+
dif, sdif, net->ipv4.udp_table, NULL);
66016601
#if IS_ENABLED(CONFIG_IPV6)
66026602
} else {
66036603
struct in6_addr *src6 = (struct in6_addr *)&tuple->ipv6.saddr;
@@ -6613,7 +6613,7 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
66136613
src6, tuple->ipv6.sport,
66146614
dst6, tuple->ipv6.dport,
66156615
dif, sdif,
6616-
&udp_table, NULL);
6616+
net->ipv4.udp_table, NULL);
66176617
#endif
66186618
}
66196619

@@ -11891,3 +11891,63 @@ static int __init bpf_kfunc_init(void)
1189111891
return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp);
1189211892
}
1189311893
late_initcall(bpf_kfunc_init);
11894+
11895+
__bpf_kfunc_start_defs();
11896+
11897+
/* bpf_sock_destroy: Destroy the given socket with ECONNABORTED error code.
11898+
*
11899+
* The function expects a non-NULL pointer to a socket, and invokes the
11900+
* protocol specific socket destroy handlers.
11901+
*
11902+
* The helper can only be called from BPF contexts that have acquired the socket
11903+
* locks.
11904+
*
11905+
* Parameters:
11906+
* @sock: Pointer to socket to be destroyed
11907+
*
11908+
* Return:
11909+
* On error, may return EPROTONOSUPPORT, EINVAL.
11910+
* EPROTONOSUPPORT if protocol specific destroy handler is not supported.
11911+
* 0 otherwise
11912+
*/
11913+
__bpf_kfunc int bpf_sock_destroy(struct sock_common *sock)
11914+
{
11915+
struct sock *sk = (struct sock *)sock;
11916+
11917+
/* The locking semantics that allow for synchronous execution of the
11918+
* destroy handlers are only supported for TCP and UDP.
11919+
* Supporting protocols will need to acquire sock lock in the BPF context
11920+
* prior to invoking this kfunc.
11921+
*/
11922+
if (!sk->sk_prot->diag_destroy || (sk->sk_protocol != IPPROTO_TCP &&
11923+
sk->sk_protocol != IPPROTO_UDP))
11924+
return -EOPNOTSUPP;
11925+
11926+
return sk->sk_prot->diag_destroy(sk, ECONNABORTED);
11927+
}
11928+
11929+
__bpf_kfunc_end_defs();
11930+
11931+
BTF_KFUNCS_START(bpf_sk_iter_kfunc_ids)
11932+
BTF_ID_FLAGS(func, bpf_sock_destroy, KF_TRUSTED_ARGS)
11933+
BTF_KFUNCS_END(bpf_sk_iter_kfunc_ids)
11934+
11935+
static int tracing_iter_filter(const struct bpf_prog *prog, u32 kfunc_id)
11936+
{
11937+
if (btf_id_set8_contains(&bpf_sk_iter_kfunc_ids, kfunc_id) &&
11938+
prog->expected_attach_type != BPF_TRACE_ITER)
11939+
return -EACCES;
11940+
return 0;
11941+
}
11942+
11943+
static const struct btf_kfunc_id_set bpf_sk_iter_kfunc_set = {
11944+
.owner = THIS_MODULE,
11945+
.set = &bpf_sk_iter_kfunc_ids,
11946+
.filter = tracing_iter_filter,
11947+
};
11948+
11949+
static int init_subsystem(void)
11950+
{
11951+
return register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_sk_iter_kfunc_set);
11952+
}
11953+
late_initcall(init_subsystem);

net/ipv4/tcp.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4716,8 +4716,10 @@ int tcp_abort(struct sock *sk, int err)
47164716
return -EOPNOTSUPP;
47174717
}
47184718

4719-
/* Don't race with userspace socket closes such as tcp_close. */
4720-
lock_sock(sk);
4719+
/* BPF context ensures sock locking. */
4720+
if (!has_current_bpf_ctx())
4721+
/* Don't race with userspace socket closes such as tcp_close. */
4722+
lock_sock(sk);
47214723

47224724
/* Avoid closing the same socket twice. */
47234725
if (sk->sk_state == TCP_CLOSE) {
@@ -4745,7 +4747,8 @@ int tcp_abort(struct sock *sk, int err)
47454747

47464748
bh_unlock_sock(sk);
47474749
local_bh_enable();
4748-
release_sock(sk);
4750+
if (!has_current_bpf_ctx())
4751+
release_sock(sk);
47494752
return 0;
47504753
}
47514754
EXPORT_SYMBOL_GPL(tcp_abort);

net/ipv4/tcp_ipv4.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2916,15 +2916,14 @@ static int bpf_iter_tcp_seq_show(struct seq_file *seq, void *v)
29162916
struct bpf_iter_meta meta;
29172917
struct bpf_prog *prog;
29182918
struct sock *sk = v;
2919-
bool slow;
29202919
uid_t uid;
29212920
int ret;
29222921

29232922
if (v == SEQ_START_TOKEN)
29242923
return 0;
29252924

29262925
if (sk_fullsock(sk))
2927-
slow = lock_sock_fast(sk);
2926+
lock_sock(sk);
29282927

29292928
if (unlikely(sk_unhashed(sk))) {
29302929
ret = SEQ_SKIP;
@@ -2948,7 +2947,7 @@ static int bpf_iter_tcp_seq_show(struct seq_file *seq, void *v)
29482947

29492948
unlock:
29502949
if (sk_fullsock(sk))
2951-
unlock_sock_fast(sk, slow);
2950+
release_sock(sk);
29522951
return ret;
29532952

29542953
}
@@ -3303,7 +3302,7 @@ static struct bpf_iter_reg tcp_reg_info = {
33033302
.ctx_arg_info_size = 1,
33043303
.ctx_arg_info = {
33053304
{ offsetof(struct bpf_iter__tcp, sk_common),
3306-
PTR_TO_BTF_ID_OR_NULL },
3305+
PTR_TO_BTF_ID_OR_NULL | PTR_TRUSTED },
33073306
},
33083307
.get_func_proto = bpf_iter_tcp_get_func_proto,
33093308
.seq_info = &tcp_seq_info,

0 commit comments

Comments
 (0)