From 00eaf20fae3d6a57862f1076810001b95cf16404 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Tue, 13 Oct 2020 15:07:39 +0200 Subject: [PATCH] MTU-tests: Add tc_bpf program that increase packet size Signed-off-by: Jesper Dangaard Brouer --- MTU-tests/Makefile | 4 +- MTU-tests/tc_bpf_inc_pkt_size.c | 69 +++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 MTU-tests/tc_bpf_inc_pkt_size.c diff --git a/MTU-tests/Makefile b/MTU-tests/Makefile index 5b34c4c..7539848 100644 --- a/MTU-tests/Makefile +++ b/MTU-tests/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) USER_TARGETS := -BPF_TARGETS := tc_bpf_encap -EXTRA_DEPS := encap.h +BPF_TARGETS := tc_bpf_inc_pkt_size +# EXTRA_DEPS := encap.h LIB_DIR = ../lib diff --git a/MTU-tests/tc_bpf_inc_pkt_size.c b/MTU-tests/tc_bpf_inc_pkt_size.c new file mode 100644 index 0000000..4c635cf --- /dev/null +++ b/MTU-tests/tc_bpf_inc_pkt_size.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +/* MTU is defined as L3 size (usually 1500 for Ethernet), + * but remember TC (and XDP) operate at L2. + */ +//#define PKT_SIZE_L3 1500 +#define PKT_SIZE_L3 1501 +//#define PKT_SIZE_L3 1505 +//#define PKT_SIZE_L3 1600 +//#define PKT_SIZE_L3 20000 +//#define PKT_SIZE_L3 65535 + +#define OFFSET sizeof(struct iphdr) +#define ENCAP_TYPE BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 + +SEC("classifier") int tc_inc_pkt_sz(struct __sk_buff *skb) +{ + volatile void *data, *data_end; + int ret = BPF_DROP; + struct ethhdr *eth; + struct iphdr *iph; + int extra_len; + int len; + + /* Desired packet size at L2 */ + int pkt_size_l2 = PKT_SIZE_L3 + sizeof(*eth) ; + + data = (void *)(long)skb->data; + data_end = (void *)(long)skb->data_end; + eth = (struct ethhdr *)data; + + if (data + sizeof(*eth) > data_end) + return BPF_DROP; + + /* Keep ARP resolution working */ + if (eth->h_proto == bpf_htons(ETH_P_ARP)) { + ret = BPF_OK; + goto out; + } + + len = (data_end - data); + extra_len = pkt_size_l2 - len; + + if (bpf_skb_adjust_room(skb, extra_len, BPF_ADJ_ROOM_MAC, ENCAP_TYPE)) + goto out; + + // TODO: Handle if bpf_skb_adjust_room() cannot increase size, + // as it's only my patched kernel that drop the MTU check + + /* Most re-load after bpf_skb_adjust_room() */ + data = (void *)(long)skb->data; + data_end = (void *)(long)skb->data_end; + + eth = (void *)data; + iph = (void *)(eth +1); + if (iph +1 > data_end) + goto out; + + eth->h_proto = bpf_htons(ETH_P_IP); + + ret = BPF_OK; +out: + return ret; +} + +char _license[] SEC("license") = "GPL";