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

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/test_sockmap_kern.h

Version: ~ [ linux-5.5-rc6 ] ~ [ linux-5.4.11 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.95 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.164 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.209 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.209 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /* Copyright (c) 2017-2018 Covalent IO, Inc. http://covalent.io */
  3 #include <stddef.h>
  4 #include <string.h>
  5 #include <linux/bpf.h>
  6 #include <linux/if_ether.h>
  7 #include <linux/if_packet.h>
  8 #include <linux/ip.h>
  9 #include <linux/ipv6.h>
 10 #include <linux/in.h>
 11 #include <linux/udp.h>
 12 #include <linux/tcp.h>
 13 #include <linux/pkt_cls.h>
 14 #include <sys/socket.h>
 15 #include "bpf_helpers.h"
 16 #include "bpf_endian.h"
 17 
 18 /* Sockmap sample program connects a client and a backend together
 19  * using cgroups.
 20  *
 21  *    client:X <---> frontend:80 client:X <---> backend:80
 22  *
 23  * For simplicity we hard code values here and bind 1:1. The hard
 24  * coded values are part of the setup in sockmap.sh script that
 25  * is associated with this BPF program.
 26  *
 27  * The bpf_printk is verbose and prints information as connections
 28  * are established and verdicts are decided.
 29  */
 30 
 31 #define bpf_printk(fmt, ...)                                    \
 32 ({                                                              \
 33                char ____fmt[] = fmt;                            \
 34                bpf_trace_printk(____fmt, sizeof(____fmt),       \
 35                                 ##__VA_ARGS__);                 \
 36 })
 37 
 38 struct bpf_map_def SEC("maps") sock_map = {
 39         .type = TEST_MAP_TYPE,
 40         .key_size = sizeof(int),
 41         .value_size = sizeof(int),
 42         .max_entries = 20,
 43 };
 44 
 45 struct bpf_map_def SEC("maps") sock_map_txmsg = {
 46         .type = TEST_MAP_TYPE,
 47         .key_size = sizeof(int),
 48         .value_size = sizeof(int),
 49         .max_entries = 20,
 50 };
 51 
 52 struct bpf_map_def SEC("maps") sock_map_redir = {
 53         .type = TEST_MAP_TYPE,
 54         .key_size = sizeof(int),
 55         .value_size = sizeof(int),
 56         .max_entries = 20,
 57 };
 58 
 59 struct bpf_map_def SEC("maps") sock_apply_bytes = {
 60         .type = BPF_MAP_TYPE_ARRAY,
 61         .key_size = sizeof(int),
 62         .value_size = sizeof(int),
 63         .max_entries = 1
 64 };
 65 
 66 struct bpf_map_def SEC("maps") sock_cork_bytes = {
 67         .type = BPF_MAP_TYPE_ARRAY,
 68         .key_size = sizeof(int),
 69         .value_size = sizeof(int),
 70         .max_entries = 1
 71 };
 72 
 73 struct bpf_map_def SEC("maps") sock_bytes = {
 74         .type = BPF_MAP_TYPE_ARRAY,
 75         .key_size = sizeof(int),
 76         .value_size = sizeof(int),
 77         .max_entries = 4
 78 };
 79 
 80 struct bpf_map_def SEC("maps") sock_redir_flags = {
 81         .type = BPF_MAP_TYPE_ARRAY,
 82         .key_size = sizeof(int),
 83         .value_size = sizeof(int),
 84         .max_entries = 1
 85 };
 86 
 87 struct bpf_map_def SEC("maps") sock_skb_opts = {
 88         .type = BPF_MAP_TYPE_ARRAY,
 89         .key_size = sizeof(int),
 90         .value_size = sizeof(int),
 91         .max_entries = 1
 92 };
 93 
 94 SEC("sk_skb1")
 95 int bpf_prog1(struct __sk_buff *skb)
 96 {
 97         return skb->len;
 98 }
 99 
100 SEC("sk_skb2")
101 int bpf_prog2(struct __sk_buff *skb)
102 {
103         __u32 lport = skb->local_port;
104         __u32 rport = skb->remote_port;
105         int len, *f, ret, zero = 0;
106         __u64 flags = 0;
107 
108         if (lport == 10000)
109                 ret = 10;
110         else
111                 ret = 1;
112 
113         len = (__u32)skb->data_end - (__u32)skb->data;
114         f = bpf_map_lookup_elem(&sock_skb_opts, &zero);
115         if (f && *f) {
116                 ret = 3;
117                 flags = *f;
118         }
119 
120         bpf_printk("sk_skb2: redirect(%iB) flags=%i\n",
121                    len, flags);
122 #ifdef SOCKMAP
123         return bpf_sk_redirect_map(skb, &sock_map, ret, flags);
124 #else
125         return bpf_sk_redirect_hash(skb, &sock_map, &ret, flags);
126 #endif
127 
128 }
129 
130 SEC("sockops")
131 int bpf_sockmap(struct bpf_sock_ops *skops)
132 {
133         __u32 lport, rport;
134         int op, err = 0, index, key, ret;
135 
136 
137         op = (int) skops->op;
138 
139         switch (op) {
140         case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
141                 lport = skops->local_port;
142                 rport = skops->remote_port;
143 
144                 if (lport == 10000) {
145                         ret = 1;
146 #ifdef SOCKMAP
147                         err = bpf_sock_map_update(skops, &sock_map, &ret,
148                                                   BPF_NOEXIST);
149 #else
150                         err = bpf_sock_hash_update(skops, &sock_map, &ret,
151                                                    BPF_NOEXIST);
152 #endif
153                         bpf_printk("passive(%i -> %i) map ctx update err: %d\n",
154                                    lport, bpf_ntohl(rport), err);
155                 }
156                 break;
157         case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
158                 lport = skops->local_port;
159                 rport = skops->remote_port;
160 
161                 if (bpf_ntohl(rport) == 10001) {
162                         ret = 10;
163 #ifdef SOCKMAP
164                         err = bpf_sock_map_update(skops, &sock_map, &ret,
165                                                   BPF_NOEXIST);
166 #else
167                         err = bpf_sock_hash_update(skops, &sock_map, &ret,
168                                                    BPF_NOEXIST);
169 #endif
170                         bpf_printk("active(%i -> %i) map ctx update err: %d\n",
171                                    lport, bpf_ntohl(rport), err);
172                 }
173                 break;
174         default:
175                 break;
176         }
177 
178         return 0;
179 }
180 
181 SEC("sk_msg1")
182 int bpf_prog4(struct sk_msg_md *msg)
183 {
184         int *bytes, zero = 0, one = 1, two = 2, three = 3;
185         int *start, *end, *start_push, *end_push;
186 
187         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
188         if (bytes)
189                 bpf_msg_apply_bytes(msg, *bytes);
190         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
191         if (bytes)
192                 bpf_msg_cork_bytes(msg, *bytes);
193         start = bpf_map_lookup_elem(&sock_bytes, &zero);
194         end = bpf_map_lookup_elem(&sock_bytes, &one);
195         if (start && end)
196                 bpf_msg_pull_data(msg, *start, *end, 0);
197         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
198         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
199         if (start_push && end_push)
200                 bpf_msg_push_data(msg, *start_push, *end_push, 0);
201         return SK_PASS;
202 }
203 
204 SEC("sk_msg2")
205 int bpf_prog5(struct sk_msg_md *msg)
206 {
207         int zero = 0, one = 1, two = 2, three = 3;
208         int *start, *end, *start_push, *end_push;
209         int *bytes, len1, len2 = 0, len3;
210         int err1 = -1, err2 = -1;
211 
212         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
213         if (bytes)
214                 err1 = bpf_msg_apply_bytes(msg, *bytes);
215         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
216         if (bytes)
217                 err2 = bpf_msg_cork_bytes(msg, *bytes);
218         len1 = (__u64)msg->data_end - (__u64)msg->data;
219         start = bpf_map_lookup_elem(&sock_bytes, &zero);
220         end = bpf_map_lookup_elem(&sock_bytes, &one);
221         if (start && end) {
222                 int err;
223 
224                 bpf_printk("sk_msg2: pull(%i:%i)\n",
225                            start ? *start : 0, end ? *end : 0);
226                 err = bpf_msg_pull_data(msg, *start, *end, 0);
227                 if (err)
228                         bpf_printk("sk_msg2: pull_data err %i\n",
229                                    err);
230                 len2 = (__u64)msg->data_end - (__u64)msg->data;
231                 bpf_printk("sk_msg2: length update %i->%i\n",
232                            len1, len2);
233         }
234 
235         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
236         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
237         if (start_push && end_push) {
238                 int err;
239 
240                 bpf_printk("sk_msg2: push(%i:%i)\n",
241                            start_push ? *start_push : 0,
242                            end_push ? *end_push : 0);
243                 err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
244                 if (err)
245                         bpf_printk("sk_msg2: push_data err %i\n", err);
246                 len3 = (__u64)msg->data_end - (__u64)msg->data;
247                 bpf_printk("sk_msg2: length push_update %i->%i\n",
248                            len2 ? len2 : len1, len3);
249         }
250 
251         bpf_printk("sk_msg2: data length %i err1 %i err2 %i\n",
252                    len1, err1, err2);
253         return SK_PASS;
254 }
255 
256 SEC("sk_msg3")
257 int bpf_prog6(struct sk_msg_md *msg)
258 {
259         int *bytes, *start, *end, *start_push, *end_push, *f;
260         int zero = 0, one = 1, two = 2, three = 3, key = 0;
261         __u64 flags = 0;
262 
263         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
264         if (bytes)
265                 bpf_msg_apply_bytes(msg, *bytes);
266         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
267         if (bytes)
268                 bpf_msg_cork_bytes(msg, *bytes);
269 
270         start = bpf_map_lookup_elem(&sock_bytes, &zero);
271         end = bpf_map_lookup_elem(&sock_bytes, &one);
272         if (start && end)
273                 bpf_msg_pull_data(msg, *start, *end, 0);
274 
275         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
276         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
277         if (start_push && end_push)
278                 bpf_msg_push_data(msg, *start_push, *end_push, 0);
279 
280         f = bpf_map_lookup_elem(&sock_redir_flags, &zero);
281         if (f && *f) {
282                 key = 2;
283                 flags = *f;
284         }
285 #ifdef SOCKMAP
286         return bpf_msg_redirect_map(msg, &sock_map_redir, key, flags);
287 #else
288         return bpf_msg_redirect_hash(msg, &sock_map_redir, &key, flags);
289 #endif
290 }
291 
292 SEC("sk_msg4")
293 int bpf_prog7(struct sk_msg_md *msg)
294 {
295         int zero = 0, one = 1, two = 2, three = 3, len1, len2 = 0, len3;
296         int *bytes, *start, *end, *start_push, *end_push, *f;
297         int err1 = 0, err2 = 0, key = 0;
298         __u64 flags = 0;
299 
300                 int err;
301         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
302         if (bytes)
303                 err1 = bpf_msg_apply_bytes(msg, *bytes);
304         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
305         if (bytes)
306                 err2 = bpf_msg_cork_bytes(msg, *bytes);
307         len1 = (__u64)msg->data_end - (__u64)msg->data;
308 
309         start = bpf_map_lookup_elem(&sock_bytes, &zero);
310         end = bpf_map_lookup_elem(&sock_bytes, &one);
311         if (start && end) {
312                 bpf_printk("sk_msg2: pull(%i:%i)\n",
313                            start ? *start : 0, end ? *end : 0);
314                 err = bpf_msg_pull_data(msg, *start, *end, 0);
315                 if (err)
316                         bpf_printk("sk_msg2: pull_data err %i\n",
317                                    err);
318                 len2 = (__u64)msg->data_end - (__u64)msg->data;
319                 bpf_printk("sk_msg2: length update %i->%i\n",
320                            len1, len2);
321         }
322 
323         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
324         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
325         if (start_push && end_push) {
326                 bpf_printk("sk_msg4: push(%i:%i)\n",
327                            start_push ? *start_push : 0,
328                            end_push ? *end_push : 0);
329                 err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
330                 if (err)
331                         bpf_printk("sk_msg4: push_data err %i\n",
332                                    err);
333                 len3 = (__u64)msg->data_end - (__u64)msg->data;
334                 bpf_printk("sk_msg4: length push_update %i->%i\n",
335                            len2 ? len2 : len1, len3);
336         }
337 
338         f = bpf_map_lookup_elem(&sock_redir_flags, &zero);
339         if (f && *f) {
340                 key = 2;
341                 flags = *f;
342         }
343         bpf_printk("sk_msg3: redirect(%iB) flags=%i err=%i\n",
344                    len1, flags, err1 ? err1 : err2);
345 #ifdef SOCKMAP
346         err = bpf_msg_redirect_map(msg, &sock_map_redir, key, flags);
347 #else
348         err = bpf_msg_redirect_hash(msg, &sock_map_redir, &key, flags);
349 #endif
350         bpf_printk("sk_msg3: err %i\n", err);
351         return err;
352 }
353 
354 SEC("sk_msg5")
355 int bpf_prog8(struct sk_msg_md *msg)
356 {
357         void *data_end = (void *)(long) msg->data_end;
358         void *data = (void *)(long) msg->data;
359         int ret = 0, *bytes, zero = 0;
360 
361         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
362         if (bytes) {
363                 ret = bpf_msg_apply_bytes(msg, *bytes);
364                 if (ret)
365                         return SK_DROP;
366         } else {
367                 return SK_DROP;
368         }
369         return SK_PASS;
370 }
371 SEC("sk_msg6")
372 int bpf_prog9(struct sk_msg_md *msg)
373 {
374         void *data_end = (void *)(long) msg->data_end;
375         void *data = (void *)(long) msg->data;
376         int ret = 0, *bytes, zero = 0;
377 
378         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
379         if (bytes) {
380                 if (((__u64)data_end - (__u64)data) >= *bytes)
381                         return SK_PASS;
382                 ret = bpf_msg_cork_bytes(msg, *bytes);
383                 if (ret)
384                         return SK_DROP;
385         }
386         return SK_PASS;
387 }
388 
389 SEC("sk_msg7")
390 int bpf_prog10(struct sk_msg_md *msg)
391 {
392         int *bytes, *start, *end, *start_push, *end_push;
393         int zero = 0, one = 1, two = 2, three = 3;
394 
395         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
396         if (bytes)
397                 bpf_msg_apply_bytes(msg, *bytes);
398         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
399         if (bytes)
400                 bpf_msg_cork_bytes(msg, *bytes);
401         start = bpf_map_lookup_elem(&sock_bytes, &zero);
402         end = bpf_map_lookup_elem(&sock_bytes, &one);
403         if (start && end)
404                 bpf_msg_pull_data(msg, *start, *end, 0);
405         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
406         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
407         if (start_push && end_push)
408                 bpf_msg_push_data(msg, *start_push, *end_push, 0);
409 
410         return SK_DROP;
411 }
412 
413 int _version SEC("version") = 1;
414 char _license[] SEC("license") = "GPL";
415 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp