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

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/test_tunnel_kern.c

Version: ~ [ linux-5.8-rc3 ] ~ [ linux-5.7.5 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.48 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.129 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.185 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.228 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.228 ] ~ [ 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.85 ] ~ [ 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-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) 2016 VMware
  3  * Copyright (c) 2016 Facebook
  4  *
  5  * This program is free software; you can redistribute it and/or
  6  * modify it under the terms of version 2 of the GNU General Public
  7  * License as published by the Free Software Foundation.
  8  */
  9 #include <stddef.h>
 10 #include <string.h>
 11 #include <arpa/inet.h>
 12 #include <linux/bpf.h>
 13 #include <linux/if_ether.h>
 14 #include <linux/if_packet.h>
 15 #include <linux/ip.h>
 16 #include <linux/ipv6.h>
 17 #include <linux/types.h>
 18 #include <linux/tcp.h>
 19 #include <linux/socket.h>
 20 #include <linux/pkt_cls.h>
 21 #include <linux/erspan.h>
 22 #include "bpf_helpers.h"
 23 #include "bpf_endian.h"
 24 
 25 #define ERROR(ret) do {\
 26                 char fmt[] = "ERROR line:%d ret:%d\n";\
 27                 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
 28         } while (0)
 29 
 30 int _version SEC("version") = 1;
 31 
 32 struct geneve_opt {
 33         __be16  opt_class;
 34         __u8    type;
 35         __u8    length:5;
 36         __u8    r3:1;
 37         __u8    r2:1;
 38         __u8    r1:1;
 39         __u8    opt_data[8]; /* hard-coded to 8 byte */
 40 };
 41 
 42 struct vxlan_metadata {
 43         __u32     gbp;
 44 };
 45 
 46 SEC("gre_set_tunnel")
 47 int _gre_set_tunnel(struct __sk_buff *skb)
 48 {
 49         int ret;
 50         struct bpf_tunnel_key key;
 51 
 52         __builtin_memset(&key, 0x0, sizeof(key));
 53         key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
 54         key.tunnel_id = 2;
 55         key.tunnel_tos = 0;
 56         key.tunnel_ttl = 64;
 57 
 58         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 59                                      BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
 60         if (ret < 0) {
 61                 ERROR(ret);
 62                 return TC_ACT_SHOT;
 63         }
 64 
 65         return TC_ACT_OK;
 66 }
 67 
 68 SEC("gre_get_tunnel")
 69 int _gre_get_tunnel(struct __sk_buff *skb)
 70 {
 71         int ret;
 72         struct bpf_tunnel_key key;
 73         char fmt[] = "key %d remote ip 0x%x\n";
 74 
 75         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
 76         if (ret < 0) {
 77                 ERROR(ret);
 78                 return TC_ACT_SHOT;
 79         }
 80 
 81         bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
 82         return TC_ACT_OK;
 83 }
 84 
 85 SEC("ip6gretap_set_tunnel")
 86 int _ip6gretap_set_tunnel(struct __sk_buff *skb)
 87 {
 88         struct bpf_tunnel_key key;
 89         int ret;
 90 
 91         __builtin_memset(&key, 0x0, sizeof(key));
 92         key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
 93         key.tunnel_id = 2;
 94         key.tunnel_tos = 0;
 95         key.tunnel_ttl = 64;
 96         key.tunnel_label = 0xabcde;
 97 
 98         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 99                                      BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
100                                      BPF_F_SEQ_NUMBER);
101         if (ret < 0) {
102                 ERROR(ret);
103                 return TC_ACT_SHOT;
104         }
105 
106         return TC_ACT_OK;
107 }
108 
109 SEC("ip6gretap_get_tunnel")
110 int _ip6gretap_get_tunnel(struct __sk_buff *skb)
111 {
112         char fmt[] = "key %d remote ip6 ::%x label %x\n";
113         struct bpf_tunnel_key key;
114         int ret;
115 
116         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
117                                      BPF_F_TUNINFO_IPV6);
118         if (ret < 0) {
119                 ERROR(ret);
120                 return TC_ACT_SHOT;
121         }
122 
123         bpf_trace_printk(fmt, sizeof(fmt),
124                          key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
125 
126         return TC_ACT_OK;
127 }
128 
129 SEC("erspan_set_tunnel")
130 int _erspan_set_tunnel(struct __sk_buff *skb)
131 {
132         struct bpf_tunnel_key key;
133         struct erspan_metadata md;
134         int ret;
135 
136         __builtin_memset(&key, 0x0, sizeof(key));
137         key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
138         key.tunnel_id = 2;
139         key.tunnel_tos = 0;
140         key.tunnel_ttl = 64;
141 
142         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
143                                      BPF_F_ZERO_CSUM_TX);
144         if (ret < 0) {
145                 ERROR(ret);
146                 return TC_ACT_SHOT;
147         }
148 
149         __builtin_memset(&md, 0, sizeof(md));
150 #ifdef ERSPAN_V1
151         md.version = 1;
152         md.u.index = bpf_htonl(123);
153 #else
154         __u8 direction = 1;
155         __u8 hwid = 7;
156 
157         md.version = 2;
158         md.u.md2.dir = direction;
159         md.u.md2.hwid = hwid & 0xf;
160         md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
161 #endif
162 
163         ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
164         if (ret < 0) {
165                 ERROR(ret);
166                 return TC_ACT_SHOT;
167         }
168 
169         return TC_ACT_OK;
170 }
171 
172 SEC("erspan_get_tunnel")
173 int _erspan_get_tunnel(struct __sk_buff *skb)
174 {
175         char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
176         struct bpf_tunnel_key key;
177         struct erspan_metadata md;
178         __u32 index;
179         int ret;
180 
181         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
182         if (ret < 0) {
183                 ERROR(ret);
184                 return TC_ACT_SHOT;
185         }
186 
187         ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
188         if (ret < 0) {
189                 ERROR(ret);
190                 return TC_ACT_SHOT;
191         }
192 
193         bpf_trace_printk(fmt, sizeof(fmt),
194                         key.tunnel_id, key.remote_ipv4, md.version);
195 
196 #ifdef ERSPAN_V1
197         char fmt2[] = "\tindex %x\n";
198 
199         index = bpf_ntohl(md.u.index);
200         bpf_trace_printk(fmt2, sizeof(fmt2), index);
201 #else
202         char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
203 
204         bpf_trace_printk(fmt2, sizeof(fmt2),
205                          md.u.md2.dir,
206                          (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
207                          bpf_ntohl(md.u.md2.timestamp));
208 #endif
209 
210         return TC_ACT_OK;
211 }
212 
213 SEC("ip4ip6erspan_set_tunnel")
214 int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
215 {
216         struct bpf_tunnel_key key;
217         struct erspan_metadata md;
218         int ret;
219 
220         __builtin_memset(&key, 0x0, sizeof(key));
221         key.remote_ipv6[3] = bpf_htonl(0x11);
222         key.tunnel_id = 2;
223         key.tunnel_tos = 0;
224         key.tunnel_ttl = 64;
225 
226         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
227                                      BPF_F_TUNINFO_IPV6);
228         if (ret < 0) {
229                 ERROR(ret);
230                 return TC_ACT_SHOT;
231         }
232 
233         __builtin_memset(&md, 0, sizeof(md));
234 
235 #ifdef ERSPAN_V1
236         md.u.index = bpf_htonl(123);
237         md.version = 1;
238 #else
239         __u8 direction = 0;
240         __u8 hwid = 17;
241 
242         md.version = 2;
243         md.u.md2.dir = direction;
244         md.u.md2.hwid = hwid & 0xf;
245         md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
246 #endif
247 
248         ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
249         if (ret < 0) {
250                 ERROR(ret);
251                 return TC_ACT_SHOT;
252         }
253 
254         return TC_ACT_OK;
255 }
256 
257 SEC("ip4ip6erspan_get_tunnel")
258 int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
259 {
260         char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
261         struct bpf_tunnel_key key;
262         struct erspan_metadata md;
263         __u32 index;
264         int ret;
265 
266         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
267                                      BPF_F_TUNINFO_IPV6);
268         if (ret < 0) {
269                 ERROR(ret);
270                 return TC_ACT_SHOT;
271         }
272 
273         ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
274         if (ret < 0) {
275                 ERROR(ret);
276                 return TC_ACT_SHOT;
277         }
278 
279         bpf_trace_printk(fmt, sizeof(fmt),
280                         key.tunnel_id, key.remote_ipv4, md.version);
281 
282 #ifdef ERSPAN_V1
283         char fmt2[] = "\tindex %x\n";
284 
285         index = bpf_ntohl(md.u.index);
286         bpf_trace_printk(fmt2, sizeof(fmt2), index);
287 #else
288         char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
289 
290         bpf_trace_printk(fmt2, sizeof(fmt2),
291                          md.u.md2.dir,
292                          (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
293                          bpf_ntohl(md.u.md2.timestamp));
294 #endif
295 
296         return TC_ACT_OK;
297 }
298 
299 SEC("vxlan_set_tunnel")
300 int _vxlan_set_tunnel(struct __sk_buff *skb)
301 {
302         int ret;
303         struct bpf_tunnel_key key;
304         struct vxlan_metadata md;
305 
306         __builtin_memset(&key, 0x0, sizeof(key));
307         key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
308         key.tunnel_id = 2;
309         key.tunnel_tos = 0;
310         key.tunnel_ttl = 64;
311 
312         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
313                                      BPF_F_ZERO_CSUM_TX);
314         if (ret < 0) {
315                 ERROR(ret);
316                 return TC_ACT_SHOT;
317         }
318 
319         md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
320         ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
321         if (ret < 0) {
322                 ERROR(ret);
323                 return TC_ACT_SHOT;
324         }
325 
326         return TC_ACT_OK;
327 }
328 
329 SEC("vxlan_get_tunnel")
330 int _vxlan_get_tunnel(struct __sk_buff *skb)
331 {
332         int ret;
333         struct bpf_tunnel_key key;
334         struct vxlan_metadata md;
335         char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
336 
337         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
338         if (ret < 0) {
339                 ERROR(ret);
340                 return TC_ACT_SHOT;
341         }
342 
343         ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
344         if (ret < 0) {
345                 ERROR(ret);
346                 return TC_ACT_SHOT;
347         }
348 
349         bpf_trace_printk(fmt, sizeof(fmt),
350                         key.tunnel_id, key.remote_ipv4, md.gbp);
351 
352         return TC_ACT_OK;
353 }
354 
355 SEC("ip6vxlan_set_tunnel")
356 int _ip6vxlan_set_tunnel(struct __sk_buff *skb)
357 {
358         struct bpf_tunnel_key key;
359         int ret;
360 
361         __builtin_memset(&key, 0x0, sizeof(key));
362         key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
363         key.tunnel_id = 22;
364         key.tunnel_tos = 0;
365         key.tunnel_ttl = 64;
366 
367         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
368                                      BPF_F_TUNINFO_IPV6);
369         if (ret < 0) {
370                 ERROR(ret);
371                 return TC_ACT_SHOT;
372         }
373 
374         return TC_ACT_OK;
375 }
376 
377 SEC("ip6vxlan_get_tunnel")
378 int _ip6vxlan_get_tunnel(struct __sk_buff *skb)
379 {
380         char fmt[] = "key %d remote ip6 ::%x label %x\n";
381         struct bpf_tunnel_key key;
382         int ret;
383 
384         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
385                                      BPF_F_TUNINFO_IPV6);
386         if (ret < 0) {
387                 ERROR(ret);
388                 return TC_ACT_SHOT;
389         }
390 
391         bpf_trace_printk(fmt, sizeof(fmt),
392                          key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
393 
394         return TC_ACT_OK;
395 }
396 
397 SEC("geneve_set_tunnel")
398 int _geneve_set_tunnel(struct __sk_buff *skb)
399 {
400         int ret, ret2;
401         struct bpf_tunnel_key key;
402         struct geneve_opt gopt;
403 
404         __builtin_memset(&key, 0x0, sizeof(key));
405         key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
406         key.tunnel_id = 2;
407         key.tunnel_tos = 0;
408         key.tunnel_ttl = 64;
409 
410         __builtin_memset(&gopt, 0x0, sizeof(gopt));
411         gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
412         gopt.type = 0x08;
413         gopt.r1 = 0;
414         gopt.r2 = 0;
415         gopt.r3 = 0;
416         gopt.length = 2; /* 4-byte multiple */
417         *(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef);
418 
419         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
420                                      BPF_F_ZERO_CSUM_TX);
421         if (ret < 0) {
422                 ERROR(ret);
423                 return TC_ACT_SHOT;
424         }
425 
426         ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
427         if (ret < 0) {
428                 ERROR(ret);
429                 return TC_ACT_SHOT;
430         }
431 
432         return TC_ACT_OK;
433 }
434 
435 SEC("geneve_get_tunnel")
436 int _geneve_get_tunnel(struct __sk_buff *skb)
437 {
438         int ret;
439         struct bpf_tunnel_key key;
440         struct geneve_opt gopt;
441         char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
442 
443         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
444         if (ret < 0) {
445                 ERROR(ret);
446                 return TC_ACT_SHOT;
447         }
448 
449         ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
450         if (ret < 0) {
451                 ERROR(ret);
452                 return TC_ACT_SHOT;
453         }
454 
455         bpf_trace_printk(fmt, sizeof(fmt),
456                         key.tunnel_id, key.remote_ipv4, gopt.opt_class);
457         return TC_ACT_OK;
458 }
459 
460 SEC("ip6geneve_set_tunnel")
461 int _ip6geneve_set_tunnel(struct __sk_buff *skb)
462 {
463         struct bpf_tunnel_key key;
464         struct geneve_opt gopt;
465         int ret;
466 
467         __builtin_memset(&key, 0x0, sizeof(key));
468         key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
469         key.tunnel_id = 22;
470         key.tunnel_tos = 0;
471         key.tunnel_ttl = 64;
472 
473         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
474                                      BPF_F_TUNINFO_IPV6);
475         if (ret < 0) {
476                 ERROR(ret);
477                 return TC_ACT_SHOT;
478         }
479 
480         __builtin_memset(&gopt, 0x0, sizeof(gopt));
481         gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
482         gopt.type = 0x08;
483         gopt.r1 = 0;
484         gopt.r2 = 0;
485         gopt.r3 = 0;
486         gopt.length = 2; /* 4-byte multiple */
487         *(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
488 
489         ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
490         if (ret < 0) {
491                 ERROR(ret);
492                 return TC_ACT_SHOT;
493         }
494 
495         return TC_ACT_OK;
496 }
497 
498 SEC("ip6geneve_get_tunnel")
499 int _ip6geneve_get_tunnel(struct __sk_buff *skb)
500 {
501         char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
502         struct bpf_tunnel_key key;
503         struct geneve_opt gopt;
504         int ret;
505 
506         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
507                                      BPF_F_TUNINFO_IPV6);
508         if (ret < 0) {
509                 ERROR(ret);
510                 return TC_ACT_SHOT;
511         }
512 
513         ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
514         if (ret < 0) {
515                 ERROR(ret);
516                 return TC_ACT_SHOT;
517         }
518 
519         bpf_trace_printk(fmt, sizeof(fmt),
520                         key.tunnel_id, key.remote_ipv4, gopt.opt_class);
521 
522         return TC_ACT_OK;
523 }
524 
525 SEC("ipip_set_tunnel")
526 int _ipip_set_tunnel(struct __sk_buff *skb)
527 {
528         struct bpf_tunnel_key key = {};
529         void *data = (void *)(long)skb->data;
530         struct iphdr *iph = data;
531         struct tcphdr *tcp = data + sizeof(*iph);
532         void *data_end = (void *)(long)skb->data_end;
533         int ret;
534 
535         /* single length check */
536         if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
537                 ERROR(1);
538                 return TC_ACT_SHOT;
539         }
540 
541         key.tunnel_ttl = 64;
542         if (iph->protocol == IPPROTO_ICMP) {
543                 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
544         } else {
545                 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
546                         return TC_ACT_SHOT;
547 
548                 if (tcp->dest == bpf_htons(5200))
549                         key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
550                 else if (tcp->dest == bpf_htons(5201))
551                         key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
552                 else
553                         return TC_ACT_SHOT;
554         }
555 
556         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
557         if (ret < 0) {
558                 ERROR(ret);
559                 return TC_ACT_SHOT;
560         }
561 
562         return TC_ACT_OK;
563 }
564 
565 SEC("ipip_get_tunnel")
566 int _ipip_get_tunnel(struct __sk_buff *skb)
567 {
568         int ret;
569         struct bpf_tunnel_key key;
570         char fmt[] = "remote ip 0x%x\n";
571 
572         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
573         if (ret < 0) {
574                 ERROR(ret);
575                 return TC_ACT_SHOT;
576         }
577 
578         bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
579         return TC_ACT_OK;
580 }
581 
582 SEC("ipip6_set_tunnel")
583 int _ipip6_set_tunnel(struct __sk_buff *skb)
584 {
585         struct bpf_tunnel_key key = {};
586         void *data = (void *)(long)skb->data;
587         struct iphdr *iph = data;
588         struct tcphdr *tcp = data + sizeof(*iph);
589         void *data_end = (void *)(long)skb->data_end;
590         int ret;
591 
592         /* single length check */
593         if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
594                 ERROR(1);
595                 return TC_ACT_SHOT;
596         }
597 
598         __builtin_memset(&key, 0x0, sizeof(key));
599         key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
600         key.tunnel_ttl = 64;
601 
602         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
603                                      BPF_F_TUNINFO_IPV6);
604         if (ret < 0) {
605                 ERROR(ret);
606                 return TC_ACT_SHOT;
607         }
608 
609         return TC_ACT_OK;
610 }
611 
612 SEC("ipip6_get_tunnel")
613 int _ipip6_get_tunnel(struct __sk_buff *skb)
614 {
615         int ret;
616         struct bpf_tunnel_key key;
617         char fmt[] = "remote ip6 %x::%x\n";
618 
619         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
620                                      BPF_F_TUNINFO_IPV6);
621         if (ret < 0) {
622                 ERROR(ret);
623                 return TC_ACT_SHOT;
624         }
625 
626         bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
627                          bpf_htonl(key.remote_ipv6[3]));
628         return TC_ACT_OK;
629 }
630 
631 SEC("ip6ip6_set_tunnel")
632 int _ip6ip6_set_tunnel(struct __sk_buff *skb)
633 {
634         struct bpf_tunnel_key key = {};
635         void *data = (void *)(long)skb->data;
636         struct ipv6hdr *iph = data;
637         struct tcphdr *tcp = data + sizeof(*iph);
638         void *data_end = (void *)(long)skb->data_end;
639         int ret;
640 
641         /* single length check */
642         if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
643                 ERROR(1);
644                 return TC_ACT_SHOT;
645         }
646 
647         key.remote_ipv6[0] = bpf_htonl(0x2401db00);
648         key.tunnel_ttl = 64;
649 
650         if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
651                 key.remote_ipv6[3] = bpf_htonl(1);
652         } else {
653                 if (iph->nexthdr != 6 /* NEXTHDR_TCP */) {
654                         ERROR(iph->nexthdr);
655                         return TC_ACT_SHOT;
656                 }
657 
658                 if (tcp->dest == bpf_htons(5200)) {
659                         key.remote_ipv6[3] = bpf_htonl(1);
660                 } else if (tcp->dest == bpf_htons(5201)) {
661                         key.remote_ipv6[3] = bpf_htonl(2);
662                 } else {
663                         ERROR(tcp->dest);
664                         return TC_ACT_SHOT;
665                 }
666         }
667 
668         ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
669                                      BPF_F_TUNINFO_IPV6);
670         if (ret < 0) {
671                 ERROR(ret);
672                 return TC_ACT_SHOT;
673         }
674 
675         return TC_ACT_OK;
676 }
677 
678 SEC("ip6ip6_get_tunnel")
679 int _ip6ip6_get_tunnel(struct __sk_buff *skb)
680 {
681         int ret;
682         struct bpf_tunnel_key key;
683         char fmt[] = "remote ip6 %x::%x\n";
684 
685         ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
686                                      BPF_F_TUNINFO_IPV6);
687         if (ret < 0) {
688                 ERROR(ret);
689                 return TC_ACT_SHOT;
690         }
691 
692         bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
693                          bpf_htonl(key.remote_ipv6[3]));
694         return TC_ACT_OK;
695 }
696 
697 SEC("xfrm_get_state")
698 int _xfrm_get_state(struct __sk_buff *skb)
699 {
700         struct bpf_xfrm_state x;
701         char fmt[] = "reqid %d spi 0x%x remote ip 0x%x\n";
702         int ret;
703 
704         ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
705         if (ret < 0)
706                 return TC_ACT_OK;
707 
708         bpf_trace_printk(fmt, sizeof(fmt), x.reqid, bpf_ntohl(x.spi),
709                          bpf_ntohl(x.remote_ipv4));
710         return TC_ACT_OK;
711 }
712 
713 char _license[] SEC("license") = "GPL";
714 

~ [ 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