1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/bpf.h> |
3 | #include <bpf/bpf_helpers.h> |
4 | #include <bpf/bpf_endian.h> |
5 | |
6 | #include <linux/ip.h> |
7 | #include <linux/in.h> |
8 | #include <linux/if_ether.h> |
9 | #include <linux/pkt_cls.h> |
10 | #include <stdbool.h> |
11 | |
12 | int lookup_status; |
13 | bool test_xdp; |
14 | bool tcp_skc; |
15 | |
16 | #define CUR_NS BPF_F_CURRENT_NETNS |
17 | |
18 | static void socket_lookup(void *ctx, void *data_end, void *data) |
19 | { |
20 | struct ethhdr *eth = data; |
21 | struct bpf_sock_tuple *tp; |
22 | struct bpf_sock *sk; |
23 | struct iphdr *iph; |
24 | int tplen; |
25 | |
26 | if (eth + 1 > data_end) |
27 | return; |
28 | |
29 | if (eth->h_proto != bpf_htons(ETH_P_IP)) |
30 | return; |
31 | |
32 | iph = (struct iphdr *)(eth + 1); |
33 | if (iph + 1 > data_end) |
34 | return; |
35 | |
36 | tp = (struct bpf_sock_tuple *)&iph->saddr; |
37 | tplen = sizeof(tp->ipv4); |
38 | if ((void *)tp + tplen > data_end) |
39 | return; |
40 | |
41 | switch (iph->protocol) { |
42 | case IPPROTO_TCP: |
43 | if (tcp_skc) |
44 | sk = bpf_skc_lookup_tcp(ctx, tp, tplen, CUR_NS, 0); |
45 | else |
46 | sk = bpf_sk_lookup_tcp(ctx, tp, tplen, CUR_NS, 0); |
47 | break; |
48 | case IPPROTO_UDP: |
49 | sk = bpf_sk_lookup_udp(ctx, tp, tplen, CUR_NS, 0); |
50 | break; |
51 | default: |
52 | return; |
53 | } |
54 | |
55 | lookup_status = 0; |
56 | |
57 | if (sk) { |
58 | bpf_sk_release(sk); |
59 | lookup_status = 1; |
60 | } |
61 | } |
62 | |
63 | SEC("tc" ) |
64 | int tc_socket_lookup(struct __sk_buff *skb) |
65 | { |
66 | void *data_end = (void *)(long)skb->data_end; |
67 | void *data = (void *)(long)skb->data; |
68 | |
69 | if (test_xdp) |
70 | return TC_ACT_UNSPEC; |
71 | |
72 | socket_lookup(ctx: skb, data_end, data); |
73 | return TC_ACT_UNSPEC; |
74 | } |
75 | |
76 | SEC("xdp" ) |
77 | int xdp_socket_lookup(struct xdp_md *xdp) |
78 | { |
79 | void *data_end = (void *)(long)xdp->data_end; |
80 | void *data = (void *)(long)xdp->data; |
81 | |
82 | if (!test_xdp) |
83 | return XDP_PASS; |
84 | |
85 | socket_lookup(ctx: xdp, data_end, data); |
86 | return XDP_PASS; |
87 | } |
88 | |
89 | char _license[] SEC("license" ) = "GPL" ; |
90 | |