1 | // SPDX-License-Identifier: GPL-2.0 |
2 | |
3 | #include "vmlinux.h" |
4 | #include <bpf/bpf_helpers.h> |
5 | #include <bpf/bpf_endian.h> |
6 | |
7 | #include "bpf_tracing_net.h" |
8 | |
9 | __be16 serv_port = 0; |
10 | |
11 | int bpf_sock_destroy(struct sock_common *sk) __ksym; |
12 | |
13 | struct { |
14 | __uint(type, BPF_MAP_TYPE_ARRAY); |
15 | __uint(max_entries, 1); |
16 | __type(key, __u32); |
17 | __type(value, __u64); |
18 | } tcp_conn_sockets SEC(".maps" ); |
19 | |
20 | struct { |
21 | __uint(type, BPF_MAP_TYPE_ARRAY); |
22 | __uint(max_entries, 1); |
23 | __type(key, __u32); |
24 | __type(value, __u64); |
25 | } udp_conn_sockets SEC(".maps" ); |
26 | |
27 | SEC("cgroup/connect6" ) |
28 | int sock_connect(struct bpf_sock_addr *ctx) |
29 | { |
30 | __u64 sock_cookie = 0; |
31 | int key = 0; |
32 | __u32 keyc = 0; |
33 | |
34 | if (ctx->family != AF_INET6 || ctx->user_family != AF_INET6) |
35 | return 1; |
36 | |
37 | sock_cookie = bpf_get_socket_cookie(ctx); |
38 | if (ctx->protocol == IPPROTO_TCP) |
39 | bpf_map_update_elem(&tcp_conn_sockets, &key, &sock_cookie, 0); |
40 | else if (ctx->protocol == IPPROTO_UDP) |
41 | bpf_map_update_elem(&udp_conn_sockets, &keyc, &sock_cookie, 0); |
42 | else |
43 | return 1; |
44 | |
45 | return 1; |
46 | } |
47 | |
48 | SEC("iter/tcp" ) |
49 | int iter_tcp6_client(struct bpf_iter__tcp *ctx) |
50 | { |
51 | struct sock_common *sk_common = ctx->sk_common; |
52 | __u64 sock_cookie = 0; |
53 | __u64 *val; |
54 | int key = 0; |
55 | |
56 | if (!sk_common) |
57 | return 0; |
58 | |
59 | if (sk_common->skc_family != AF_INET6) |
60 | return 0; |
61 | |
62 | sock_cookie = bpf_get_socket_cookie(sk_common); |
63 | val = bpf_map_lookup_elem(&tcp_conn_sockets, &key); |
64 | if (!val) |
65 | return 0; |
66 | /* Destroy connected client sockets. */ |
67 | if (sock_cookie == *val) |
68 | bpf_sock_destroy(sk_common); |
69 | |
70 | return 0; |
71 | } |
72 | |
73 | SEC("iter/tcp" ) |
74 | int iter_tcp6_server(struct bpf_iter__tcp *ctx) |
75 | { |
76 | struct sock_common *sk_common = ctx->sk_common; |
77 | const struct inet_connection_sock *icsk; |
78 | const struct inet_sock *inet; |
79 | struct tcp6_sock *tcp_sk; |
80 | __be16 srcp; |
81 | |
82 | if (!sk_common) |
83 | return 0; |
84 | |
85 | if (sk_common->skc_family != AF_INET6) |
86 | return 0; |
87 | |
88 | tcp_sk = bpf_skc_to_tcp6_sock(sk_common); |
89 | if (!tcp_sk) |
90 | return 0; |
91 | |
92 | icsk = &tcp_sk->tcp.inet_conn; |
93 | inet = &icsk->icsk_inet; |
94 | srcp = inet->inet_sport; |
95 | |
96 | /* Destroy server sockets. */ |
97 | if (srcp == serv_port) |
98 | bpf_sock_destroy(sk_common); |
99 | |
100 | return 0; |
101 | } |
102 | |
103 | |
104 | SEC("iter/udp" ) |
105 | int iter_udp6_client(struct bpf_iter__udp *ctx) |
106 | { |
107 | struct udp_sock *udp_sk = ctx->udp_sk; |
108 | struct sock *sk = (struct sock *) udp_sk; |
109 | __u64 sock_cookie = 0, *val; |
110 | int key = 0; |
111 | |
112 | if (!sk) |
113 | return 0; |
114 | |
115 | sock_cookie = bpf_get_socket_cookie(sk); |
116 | val = bpf_map_lookup_elem(&udp_conn_sockets, &key); |
117 | if (!val) |
118 | return 0; |
119 | /* Destroy connected client sockets. */ |
120 | if (sock_cookie == *val) |
121 | bpf_sock_destroy((struct sock_common *)sk); |
122 | |
123 | return 0; |
124 | } |
125 | |
126 | SEC("iter/udp" ) |
127 | int iter_udp6_server(struct bpf_iter__udp *ctx) |
128 | { |
129 | struct udp_sock *udp_sk = ctx->udp_sk; |
130 | struct sock *sk = (struct sock *) udp_sk; |
131 | struct inet_sock *inet; |
132 | __be16 srcp; |
133 | |
134 | if (!sk) |
135 | return 0; |
136 | |
137 | inet = &udp_sk->inet; |
138 | srcp = inet->inet_sport; |
139 | if (srcp == serv_port) |
140 | bpf_sock_destroy((struct sock_common *)sk); |
141 | |
142 | return 0; |
143 | } |
144 | |
145 | char _license[] SEC("license" ) = "GPL" ; |
146 | |