xref: /linux/tools/testing/selftests/bpf/progs/fib_lookup.c (revision 5a8cd539ac19f7a68e68e1d25ef9ca2ff55b8500)
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, &params, 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