mirror of
https://github.com/xdp-project/bpf-examples.git
synced 2024-05-06 15:54:53 +00:00
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:
@@ -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
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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:
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user