90 lines · c
1// SPDX-License-Identifier: GPL-2.02#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 12int lookup_status;13bool test_xdp;14bool tcp_skc;15 16#define CUR_NS BPF_F_CURRENT_NETNS17 18static 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 else46 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 63SEC("tc")64int 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(skb, data_end, data);73 return TC_ACT_UNSPEC;74}75 76SEC("xdp")77int 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(xdp, data_end, data);86 return XDP_PASS;87}88 89char _license[] SEC("license") = "GPL";90