86 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <stddef.h>3#include <string.h>4#include <linux/bpf.h>5#include <linux/ip.h>6#include <linux/ipv6.h>7#include <bpf/bpf_helpers.h>8#include <bpf/bpf_endian.h>9 10struct grehdr {11 __be16 flags;12 __be16 protocol;13};14 15SEC("encap_gre")16int bpf_lwt_encap_gre(struct __sk_buff *skb)17{18 struct encap_hdr {19 struct iphdr iph;20 struct grehdr greh;21 } hdr;22 int err;23 24 memset(&hdr, 0, sizeof(struct encap_hdr));25 26 hdr.iph.ihl = 5;27 hdr.iph.version = 4;28 hdr.iph.ttl = 0x40;29 hdr.iph.protocol = 47; /* IPPROTO_GRE */30#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__31 hdr.iph.saddr = 0x640110ac; /* 172.16.1.100 */32 hdr.iph.daddr = 0x641010ac; /* 172.16.16.100 */33#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__34 hdr.iph.saddr = 0xac100164; /* 172.16.1.100 */35 hdr.iph.daddr = 0xac101064; /* 172.16.16.100 */36#else37#error "Fix your compiler's __BYTE_ORDER__?!"38#endif39 hdr.iph.tot_len = bpf_htons(skb->len + sizeof(struct encap_hdr));40 41 hdr.greh.protocol = skb->protocol;42 43 err = bpf_lwt_push_encap(skb, BPF_LWT_ENCAP_IP, &hdr,44 sizeof(struct encap_hdr));45 if (err)46 return BPF_DROP;47 48 return BPF_LWT_REROUTE;49}50 51SEC("encap_gre6")52int bpf_lwt_encap_gre6(struct __sk_buff *skb)53{54 struct encap_hdr {55 struct ipv6hdr ip6hdr;56 struct grehdr greh;57 } hdr;58 int err;59 60 memset(&hdr, 0, sizeof(struct encap_hdr));61 62 hdr.ip6hdr.version = 6;63 hdr.ip6hdr.payload_len = bpf_htons(skb->len + sizeof(struct grehdr));64 hdr.ip6hdr.nexthdr = 47; /* IPPROTO_GRE */65 hdr.ip6hdr.hop_limit = 0x40;66 /* fb01::1 */67 hdr.ip6hdr.saddr.s6_addr[0] = 0xfb;68 hdr.ip6hdr.saddr.s6_addr[1] = 1;69 hdr.ip6hdr.saddr.s6_addr[15] = 1;70 /* fb10::1 */71 hdr.ip6hdr.daddr.s6_addr[0] = 0xfb;72 hdr.ip6hdr.daddr.s6_addr[1] = 0x10;73 hdr.ip6hdr.daddr.s6_addr[15] = 1;74 75 hdr.greh.protocol = skb->protocol;76 77 err = bpf_lwt_push_encap(skb, BPF_LWT_ENCAP_IP, &hdr,78 sizeof(struct encap_hdr));79 if (err)80 return BPF_DROP;81 82 return BPF_LWT_REROUTE;83}84 85char _license[] SEC("license") = "GPL";86