1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2016 VMware
3 * Copyright (c) 2016 Facebook
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.
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/if_tunnel.h>
17 #include <linux/ipv6.h>
18 #include <linux/icmp.h>
19 #include <linux/types.h>
20 #include <linux/socket.h>
21 #include <linux/pkt_cls.h>
22 #include <linux/erspan.h>
23 #include <linux/udp.h>
24 #include <bpf/bpf_helpers.h>
25 #include <bpf/bpf_endian.h>
27 #define log_err(__ret) bpf_printk("ERROR line:%d ret:%d\n", __LINE__, __ret)
29 #define VXLAN_UDP_PORT 4789
31 /* Only IPv4 address assigned to veth1.
34 #define ASSIGNED_ADDR_VETH1 0xac1001c8
43 __u8 opt_data[8]; /* hard-coded to 8 byte */
49 } __attribute__((packed));
51 struct vxlan_metadata {
55 struct bpf_fou_encap {
60 enum bpf_fou_encap_type {
65 int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
66 struct bpf_fou_encap *encap, int type) __ksym;
67 int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
68 struct bpf_fou_encap *encap) __ksym;
71 __uint(type, BPF_MAP_TYPE_ARRAY);
72 __uint(max_entries, 1);
75 } local_ip_map SEC(".maps");
78 int gre_set_tunnel(struct __sk_buff *skb)
81 struct bpf_tunnel_key key;
83 __builtin_memset(&key, 0x0, sizeof(key));
84 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
89 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
90 BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
100 int gre_set_tunnel_no_key(struct __sk_buff *skb)
103 struct bpf_tunnel_key key;
105 __builtin_memset(&key, 0x0, sizeof(key));
106 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
109 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
110 BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER |
111 BPF_F_NO_TUNNEL_KEY);
121 int gre_get_tunnel(struct __sk_buff *skb)
124 struct bpf_tunnel_key key;
126 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
132 bpf_printk("key %d remote ip 0x%x\n", key.tunnel_id, key.remote_ipv4);
137 int ip6gretap_set_tunnel(struct __sk_buff *skb)
139 struct bpf_tunnel_key key;
142 __builtin_memset(&key, 0x0, sizeof(key));
143 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
147 key.tunnel_label = 0xabcde;
149 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
150 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
161 int ip6gretap_get_tunnel(struct __sk_buff *skb)
163 struct bpf_tunnel_key key;
166 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
173 bpf_printk("key %d remote ip6 ::%x label %x\n",
174 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
180 int erspan_set_tunnel(struct __sk_buff *skb)
182 struct bpf_tunnel_key key;
183 struct erspan_metadata md;
186 __builtin_memset(&key, 0x0, sizeof(key));
187 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
192 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
199 __builtin_memset(&md, 0, sizeof(md));
202 md.u.index = bpf_htonl(123);
208 md.u.md2.dir = direction;
209 md.u.md2.hwid = hwid & 0xf;
210 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
213 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
223 int erspan_get_tunnel(struct __sk_buff *skb)
225 struct bpf_tunnel_key key;
226 struct erspan_metadata md;
229 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
235 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
241 bpf_printk("key %d remote ip 0x%x erspan version %d\n",
242 key.tunnel_id, key.remote_ipv4, md.version);
245 index = bpf_ntohl(md.u.index);
246 bpf_printk("\tindex %x\n", index);
248 bpf_printk("\tdirection %d hwid %x timestamp %u\n",
250 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
251 bpf_ntohl(md.u.md2.timestamp));
258 int ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
260 struct bpf_tunnel_key key;
261 struct erspan_metadata md;
264 __builtin_memset(&key, 0x0, sizeof(key));
265 key.remote_ipv6[3] = bpf_htonl(0x11);
270 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
277 __builtin_memset(&md, 0, sizeof(md));
280 md.u.index = bpf_htonl(123);
287 md.u.md2.dir = direction;
288 md.u.md2.hwid = hwid & 0xf;
289 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
292 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
302 int ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
304 struct bpf_tunnel_key key;
305 struct erspan_metadata md;
308 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
315 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
321 bpf_printk("ip6erspan get key %d remote ip6 ::%x erspan version %d\n",
322 key.tunnel_id, key.remote_ipv4, md.version);
325 index = bpf_ntohl(md.u.index);
326 bpf_printk("\tindex %x\n", index);
328 bpf_printk("\tdirection %d hwid %x timestamp %u\n",
330 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
331 bpf_ntohl(md.u.md2.timestamp));
338 int vxlan_set_tunnel_dst(struct __sk_buff *skb)
340 struct bpf_tunnel_key key;
341 struct vxlan_metadata md;
343 __u32 *local_ip = NULL;
346 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
352 __builtin_memset(&key, 0x0, sizeof(key));
353 key.local_ipv4 = 0xac100164; /* 172.16.1.100 */
354 key.remote_ipv4 = *local_ip;
359 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
366 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
367 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
377 int vxlan_set_tunnel_src(struct __sk_buff *skb)
379 struct bpf_tunnel_key key;
380 struct vxlan_metadata md;
382 __u32 *local_ip = NULL;
385 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
391 __builtin_memset(&key, 0x0, sizeof(key));
392 key.local_ipv4 = *local_ip;
393 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
398 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
405 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
406 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
416 int vxlan_get_tunnel_src(struct __sk_buff *skb)
419 struct bpf_tunnel_key key;
420 struct vxlan_metadata md;
422 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
423 BPF_F_TUNINFO_FLAGS);
429 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
435 if (key.local_ipv4 != ASSIGNED_ADDR_VETH1 || md.gbp != 0x800FF ||
436 !(key.tunnel_flags & TUNNEL_KEY) ||
437 (key.tunnel_flags & TUNNEL_CSUM)) {
438 bpf_printk("vxlan key %d local ip 0x%x remote ip 0x%x gbp 0x%x flags 0x%x\n",
439 key.tunnel_id, key.local_ipv4,
440 key.remote_ipv4, md.gbp,
441 bpf_ntohs(key.tunnel_flags));
450 int veth_set_outer_dst(struct __sk_buff *skb)
452 struct ethhdr *eth = (struct ethhdr *)(long)skb->data;
453 __u32 assigned_ip = bpf_htonl(ASSIGNED_ADDR_VETH1);
454 void *data_end = (void *)(long)skb->data_end;
460 if ((void *)eth + sizeof(*eth) > data_end) {
465 if (eth->h_proto != bpf_htons(ETH_P_IP))
468 iph = (struct iphdr *)(eth + 1);
469 if ((void *)iph + sizeof(*iph) > data_end) {
473 if (iph->protocol != IPPROTO_UDP)
476 udph = (struct udphdr *)(iph + 1);
477 if ((void *)udph + sizeof(*udph) > data_end) {
481 if (udph->dest != bpf_htons(VXLAN_UDP_PORT))
484 if (iph->daddr != assigned_ip) {
485 csum = bpf_csum_diff(&iph->daddr, sizeof(__u32), &assigned_ip,
487 if (bpf_skb_store_bytes(skb, ETH_HLEN + offsetof(struct iphdr, daddr),
488 &assigned_ip, sizeof(__u32), 0) < 0) {
492 if (bpf_l3_csum_replace(skb, ETH_HLEN + offsetof(struct iphdr, check),
497 bpf_skb_change_type(skb, PACKET_HOST);
503 int ip6vxlan_set_tunnel_dst(struct __sk_buff *skb)
505 struct bpf_tunnel_key key;
510 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
516 __builtin_memset(&key, 0x0, sizeof(key));
517 key.local_ipv6[3] = bpf_htonl(0x11); /* ::11 */
518 key.remote_ipv6[3] = bpf_htonl(*local_ip);
523 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
534 int ip6vxlan_set_tunnel_src(struct __sk_buff *skb)
536 struct bpf_tunnel_key key;
541 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
547 __builtin_memset(&key, 0x0, sizeof(key));
548 key.local_ipv6[3] = bpf_htonl(*local_ip);
549 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
554 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
565 int ip6vxlan_get_tunnel_src(struct __sk_buff *skb)
567 struct bpf_tunnel_key key;
572 local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
578 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
579 BPF_F_TUNINFO_IPV6 | BPF_F_TUNINFO_FLAGS);
585 if (bpf_ntohl(key.local_ipv6[3]) != *local_ip ||
586 !(key.tunnel_flags & TUNNEL_KEY) ||
587 !(key.tunnel_flags & TUNNEL_CSUM)) {
588 bpf_printk("ip6vxlan key %d local ip6 ::%x remote ip6 ::%x label 0x%x flags 0x%x\n",
589 key.tunnel_id, bpf_ntohl(key.local_ipv6[3]),
590 bpf_ntohl(key.remote_ipv6[3]), key.tunnel_label,
591 bpf_ntohs(key.tunnel_flags));
592 bpf_printk("local_ip 0x%x\n", *local_ip);
601 int geneve_set_tunnel(struct __sk_buff *skb)
604 struct bpf_tunnel_key key;
605 struct geneve_opt gopt;
607 __builtin_memset(&key, 0x0, sizeof(key));
608 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
613 __builtin_memset(&gopt, 0x0, sizeof(gopt));
614 gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
619 gopt.length = 2; /* 4-byte multiple */
620 *(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef);
622 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
629 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
639 int geneve_get_tunnel(struct __sk_buff *skb)
642 struct bpf_tunnel_key key;
643 struct geneve_opt gopt;
645 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
651 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
655 bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
656 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
661 int ip6geneve_set_tunnel(struct __sk_buff *skb)
663 struct bpf_tunnel_key key;
664 struct geneve_opt gopt;
667 __builtin_memset(&key, 0x0, sizeof(key));
668 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
673 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
680 __builtin_memset(&gopt, 0x0, sizeof(gopt));
681 gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
686 gopt.length = 2; /* 4-byte multiple */
687 *(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
689 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
699 int ip6geneve_get_tunnel(struct __sk_buff *skb)
701 struct bpf_tunnel_key key;
702 struct geneve_opt gopt;
705 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
712 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
716 bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
717 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
723 int ipip_set_tunnel(struct __sk_buff *skb)
725 struct bpf_tunnel_key key = {};
726 void *data = (void *)(long)skb->data;
727 struct iphdr *iph = data;
728 void *data_end = (void *)(long)skb->data_end;
731 /* single length check */
732 if (data + sizeof(*iph) > data_end) {
738 if (iph->protocol == IPPROTO_ICMP) {
739 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
742 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
752 int ipip_get_tunnel(struct __sk_buff *skb)
755 struct bpf_tunnel_key key;
757 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
763 bpf_printk("remote ip 0x%x\n", key.remote_ipv4);
768 int ipip_gue_set_tunnel(struct __sk_buff *skb)
770 struct bpf_tunnel_key key = {};
771 struct bpf_fou_encap encap = {};
772 void *data = (void *)(long)skb->data;
773 struct iphdr *iph = data;
774 void *data_end = (void *)(long)skb->data_end;
777 if (data + sizeof(*iph) > data_end) {
783 if (iph->protocol == IPPROTO_ICMP)
784 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
786 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
793 encap.dport = bpf_htons(5555);
795 ret = bpf_skb_set_fou_encap(skb, &encap, FOU_BPF_ENCAP_GUE);
805 int ipip_fou_set_tunnel(struct __sk_buff *skb)
807 struct bpf_tunnel_key key = {};
808 struct bpf_fou_encap encap = {};
809 void *data = (void *)(long)skb->data;
810 struct iphdr *iph = data;
811 void *data_end = (void *)(long)skb->data_end;
814 if (data + sizeof(*iph) > data_end) {
820 if (iph->protocol == IPPROTO_ICMP)
821 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
823 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
830 encap.dport = bpf_htons(5555);
832 ret = bpf_skb_set_fou_encap(skb, &encap, FOU_BPF_ENCAP_FOU);
842 int ipip_encap_get_tunnel(struct __sk_buff *skb)
845 struct bpf_tunnel_key key = {};
846 struct bpf_fou_encap encap = {};
848 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
854 ret = bpf_skb_get_fou_encap(skb, &encap);
860 if (bpf_ntohs(encap.dport) != 5555)
863 bpf_printk("%d remote ip 0x%x, sport %d, dport %d\n", ret,
864 key.remote_ipv4, bpf_ntohs(encap.sport),
865 bpf_ntohs(encap.dport));
870 int ipip6_set_tunnel(struct __sk_buff *skb)
872 struct bpf_tunnel_key key = {};
873 void *data = (void *)(long)skb->data;
874 struct iphdr *iph = data;
875 void *data_end = (void *)(long)skb->data_end;
878 /* single length check */
879 if (data + sizeof(*iph) > data_end) {
884 __builtin_memset(&key, 0x0, sizeof(key));
886 if (iph->protocol == IPPROTO_ICMP) {
887 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
890 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
901 int ipip6_get_tunnel(struct __sk_buff *skb)
904 struct bpf_tunnel_key key;
906 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
913 bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
914 bpf_htonl(key.remote_ipv6[3]));
919 int ip6ip6_set_tunnel(struct __sk_buff *skb)
921 struct bpf_tunnel_key key = {};
922 void *data = (void *)(long)skb->data;
923 struct ipv6hdr *iph = data;
924 void *data_end = (void *)(long)skb->data_end;
927 /* single length check */
928 if (data + sizeof(*iph) > data_end) {
934 if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
935 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
938 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
949 int ip6ip6_get_tunnel(struct __sk_buff *skb)
952 struct bpf_tunnel_key key;
954 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
961 bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
962 bpf_htonl(key.remote_ipv6[3]));
967 int xfrm_get_state(struct __sk_buff *skb)
969 struct bpf_xfrm_state x;
972 ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
976 bpf_printk("reqid %d spi 0x%x remote ip 0x%x\n",
977 x.reqid, bpf_ntohl(x.spi),
978 bpf_ntohl(x.remote_ipv4));
982 char _license[] SEC("license") = "GPL";