1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
// 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";
|