selftests/bpf: Fix erroneous bitmask operation
[platform/kernel/linux-rpi.git] / tools / testing / selftests / bpf / progs / vrf_socket_lookup.c
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(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(xdp, data_end, data);
86         return XDP_PASS;
87 }
88
89 char _license[] SEC("license") = "GPL";