encap-forward: Support conditional IPv6 encapsulation with IPV6=1

Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
This commit is contained in:
Toke Høiland-Jørgensen
2020-10-07 13:35:38 +02:00
parent 061bb5026c
commit bc91d4d456
5 changed files with 31 additions and 9 deletions

View File

@@ -3,6 +3,7 @@
USER_TARGETS := USER_TARGETS :=
BPF_TARGETS := xdp_encap tc_bpf_encap BPF_TARGETS := xdp_encap tc_bpf_encap
EXTRA_DEPS := encap.h EXTRA_DEPS := encap.h
EXTRA_CFLAGS := $(if $(IPV6),-DIPV6)
LIB_DIR = ../lib LIB_DIR = ../lib

View File

@@ -1,6 +1,6 @@
#define NEXTHDR_IPV6 41 #define NEXTHDR_IPV6 41
#ifdef IPV6
static void encap_ipv6(volatile void *data, volatile void *data_end) static void encap_ipv6(volatile void *data, volatile void *data_end)
{ {
volatile struct ipv6hdr *ip6h; volatile struct ipv6hdr *ip6h;
@@ -27,6 +27,7 @@ static void encap_ipv6(volatile void *data, volatile void *data_end)
len = (data_end - data); len = (data_end - data);
ip6h->payload_len = bpf_htons(len - sizeof(struct ethhdr) - sizeof(*ip6h)); ip6h->payload_len = bpf_htons(len - sizeof(struct ethhdr) - sizeof(*ip6h));
} }
#else
static __always_inline __u16 csum_fold_helper(__u32 csum) static __always_inline __u16 csum_fold_helper(__u32 csum)
{ {
@@ -60,3 +61,5 @@ static void encap_ipv4(volatile void *data, volatile void *data_end)
iph->tot_len = bpf_htons(len - sizeof(struct ethhdr)); 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)); iph->check = csum_fold_helper(bpf_csum_diff((__be32 *)iph, 0, (__be32 *)iph, sizeof(*iph), 0));
} }
#endif

View File

@@ -4,24 +4,34 @@
#include <xdp/parsing_helpers.h> #include <xdp/parsing_helpers.h>
#include "encap.h" #include "encap.h"
#ifdef IPV6
#define OFFSET sizeof(struct ipv6hdr)
#define ENCAP_TYPE BPF_F_ADJ_ROOM_ENCAP_L3_IPV6
#else
#define OFFSET sizeof(struct iphdr)
#define ENCAP_TYPE BPF_F_ADJ_ROOM_ENCAP_L3_IPV4
#endif
SEC("classifier") int tc_encap(struct __sk_buff *skb) SEC("classifier") int tc_encap(struct __sk_buff *skb)
{ {
volatile void *data, *data_end; volatile void *data, *data_end;
size_t offset = OFFSET;
int ret = BPF_DROP; int ret = BPF_DROP;
size_t offset = sizeof(struct iphdr);
if (bpf_skb_adjust_room(skb, offset, BPF_ADJ_ROOM_MAC, ENCAP_TYPE))
if (bpf_skb_adjust_room(skb, offset, BPF_ADJ_ROOM_MAC, BPF_F_ADJ_ROOM_ENCAP_L3_IPV4))
goto out; goto out;
data = (void *)(long)skb->data; data = (void *)(long)skb->data;
data_end = (void *)(long)skb->data_end; data_end = (void *)(long)skb->data_end;
// encap_ipv6(ctx); #ifdef IPV6
encap_ipv6(data, data_end);
#else
encap_ipv4(data, data_end); encap_ipv4(data, data_end);
/* proposed new helper for skipping source validation: /* proposed new helper for skipping source validation:
bpf_skb_set_source_valid(skb, 1); */ bpf_skb_set_source_valid(skb, 1); */
#endif
ret = BPF_OK; ret = BPF_OK;
out: out:

View File

@@ -4,13 +4,18 @@
#include <xdp/parsing_helpers.h> #include <xdp/parsing_helpers.h>
#include "encap.h" #include "encap.h"
#ifdef IPV6
#define OFFSET sizeof(struct ipv6hdr)
#else
#define OFFSET sizeof(struct iphdr)
#endif
SEC("prog") int xdp_encap(struct xdp_md *ctx) SEC("prog") int xdp_encap(struct xdp_md *ctx)
{ {
volatile struct ethhdr *ehdr, old_ehdr = {}; volatile struct ethhdr *ehdr, old_ehdr = {};
volatile void *data, *data_end; volatile void *data, *data_end;
size_t offset = OFFSET;
int ret = XDP_ABORTED; int ret = XDP_ABORTED;
size_t offset = sizeof(struct iphdr);
data = (void *)(long)ctx->data; data = (void *)(long)ctx->data;
data_end = (void *)(long)ctx->data_end; data_end = (void *)(long)ctx->data_end;
@@ -33,8 +38,11 @@ SEC("prog") int xdp_encap(struct xdp_md *ctx)
*ehdr = old_ehdr; *ehdr = old_ehdr;
ehdr->h_proto = bpf_htons(ETH_P_IP); ehdr->h_proto = bpf_htons(ETH_P_IP);
// encap_ipv6(data, data_end); #ifdef IPV6
encap_ipv6(data, data_end);
#else
encap_ipv4(data, data_end); encap_ipv4(data, data_end);
#endif
ret = XDP_PASS; ret = XDP_PASS;
out: out:
return ret; return ret;

View File

@@ -36,8 +36,8 @@ endif
# BPF-prog kern and userspace shares struct via header file: # BPF-prog kern and userspace shares struct via header file:
KERN_USER_H ?= $(wildcard common_kern_user.h) KERN_USER_H ?= $(wildcard common_kern_user.h)
CFLAGS += -I$(HEADER_DIR) -I$(LIB_DIR)/util CFLAGS += -I$(HEADER_DIR) -I$(LIB_DIR)/util $(EXTRA_CFLAGS)
BPF_CFLAGS += -I$(HEADER_DIR) BPF_CFLAGS += -I$(HEADER_DIR) $(EXTRA_CFLAGS)
BPF_HEADERS := $(wildcard $(HEADER_DIR)/bpf/*.h) $(wildcard $(HEADER_DIR)/xdp/*.h) BPF_HEADERS := $(wildcard $(HEADER_DIR)/bpf/*.h) $(wildcard $(HEADER_DIR)/xdp/*.h)