Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2016 VMware
0003  * Copyright (c) 2016 Facebook
0004  *
0005  * This program is free software; you can redistribute it and/or
0006  * modify it under the terms of version 2 of the GNU General Public
0007  * License as published by the Free Software Foundation.
0008  */
0009 #include <stddef.h>
0010 #include <string.h>
0011 #include <arpa/inet.h>
0012 #include <linux/bpf.h>
0013 #include <linux/if_ether.h>
0014 #include <linux/if_packet.h>
0015 #include <linux/ip.h>
0016 #include <linux/ipv6.h>
0017 #include <linux/icmp.h>
0018 #include <linux/types.h>
0019 #include <linux/socket.h>
0020 #include <linux/pkt_cls.h>
0021 #include <linux/erspan.h>
0022 #include <linux/udp.h>
0023 #include <bpf/bpf_helpers.h>
0024 #include <bpf/bpf_endian.h>
0025 
0026 #define log_err(__ret) bpf_printk("ERROR line:%d ret:%d\n", __LINE__, __ret)
0027 
0028 #define VXLAN_UDP_PORT 4789
0029 
0030 /* Only IPv4 address assigned to veth1.
0031  * 172.16.1.200
0032  */
0033 #define ASSIGNED_ADDR_VETH1 0xac1001c8
0034 
0035 struct geneve_opt {
0036     __be16  opt_class;
0037     __u8    type;
0038     __u8    length:5;
0039     __u8    r3:1;
0040     __u8    r2:1;
0041     __u8    r1:1;
0042     __u8    opt_data[8]; /* hard-coded to 8 byte */
0043 };
0044 
0045 struct vxlanhdr {
0046     __be32 vx_flags;
0047     __be32 vx_vni;
0048 } __attribute__((packed));
0049 
0050 struct vxlan_metadata {
0051     __u32     gbp;
0052 };
0053 
0054 struct {
0055     __uint(type, BPF_MAP_TYPE_ARRAY);
0056     __uint(max_entries, 1);
0057     __type(key, __u32);
0058     __type(value, __u32);
0059 } local_ip_map SEC(".maps");
0060 
0061 SEC("tc")
0062 int gre_set_tunnel(struct __sk_buff *skb)
0063 {
0064     int ret;
0065     struct bpf_tunnel_key key;
0066 
0067     __builtin_memset(&key, 0x0, sizeof(key));
0068     key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
0069     key.tunnel_id = 2;
0070     key.tunnel_tos = 0;
0071     key.tunnel_ttl = 64;
0072 
0073     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0074                      BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
0075     if (ret < 0) {
0076         log_err(ret);
0077         return TC_ACT_SHOT;
0078     }
0079 
0080     return TC_ACT_OK;
0081 }
0082 
0083 SEC("tc")
0084 int gre_get_tunnel(struct __sk_buff *skb)
0085 {
0086     int ret;
0087     struct bpf_tunnel_key key;
0088 
0089     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
0090     if (ret < 0) {
0091         log_err(ret);
0092         return TC_ACT_SHOT;
0093     }
0094 
0095     bpf_printk("key %d remote ip 0x%x\n", key.tunnel_id, key.remote_ipv4);
0096     return TC_ACT_OK;
0097 }
0098 
0099 SEC("tc")
0100 int ip6gretap_set_tunnel(struct __sk_buff *skb)
0101 {
0102     struct bpf_tunnel_key key;
0103     int ret;
0104 
0105     __builtin_memset(&key, 0x0, sizeof(key));
0106     key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
0107     key.tunnel_id = 2;
0108     key.tunnel_tos = 0;
0109     key.tunnel_ttl = 64;
0110     key.tunnel_label = 0xabcde;
0111 
0112     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0113                      BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
0114                      BPF_F_SEQ_NUMBER);
0115     if (ret < 0) {
0116         log_err(ret);
0117         return TC_ACT_SHOT;
0118     }
0119 
0120     return TC_ACT_OK;
0121 }
0122 
0123 SEC("tc")
0124 int ip6gretap_get_tunnel(struct __sk_buff *skb)
0125 {
0126     struct bpf_tunnel_key key;
0127     int ret;
0128 
0129     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
0130                      BPF_F_TUNINFO_IPV6);
0131     if (ret < 0) {
0132         log_err(ret);
0133         return TC_ACT_SHOT;
0134     }
0135 
0136     bpf_printk("key %d remote ip6 ::%x label %x\n",
0137            key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
0138 
0139     return TC_ACT_OK;
0140 }
0141 
0142 SEC("tc")
0143 int erspan_set_tunnel(struct __sk_buff *skb)
0144 {
0145     struct bpf_tunnel_key key;
0146     struct erspan_metadata md;
0147     int ret;
0148 
0149     __builtin_memset(&key, 0x0, sizeof(key));
0150     key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
0151     key.tunnel_id = 2;
0152     key.tunnel_tos = 0;
0153     key.tunnel_ttl = 64;
0154 
0155     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0156                      BPF_F_ZERO_CSUM_TX);
0157     if (ret < 0) {
0158         log_err(ret);
0159         return TC_ACT_SHOT;
0160     }
0161 
0162     __builtin_memset(&md, 0, sizeof(md));
0163 #ifdef ERSPAN_V1
0164     md.version = 1;
0165     md.u.index = bpf_htonl(123);
0166 #else
0167     __u8 direction = 1;
0168     __u8 hwid = 7;
0169 
0170     md.version = 2;
0171     md.u.md2.dir = direction;
0172     md.u.md2.hwid = hwid & 0xf;
0173     md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
0174 #endif
0175 
0176     ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
0177     if (ret < 0) {
0178         log_err(ret);
0179         return TC_ACT_SHOT;
0180     }
0181 
0182     return TC_ACT_OK;
0183 }
0184 
0185 SEC("tc")
0186 int erspan_get_tunnel(struct __sk_buff *skb)
0187 {
0188     struct bpf_tunnel_key key;
0189     struct erspan_metadata md;
0190     __u32 index;
0191     int ret;
0192 
0193     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
0194     if (ret < 0) {
0195         log_err(ret);
0196         return TC_ACT_SHOT;
0197     }
0198 
0199     ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
0200     if (ret < 0) {
0201         log_err(ret);
0202         return TC_ACT_SHOT;
0203     }
0204 
0205     bpf_printk("key %d remote ip 0x%x erspan version %d\n",
0206            key.tunnel_id, key.remote_ipv4, md.version);
0207 
0208 #ifdef ERSPAN_V1
0209     index = bpf_ntohl(md.u.index);
0210     bpf_printk("\tindex %x\n", index);
0211 #else
0212     bpf_printk("\tdirection %d hwid %x timestamp %u\n",
0213            md.u.md2.dir,
0214            (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
0215            bpf_ntohl(md.u.md2.timestamp));
0216 #endif
0217 
0218     return TC_ACT_OK;
0219 }
0220 
0221 SEC("tc")
0222 int ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
0223 {
0224     struct bpf_tunnel_key key;
0225     struct erspan_metadata md;
0226     int ret;
0227 
0228     __builtin_memset(&key, 0x0, sizeof(key));
0229     key.remote_ipv6[3] = bpf_htonl(0x11);
0230     key.tunnel_id = 2;
0231     key.tunnel_tos = 0;
0232     key.tunnel_ttl = 64;
0233 
0234     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0235                      BPF_F_TUNINFO_IPV6);
0236     if (ret < 0) {
0237         log_err(ret);
0238         return TC_ACT_SHOT;
0239     }
0240 
0241     __builtin_memset(&md, 0, sizeof(md));
0242 
0243 #ifdef ERSPAN_V1
0244     md.u.index = bpf_htonl(123);
0245     md.version = 1;
0246 #else
0247     __u8 direction = 0;
0248     __u8 hwid = 17;
0249 
0250     md.version = 2;
0251     md.u.md2.dir = direction;
0252     md.u.md2.hwid = hwid & 0xf;
0253     md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
0254 #endif
0255 
0256     ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
0257     if (ret < 0) {
0258         log_err(ret);
0259         return TC_ACT_SHOT;
0260     }
0261 
0262     return TC_ACT_OK;
0263 }
0264 
0265 SEC("tc")
0266 int ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
0267 {
0268     struct bpf_tunnel_key key;
0269     struct erspan_metadata md;
0270     __u32 index;
0271     int ret;
0272 
0273     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
0274                      BPF_F_TUNINFO_IPV6);
0275     if (ret < 0) {
0276         log_err(ret);
0277         return TC_ACT_SHOT;
0278     }
0279 
0280     ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
0281     if (ret < 0) {
0282         log_err(ret);
0283         return TC_ACT_SHOT;
0284     }
0285 
0286     bpf_printk("ip6erspan get key %d remote ip6 ::%x erspan version %d\n",
0287            key.tunnel_id, key.remote_ipv4, md.version);
0288 
0289 #ifdef ERSPAN_V1
0290     index = bpf_ntohl(md.u.index);
0291     bpf_printk("\tindex %x\n", index);
0292 #else
0293     bpf_printk("\tdirection %d hwid %x timestamp %u\n",
0294            md.u.md2.dir,
0295            (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
0296            bpf_ntohl(md.u.md2.timestamp));
0297 #endif
0298 
0299     return TC_ACT_OK;
0300 }
0301 
0302 SEC("tc")
0303 int vxlan_set_tunnel_dst(struct __sk_buff *skb)
0304 {
0305     int ret;
0306     struct bpf_tunnel_key key;
0307     struct vxlan_metadata md;
0308     __u32 index = 0;
0309     __u32 *local_ip = NULL;
0310 
0311     local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
0312     if (!local_ip) {
0313         log_err(ret);
0314         return TC_ACT_SHOT;
0315     }
0316 
0317     __builtin_memset(&key, 0x0, sizeof(key));
0318     key.local_ipv4 = 0xac100164; /* 172.16.1.100 */
0319     key.remote_ipv4 = *local_ip;
0320     key.tunnel_id = 2;
0321     key.tunnel_tos = 0;
0322     key.tunnel_ttl = 64;
0323 
0324     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0325                      BPF_F_ZERO_CSUM_TX);
0326     if (ret < 0) {
0327         log_err(ret);
0328         return TC_ACT_SHOT;
0329     }
0330 
0331     md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
0332     ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
0333     if (ret < 0) {
0334         log_err(ret);
0335         return TC_ACT_SHOT;
0336     }
0337 
0338     return TC_ACT_OK;
0339 }
0340 
0341 SEC("tc")
0342 int vxlan_set_tunnel_src(struct __sk_buff *skb)
0343 {
0344     int ret;
0345     struct bpf_tunnel_key key;
0346     struct vxlan_metadata md;
0347     __u32 index = 0;
0348     __u32 *local_ip = NULL;
0349 
0350     local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
0351     if (!local_ip) {
0352         log_err(ret);
0353         return TC_ACT_SHOT;
0354     }
0355 
0356     __builtin_memset(&key, 0x0, sizeof(key));
0357     key.local_ipv4 = *local_ip;
0358     key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
0359     key.tunnel_id = 2;
0360     key.tunnel_tos = 0;
0361     key.tunnel_ttl = 64;
0362 
0363     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0364                      BPF_F_ZERO_CSUM_TX);
0365     if (ret < 0) {
0366         log_err(ret);
0367         return TC_ACT_SHOT;
0368     }
0369 
0370     md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
0371     ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
0372     if (ret < 0) {
0373         log_err(ret);
0374         return TC_ACT_SHOT;
0375     }
0376 
0377     return TC_ACT_OK;
0378 }
0379 
0380 SEC("tc")
0381 int vxlan_get_tunnel_src(struct __sk_buff *skb)
0382 {
0383     int ret;
0384     struct bpf_tunnel_key key;
0385     struct vxlan_metadata md;
0386     __u32 orig_daddr;
0387     __u32 index = 0;
0388 
0389     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
0390     if (ret < 0) {
0391         log_err(ret);
0392         return TC_ACT_SHOT;
0393     }
0394 
0395     ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
0396     if (ret < 0) {
0397         log_err(ret);
0398         return TC_ACT_SHOT;
0399     }
0400 
0401     if (key.local_ipv4 != ASSIGNED_ADDR_VETH1 || md.gbp != 0x800FF) {
0402         bpf_printk("vxlan key %d local ip 0x%x remote ip 0x%x gbp 0x%x\n",
0403                key.tunnel_id, key.local_ipv4,
0404                key.remote_ipv4, md.gbp);
0405         log_err(ret);
0406         return TC_ACT_SHOT;
0407     }
0408 
0409     return TC_ACT_OK;
0410 }
0411 
0412 SEC("tc")
0413 int veth_set_outer_dst(struct __sk_buff *skb)
0414 {
0415     struct ethhdr *eth = (struct ethhdr *)(long)skb->data;
0416     __u32 assigned_ip = bpf_htonl(ASSIGNED_ADDR_VETH1);
0417     void *data_end = (void *)(long)skb->data_end;
0418     struct udphdr *udph;
0419     struct iphdr *iph;
0420     __u32 index = 0;
0421     int ret = 0;
0422     int shrink;
0423     __s64 csum;
0424 
0425     if ((void *)eth + sizeof(*eth) > data_end) {
0426         log_err(ret);
0427         return TC_ACT_SHOT;
0428     }
0429 
0430     if (eth->h_proto != bpf_htons(ETH_P_IP))
0431         return TC_ACT_OK;
0432 
0433     iph = (struct iphdr *)(eth + 1);
0434     if ((void *)iph + sizeof(*iph) > data_end) {
0435         log_err(ret);
0436         return TC_ACT_SHOT;
0437     }
0438     if (iph->protocol != IPPROTO_UDP)
0439         return TC_ACT_OK;
0440 
0441     udph = (struct udphdr *)(iph + 1);
0442     if ((void *)udph + sizeof(*udph) > data_end) {
0443         log_err(ret);
0444         return TC_ACT_SHOT;
0445     }
0446     if (udph->dest != bpf_htons(VXLAN_UDP_PORT))
0447         return TC_ACT_OK;
0448 
0449     if (iph->daddr != assigned_ip) {
0450         csum = bpf_csum_diff(&iph->daddr, sizeof(__u32), &assigned_ip,
0451                      sizeof(__u32), 0);
0452         if (bpf_skb_store_bytes(skb, ETH_HLEN + offsetof(struct iphdr, daddr),
0453                     &assigned_ip, sizeof(__u32), 0) < 0) {
0454             log_err(ret);
0455             return TC_ACT_SHOT;
0456         }
0457         if (bpf_l3_csum_replace(skb, ETH_HLEN + offsetof(struct iphdr, check),
0458                     0, csum, 0) < 0) {
0459             log_err(ret);
0460             return TC_ACT_SHOT;
0461         }
0462         bpf_skb_change_type(skb, PACKET_HOST);
0463     }
0464     return TC_ACT_OK;
0465 }
0466 
0467 SEC("tc")
0468 int ip6vxlan_set_tunnel_dst(struct __sk_buff *skb)
0469 {
0470     struct bpf_tunnel_key key;
0471     int ret;
0472     __u32 index = 0;
0473     __u32 *local_ip;
0474 
0475     local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
0476     if (!local_ip) {
0477         log_err(ret);
0478         return TC_ACT_SHOT;
0479     }
0480 
0481     __builtin_memset(&key, 0x0, sizeof(key));
0482     key.local_ipv6[3] = bpf_htonl(0x11); /* ::11 */
0483     key.remote_ipv6[3] = bpf_htonl(*local_ip);
0484     key.tunnel_id = 22;
0485     key.tunnel_tos = 0;
0486     key.tunnel_ttl = 64;
0487 
0488     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0489                      BPF_F_TUNINFO_IPV6);
0490     if (ret < 0) {
0491         log_err(ret);
0492         return TC_ACT_SHOT;
0493     }
0494 
0495     return TC_ACT_OK;
0496 }
0497 
0498 SEC("tc")
0499 int ip6vxlan_set_tunnel_src(struct __sk_buff *skb)
0500 {
0501     struct bpf_tunnel_key key;
0502     int ret;
0503     __u32 index = 0;
0504     __u32 *local_ip;
0505 
0506     local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
0507     if (!local_ip) {
0508         log_err(ret);
0509         return TC_ACT_SHOT;
0510     }
0511 
0512     __builtin_memset(&key, 0x0, sizeof(key));
0513     key.local_ipv6[3] = bpf_htonl(*local_ip);
0514     key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
0515     key.tunnel_id = 22;
0516     key.tunnel_tos = 0;
0517     key.tunnel_ttl = 64;
0518 
0519     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0520                      BPF_F_TUNINFO_IPV6);
0521     if (ret < 0) {
0522         log_err(ret);
0523         return TC_ACT_SHOT;
0524     }
0525 
0526     return TC_ACT_OK;
0527 }
0528 
0529 SEC("tc")
0530 int ip6vxlan_get_tunnel_src(struct __sk_buff *skb)
0531 {
0532     struct bpf_tunnel_key key;
0533     int ret;
0534     __u32 index = 0;
0535     __u32 *local_ip;
0536 
0537     local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
0538     if (!local_ip) {
0539         log_err(ret);
0540         return TC_ACT_SHOT;
0541     }
0542 
0543     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
0544                      BPF_F_TUNINFO_IPV6);
0545     if (ret < 0) {
0546         log_err(ret);
0547         return TC_ACT_SHOT;
0548     }
0549 
0550     if (bpf_ntohl(key.local_ipv6[3]) != *local_ip) {
0551         bpf_printk("ip6vxlan key %d local ip6 ::%x remote ip6 ::%x label 0x%x\n",
0552                key.tunnel_id, bpf_ntohl(key.local_ipv6[3]),
0553                bpf_ntohl(key.remote_ipv6[3]), key.tunnel_label);
0554         bpf_printk("local_ip 0x%x\n", *local_ip);
0555         log_err(ret);
0556         return TC_ACT_SHOT;
0557     }
0558 
0559     return TC_ACT_OK;
0560 }
0561 
0562 SEC("tc")
0563 int geneve_set_tunnel(struct __sk_buff *skb)
0564 {
0565     int ret;
0566     struct bpf_tunnel_key key;
0567     struct geneve_opt gopt;
0568 
0569     __builtin_memset(&key, 0x0, sizeof(key));
0570     key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
0571     key.tunnel_id = 2;
0572     key.tunnel_tos = 0;
0573     key.tunnel_ttl = 64;
0574 
0575     __builtin_memset(&gopt, 0x0, sizeof(gopt));
0576     gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
0577     gopt.type = 0x08;
0578     gopt.r1 = 0;
0579     gopt.r2 = 0;
0580     gopt.r3 = 0;
0581     gopt.length = 2; /* 4-byte multiple */
0582     *(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef);
0583 
0584     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0585                      BPF_F_ZERO_CSUM_TX);
0586     if (ret < 0) {
0587         log_err(ret);
0588         return TC_ACT_SHOT;
0589     }
0590 
0591     ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
0592     if (ret < 0) {
0593         log_err(ret);
0594         return TC_ACT_SHOT;
0595     }
0596 
0597     return TC_ACT_OK;
0598 }
0599 
0600 SEC("tc")
0601 int geneve_get_tunnel(struct __sk_buff *skb)
0602 {
0603     int ret;
0604     struct bpf_tunnel_key key;
0605     struct geneve_opt gopt;
0606 
0607     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
0608     if (ret < 0) {
0609         log_err(ret);
0610         return TC_ACT_SHOT;
0611     }
0612 
0613     ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
0614     if (ret < 0)
0615         gopt.opt_class = 0;
0616 
0617     bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
0618            key.tunnel_id, key.remote_ipv4, gopt.opt_class);
0619     return TC_ACT_OK;
0620 }
0621 
0622 SEC("tc")
0623 int ip6geneve_set_tunnel(struct __sk_buff *skb)
0624 {
0625     struct bpf_tunnel_key key;
0626     struct geneve_opt gopt;
0627     int ret;
0628 
0629     __builtin_memset(&key, 0x0, sizeof(key));
0630     key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
0631     key.tunnel_id = 22;
0632     key.tunnel_tos = 0;
0633     key.tunnel_ttl = 64;
0634 
0635     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0636                      BPF_F_TUNINFO_IPV6);
0637     if (ret < 0) {
0638         log_err(ret);
0639         return TC_ACT_SHOT;
0640     }
0641 
0642     __builtin_memset(&gopt, 0x0, sizeof(gopt));
0643     gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
0644     gopt.type = 0x08;
0645     gopt.r1 = 0;
0646     gopt.r2 = 0;
0647     gopt.r3 = 0;
0648     gopt.length = 2; /* 4-byte multiple */
0649     *(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
0650 
0651     ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
0652     if (ret < 0) {
0653         log_err(ret);
0654         return TC_ACT_SHOT;
0655     }
0656 
0657     return TC_ACT_OK;
0658 }
0659 
0660 SEC("tc")
0661 int ip6geneve_get_tunnel(struct __sk_buff *skb)
0662 {
0663     struct bpf_tunnel_key key;
0664     struct geneve_opt gopt;
0665     int ret;
0666 
0667     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
0668                      BPF_F_TUNINFO_IPV6);
0669     if (ret < 0) {
0670         log_err(ret);
0671         return TC_ACT_SHOT;
0672     }
0673 
0674     ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
0675     if (ret < 0)
0676         gopt.opt_class = 0;
0677 
0678     bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
0679            key.tunnel_id, key.remote_ipv4, gopt.opt_class);
0680 
0681     return TC_ACT_OK;
0682 }
0683 
0684 SEC("tc")
0685 int ipip_set_tunnel(struct __sk_buff *skb)
0686 {
0687     struct bpf_tunnel_key key = {};
0688     void *data = (void *)(long)skb->data;
0689     struct iphdr *iph = data;
0690     void *data_end = (void *)(long)skb->data_end;
0691     int ret;
0692 
0693     /* single length check */
0694     if (data + sizeof(*iph) > data_end) {
0695         log_err(1);
0696         return TC_ACT_SHOT;
0697     }
0698 
0699     key.tunnel_ttl = 64;
0700     if (iph->protocol == IPPROTO_ICMP) {
0701         key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
0702     }
0703 
0704     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
0705     if (ret < 0) {
0706         log_err(ret);
0707         return TC_ACT_SHOT;
0708     }
0709 
0710     return TC_ACT_OK;
0711 }
0712 
0713 SEC("tc")
0714 int ipip_get_tunnel(struct __sk_buff *skb)
0715 {
0716     int ret;
0717     struct bpf_tunnel_key key;
0718 
0719     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
0720     if (ret < 0) {
0721         log_err(ret);
0722         return TC_ACT_SHOT;
0723     }
0724 
0725     bpf_printk("remote ip 0x%x\n", key.remote_ipv4);
0726     return TC_ACT_OK;
0727 }
0728 
0729 SEC("tc")
0730 int ipip6_set_tunnel(struct __sk_buff *skb)
0731 {
0732     struct bpf_tunnel_key key = {};
0733     void *data = (void *)(long)skb->data;
0734     struct iphdr *iph = data;
0735     void *data_end = (void *)(long)skb->data_end;
0736     int ret;
0737 
0738     /* single length check */
0739     if (data + sizeof(*iph) > data_end) {
0740         log_err(1);
0741         return TC_ACT_SHOT;
0742     }
0743 
0744     __builtin_memset(&key, 0x0, sizeof(key));
0745     key.tunnel_ttl = 64;
0746     if (iph->protocol == IPPROTO_ICMP) {
0747         key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
0748     }
0749 
0750     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0751                      BPF_F_TUNINFO_IPV6);
0752     if (ret < 0) {
0753         log_err(ret);
0754         return TC_ACT_SHOT;
0755     }
0756 
0757     return TC_ACT_OK;
0758 }
0759 
0760 SEC("tc")
0761 int ipip6_get_tunnel(struct __sk_buff *skb)
0762 {
0763     int ret;
0764     struct bpf_tunnel_key key;
0765 
0766     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
0767                      BPF_F_TUNINFO_IPV6);
0768     if (ret < 0) {
0769         log_err(ret);
0770         return TC_ACT_SHOT;
0771     }
0772 
0773     bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
0774            bpf_htonl(key.remote_ipv6[3]));
0775     return TC_ACT_OK;
0776 }
0777 
0778 SEC("tc")
0779 int ip6ip6_set_tunnel(struct __sk_buff *skb)
0780 {
0781     struct bpf_tunnel_key key = {};
0782     void *data = (void *)(long)skb->data;
0783     struct ipv6hdr *iph = data;
0784     void *data_end = (void *)(long)skb->data_end;
0785     int ret;
0786 
0787     /* single length check */
0788     if (data + sizeof(*iph) > data_end) {
0789         log_err(1);
0790         return TC_ACT_SHOT;
0791     }
0792 
0793     key.tunnel_ttl = 64;
0794     if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
0795         key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
0796     }
0797 
0798     ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
0799                      BPF_F_TUNINFO_IPV6);
0800     if (ret < 0) {
0801         log_err(ret);
0802         return TC_ACT_SHOT;
0803     }
0804 
0805     return TC_ACT_OK;
0806 }
0807 
0808 SEC("tc")
0809 int ip6ip6_get_tunnel(struct __sk_buff *skb)
0810 {
0811     int ret;
0812     struct bpf_tunnel_key key;
0813 
0814     ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
0815                      BPF_F_TUNINFO_IPV6);
0816     if (ret < 0) {
0817         log_err(ret);
0818         return TC_ACT_SHOT;
0819     }
0820 
0821     bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
0822            bpf_htonl(key.remote_ipv6[3]));
0823     return TC_ACT_OK;
0824 }
0825 
0826 SEC("tc")
0827 int xfrm_get_state(struct __sk_buff *skb)
0828 {
0829     struct bpf_xfrm_state x;
0830     int ret;
0831 
0832     ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
0833     if (ret < 0)
0834         return TC_ACT_OK;
0835 
0836     bpf_printk("reqid %d spi 0x%x remote ip 0x%x\n",
0837            x.reqid, bpf_ntohl(x.spi),
0838            bpf_ntohl(x.remote_ipv4));
0839     return TC_ACT_OK;
0840 }
0841 
0842 char _license[] SEC("license") = "GPL";