1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
3
4 #include <linux/types.h>
5 #include <linux/bpf.h>
6 #include <linux/pkt_cls.h>
7 #include <linux/if_ether.h>
8 #include <linux/ip.h>
9 #include <linux/in.h>
10 #include <bpf/bpf_helpers.h>
11 #include <bpf/bpf_endian.h>
12
13 struct bpf_fib_lookup fib_params = {};
14 int fib_lookup_ret = 0;
15 int lookup_flags = 0;
16
17 SEC("tc")
fib_lookup(struct __sk_buff * skb)18 int fib_lookup(struct __sk_buff *skb)
19 {
20 fib_lookup_ret = bpf_fib_lookup(skb, &fib_params, sizeof(fib_params),
21 lookup_flags);
22
23 return TC_ACT_SHOT;
24 }
25
26 SEC("xdp")
fib_lookup_xdp(struct xdp_md * ctx)27 int fib_lookup_xdp(struct xdp_md *ctx)
28 {
29 fib_lookup_ret = bpf_fib_lookup(ctx, &fib_params, sizeof(fib_params),
30 lookup_flags);
31
32 return XDP_DROP;
33 }
34
35 int redirected = 0;
36 int passed = 0;
37 int delivered = 0;
38
39 SEC("xdp")
fib_lookup_redirect(struct xdp_md * ctx)40 int fib_lookup_redirect(struct xdp_md *ctx)
41 {
42 struct bpf_fib_lookup params = fib_params;
43 long ret;
44
45 ret = bpf_fib_lookup(ctx, ¶ms, sizeof(params), lookup_flags);
46 if (ret == BPF_FIB_LKUP_RET_SUCCESS) {
47 redirected++;
48 return bpf_redirect(params.ifindex, 0);
49 }
50
51 passed++;
52 return XDP_PASS;
53 }
54
55 SEC("xdp")
xdp_count(struct xdp_md * ctx)56 int xdp_count(struct xdp_md *ctx)
57 {
58 void *data = (void *)(long)ctx->data;
59 void *data_end = (void *)(long)ctx->data_end;
60 struct ethhdr *eth = data;
61 struct iphdr *iph;
62
63 /*
64 * count only the test's TCP frames: the netns has live
65 * link-local traffic (DAD, MLD) that would satisfy a bare
66 * counter
67 */
68 if ((void *)(eth + 1) > data_end ||
69 eth->h_proto != bpf_htons(ETH_P_IP))
70 return XDP_DROP;
71 iph = (void *)(eth + 1);
72 if ((void *)(iph + 1) > data_end || iph->protocol != IPPROTO_TCP)
73 return XDP_DROP;
74
75 delivered++;
76 return XDP_DROP;
77 }
78
79 char _license[] SEC("license") = "GPL";
80