~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/progs/test_sk_lookup_kern.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 // Copyright (c) 2018 Covalent IO, Inc. http://covalent.io
  3 
  4 #include <stddef.h>
  5 #include <stdbool.h>
  6 #include <string.h>
  7 #include <linux/bpf.h>
  8 #include <linux/if_ether.h>
  9 #include <linux/in.h>
 10 #include <linux/ip.h>
 11 #include <linux/ipv6.h>
 12 #include <linux/pkt_cls.h>
 13 #include <linux/tcp.h>
 14 #include <sys/socket.h>
 15 #include <bpf/bpf_helpers.h>
 16 #include <bpf/bpf_endian.h>
 17 
 18 char _license[] SEC("license") = "GPL";
 19 
 20 /* Fill 'tuple' with L3 info, and attempt to find L4. On fail, return NULL. */
 21 static struct bpf_sock_tuple *get_tuple(void *data, __u64 nh_off,
 22                                         void *data_end, __u16 eth_proto,
 23                                         bool *ipv4)
 24 {
 25         struct bpf_sock_tuple *result;
 26         __u64 ihl_len = 0;
 27         __u8 proto = 0;
 28 
 29         if (eth_proto == bpf_htons(ETH_P_IP)) {
 30                 struct iphdr *iph = (struct iphdr *)(data + nh_off);
 31 
 32                 if (iph + 1 > data_end)
 33                         return NULL;
 34                 ihl_len = iph->ihl * 4;
 35                 proto = iph->protocol;
 36                 *ipv4 = true;
 37                 result = (struct bpf_sock_tuple *)&iph->saddr;
 38         } else if (eth_proto == bpf_htons(ETH_P_IPV6)) {
 39                 struct ipv6hdr *ip6h = (struct ipv6hdr *)(data + nh_off);
 40 
 41                 if (ip6h + 1 > data_end)
 42                         return NULL;
 43                 ihl_len = sizeof(*ip6h);
 44                 proto = ip6h->nexthdr;
 45                 *ipv4 = true;
 46                 result = (struct bpf_sock_tuple *)&ip6h->saddr;
 47         }
 48 
 49         if (data + nh_off + ihl_len > data_end || proto != IPPROTO_TCP)
 50                 return NULL;
 51 
 52         return result;
 53 }
 54 
 55 SEC("?tc")
 56 int sk_lookup_success(struct __sk_buff *skb)
 57 {
 58         void *data_end = (void *)(long)skb->data_end;
 59         void *data = (void *)(long)skb->data;
 60         struct ethhdr *eth = (struct ethhdr *)(data);
 61         struct bpf_sock_tuple *tuple;
 62         struct bpf_sock *sk;
 63         size_t tuple_len;
 64         bool ipv4;
 65 
 66         if (eth + 1 > data_end)
 67                 return TC_ACT_SHOT;
 68 
 69         tuple = get_tuple(data, sizeof(*eth), data_end, eth->h_proto, &ipv4);
 70         if (!tuple || tuple + sizeof *tuple > data_end)
 71                 return TC_ACT_SHOT;
 72 
 73         tuple_len = ipv4 ? sizeof(tuple->ipv4) : sizeof(tuple->ipv6);
 74         sk = bpf_sk_lookup_tcp(skb, tuple, tuple_len, BPF_F_CURRENT_NETNS, 0);
 75         bpf_printk("sk=%d\n", sk ? 1 : 0);
 76         if (sk)
 77                 bpf_sk_release(sk);
 78         return sk ? TC_ACT_OK : TC_ACT_UNSPEC;
 79 }
 80 
 81 SEC("?tc")
 82 int sk_lookup_success_simple(struct __sk_buff *skb)
 83 {
 84         struct bpf_sock_tuple tuple = {};
 85         struct bpf_sock *sk;
 86 
 87         sk = bpf_sk_lookup_tcp(skb, &tuple, sizeof(tuple), BPF_F_CURRENT_NETNS, 0);
 88         if (sk)
 89                 bpf_sk_release(sk);
 90         return 0;
 91 }
 92 
 93 SEC("?tc")
 94 int err_use_after_free(struct __sk_buff *skb)
 95 {
 96         struct bpf_sock_tuple tuple = {};
 97         struct bpf_sock *sk;
 98         __u32 family = 0;
 99 
100         sk = bpf_sk_lookup_tcp(skb, &tuple, sizeof(tuple), BPF_F_CURRENT_NETNS, 0);
101         if (sk) {
102                 bpf_sk_release(sk);
103                 family = sk->family;
104         }
105         return family;
106 }
107 
108 SEC("?tc")
109 int err_modify_sk_pointer(struct __sk_buff *skb)
110 {
111         struct bpf_sock_tuple tuple = {};
112         struct bpf_sock *sk;
113 
114         sk = bpf_sk_lookup_tcp(skb, &tuple, sizeof(tuple), BPF_F_CURRENT_NETNS, 0);
115         if (sk) {
116                 sk += 1;
117                 bpf_sk_release(sk);
118         }
119         return 0;
120 }
121 
122 SEC("?tc")
123 int err_modify_sk_or_null_pointer(struct __sk_buff *skb)
124 {
125         struct bpf_sock_tuple tuple = {};
126         struct bpf_sock *sk;
127 
128         sk = bpf_sk_lookup_tcp(skb, &tuple, sizeof(tuple), BPF_F_CURRENT_NETNS, 0);
129         sk += 1;
130         if (sk)
131                 bpf_sk_release(sk);
132         return 0;
133 }
134 
135 SEC("?tc")
136 int err_no_release(struct __sk_buff *skb)
137 {
138         struct bpf_sock_tuple tuple = {};
139 
140         bpf_sk_lookup_tcp(skb, &tuple, sizeof(tuple), BPF_F_CURRENT_NETNS, 0);
141         return 0;
142 }
143 
144 SEC("?tc")
145 int err_release_twice(struct __sk_buff *skb)
146 {
147         struct bpf_sock_tuple tuple = {};
148         struct bpf_sock *sk;
149 
150         sk = bpf_sk_lookup_tcp(skb, &tuple, sizeof(tuple), BPF_F_CURRENT_NETNS, 0);
151         bpf_sk_release(sk);
152         bpf_sk_release(sk);
153         return 0;
154 }
155 
156 SEC("?tc")
157 int err_release_unchecked(struct __sk_buff *skb)
158 {
159         struct bpf_sock_tuple tuple = {};
160         struct bpf_sock *sk;
161 
162         sk = bpf_sk_lookup_tcp(skb, &tuple, sizeof(tuple), BPF_F_CURRENT_NETNS, 0);
163         bpf_sk_release(sk);
164         return 0;
165 }
166 
167 void lookup_no_release(struct __sk_buff *skb)
168 {
169         struct bpf_sock_tuple tuple = {};
170         bpf_sk_lookup_tcp(skb, &tuple, sizeof(tuple), BPF_F_CURRENT_NETNS, 0);
171 }
172 
173 SEC("?tc")
174 int err_no_release_subcall(struct __sk_buff *skb)
175 {
176         lookup_no_release(skb);
177         return 0;
178 }
179 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php