// SPDX-License-Identifier: GPL-2.0 #include "vmlinux.h" #include <bpf/bpf_helpers.h> #include <bpf/bpf_endian.h> #include "bpf_tracing_net.h" __be16 serv_port = 0; int bpf_sock_destroy(struct sock_common *sk) __ksym; struct { __uint(type, BPF_MAP_TYPE_ARRAY); __uint(max_entries, 1); __type(key, __u32); __type(value, __u64); } tcp_conn_sockets SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_ARRAY); __uint(max_entries, 1); __type(key, __u32); __type(value, __u64); } udp_conn_sockets SEC(".maps"); SEC("cgroup/connect6") int sock_connect(struct bpf_sock_addr *ctx) { __u64 sock_cookie = 0; int key = 0; __u32 keyc = 0; if (ctx->family != AF_INET6 || ctx->user_family != AF_INET6) return 1; sock_cookie = bpf_get_socket_cookie(ctx); if (ctx->protocol == IPPROTO_TCP) bpf_map_update_elem(&tcp_conn_sockets, &key, &sock_cookie, 0); else if (ctx->protocol == IPPROTO_UDP) bpf_map_update_elem(&udp_conn_sockets, &keyc, &sock_cookie, 0); else return 1; return 1; } SEC("iter/tcp") int iter_tcp6_client(struct bpf_iter__tcp *ctx) { struct sock_common *sk_common = ctx->sk_common; __u64 sock_cookie = 0; __u64 *val; int key = 0; if (!sk_common) return 0; if (sk_common->skc_family != AF_INET6) return 0; sock_cookie = bpf_get_socket_cookie(sk_common); val = bpf_map_lookup_elem(&tcp_conn_sockets, &key); if (!val) return 0; /* Destroy connected client sockets. */ if (sock_cookie == *val) bpf_sock_destroy(sk_common); return 0; } SEC("iter/tcp") int iter_tcp6_server(struct bpf_iter__tcp *ctx) { struct sock_common *sk_common = ctx->sk_common; const struct inet_connection_sock *icsk; const struct inet_sock *inet; struct tcp6_sock *tcp_sk; __be16 srcp; if (!sk_common) return 0; if (sk_common->skc_family != AF_INET6) return 0; tcp_sk = bpf_skc_to_tcp6_sock(sk_common); if (!tcp_sk) return 0; icsk = &tcp_sk->tcp.inet_conn; inet = &icsk->icsk_inet; srcp = inet->inet_sport; /* Destroy server sockets. */ if (srcp == serv_port) bpf_sock_destroy(sk_common); return 0; } SEC("iter/udp") int iter_udp6_client(struct bpf_iter__udp *ctx) { struct udp_sock *udp_sk = ctx->udp_sk; struct sock *sk = (struct sock *) udp_sk; __u64 sock_cookie = 0, *val; int key = 0; if (!sk) return 0; sock_cookie = bpf_get_socket_cookie(sk); val = bpf_map_lookup_elem(&udp_conn_sockets, &key); if (!val) return 0; /* Destroy connected client sockets. */ if (sock_cookie == *val) bpf_sock_destroy((struct sock_common *)sk); return 0; } SEC("iter/udp") int iter_udp6_server(struct bpf_iter__udp *ctx) { struct udp_sock *udp_sk = ctx->udp_sk; struct sock *sk = (struct sock *) udp_sk; struct inet_sock *inet; __be16 srcp; if (!sk) return 0; inet = &udp_sk->inet; srcp = inet->inet_sport; if (srcp == serv_port) bpf_sock_destroy((struct sock_common *)sk); return 0; } char _license[] SEC("license") = "GPL";