2020-10-06 15:53:55 +02:00
|
|
|
#define NEXTHDR_IPV6 41
|
|
|
|
|
2020-10-07 13:35:38 +02:00
|
|
|
#ifdef IPV6
|
2020-10-06 15:53:55 +02:00
|
|
|
static void encap_ipv6(volatile void *data, volatile void *data_end)
|
|
|
|
{
|
|
|
|
volatile struct ipv6hdr *ip6h;
|
2020-11-25 11:31:06 +01:00
|
|
|
volatile struct ethhdr *eth;
|
2020-10-06 15:53:55 +02:00
|
|
|
size_t len;
|
|
|
|
|
|
|
|
struct ipv6hdr encap_hdr = {
|
|
|
|
.version = 6,
|
|
|
|
.nexthdr = NEXTHDR_IPV6,
|
|
|
|
.hop_limit = 16,
|
|
|
|
.saddr = { .s6_addr = { 0xfc, 0x00, 0xde, 0xad, 0xca, 0xfe,
|
|
|
|
0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x02 } },
|
|
|
|
.daddr = { .s6_addr = { 0xfc, 0x00, 0xde, 0xad, 0xca, 0xfe,
|
|
|
|
0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x01 } },
|
|
|
|
};
|
|
|
|
|
2020-11-25 11:31:06 +01:00
|
|
|
eth = data;
|
|
|
|
ip6h = (void *)(eth +1);
|
2020-10-06 15:53:55 +02:00
|
|
|
if (ip6h + 1 > data_end)
|
|
|
|
return;
|
|
|
|
|
2020-11-25 11:31:06 +01:00
|
|
|
eth->h_proto = bpf_htons(ETH_P_IPV6);
|
2020-10-06 15:53:55 +02:00
|
|
|
*ip6h = encap_hdr;
|
|
|
|
|
|
|
|
len = (data_end - data);
|
|
|
|
ip6h->payload_len = bpf_htons(len - sizeof(struct ethhdr) - sizeof(*ip6h));
|
|
|
|
}
|
2020-10-07 13:35:38 +02:00
|
|
|
#else
|
2020-10-06 15:53:55 +02:00
|
|
|
|
|
|
|
static __always_inline __u16 csum_fold_helper(__u32 csum)
|
|
|
|
{
|
|
|
|
__u32 sum;
|
|
|
|
sum = (csum >> 16) + (csum & 0xffff);
|
|
|
|
sum += (sum >> 16);
|
|
|
|
return ~sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void encap_ipv4(volatile void *data, volatile void *data_end)
|
|
|
|
{
|
2020-11-25 11:31:06 +01:00
|
|
|
volatile struct ethhdr *eth;
|
2020-10-06 15:53:55 +02:00
|
|
|
volatile struct iphdr *iph;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
struct iphdr encap_hdr = {
|
|
|
|
.version = 4,
|
|
|
|
.ihl = 5,
|
|
|
|
.protocol = NEXTHDR_IPV6,
|
|
|
|
.ttl = 16,
|
|
|
|
.saddr = bpf_htonl(0x0a0b0202),
|
|
|
|
.daddr = bpf_htonl(0x0a0b0201),
|
|
|
|
};
|
|
|
|
|
2020-11-25 11:31:06 +01:00
|
|
|
eth = data;
|
|
|
|
iph = (void *)(eth +1);
|
2020-10-06 15:53:55 +02:00
|
|
|
if (iph + 1 > data_end)
|
|
|
|
return;
|
|
|
|
|
2020-11-25 11:31:06 +01:00
|
|
|
eth->h_proto = bpf_htons(ETH_P_IP);
|
2020-10-06 15:53:55 +02:00
|
|
|
*iph = encap_hdr;
|
|
|
|
|
|
|
|
len = (data_end - data);
|
|
|
|
iph->tot_len = bpf_htons(len - sizeof(struct ethhdr));
|
|
|
|
iph->check = csum_fold_helper(bpf_csum_diff((__be32 *)iph, 0, (__be32 *)iph, sizeof(*iph), 0));
|
|
|
|
}
|
2020-10-07 13:35:38 +02:00
|
|
|
|
|
|
|
#endif
|