diff options
author | Yulong Pei <yulong.pei@intel.com> | 2023-01-25 08:05:03 +0000 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2023-02-02 12:51:45 +0000 |
commit | a3f1b4c719b25595fc8f0214a29210abbfc34683 (patch) | |
tree | de8385d233a0f985f87b1f74bec50175d6f5d57a | |
parent | 02bdd3f5cb0f2ff4988f972f31fb44da89fd786e (diff) |
af_xdp: update custom XDP program example
Update custom XDP program example to work with libbpf 0.8.0 and
libxdp 1.2.9.
Type: fix
Signed-off-by: Yulong Pei <yulong.pei@intel.com>
Change-Id: Ib8d03f0be7f71fe996dfb7da0cfe35165711ebb0
Signed-off-by: Yulong Pei <yulong.pei@intel.com>
-rw-r--r-- | extras/bpf/Makefile | 15 | ||||
-rw-r--r-- | extras/bpf/af_xdp.bpf.c | 103 |
2 files changed, 65 insertions, 53 deletions
diff --git a/extras/bpf/Makefile b/extras/bpf/Makefile index 77b06434237..9ad26eaacb1 100644 --- a/extras/bpf/Makefile +++ b/extras/bpf/Makefile @@ -1,13 +1,14 @@ -CC?=clang +CC := $(shell which clang) + # where to find bpf includes? -BPF_ROOT?=/usr/include -#BPF_ROOT?=/opt/vpp/external/x86_64/include +BPF_ROOT ?= /usr/include +#BPF_ROOT ?= /opt/vpp/external/x86_64/include -CFLAGS:=-O3 -g -Wextra -Wall -target bpf +CFLAGS := -O3 -g -Wextra -Wall -target bpf # Workaround for Ubuntu/Debian for asm/types.h -CFLAGS+= -I/usr/include/x86_64-linux-gnu -CFLAGS+= -I$(BPF_ROOT) -#CFLAGS+= -DDEBUG +CFLAGS += -I/usr/include/x86_64-linux-gnu +CFLAGS += -I$(BPF_ROOT) +#CFLAGS += -DDEBUG all: af_xdp.bpf.o diff --git a/extras/bpf/af_xdp.bpf.c b/extras/bpf/af_xdp.bpf.c index eddd2b0e509..c9ca0193ce5 100644 --- a/extras/bpf/af_xdp.bpf.c +++ b/extras/bpf/af_xdp.bpf.c @@ -4,11 +4,15 @@ * Copyright (c) 2020 Cisco and/or its affiliates. */ #include <linux/bpf.h> +#include <bpf/bpf_helpers.h> +#include <xdp/xdp_helpers.h> #include <linux/in.h> #include <linux/if_ether.h> #include <linux/ip.h> #include <linux/udp.h> -#include <bpf/bpf_helpers.h> + +#define XDP_METADATA_SECTION "xdp_metadata" +#define XSK_PROG_VERSION 1 /* * when compiled, debug print can be viewed with eg. @@ -26,63 +30,70 @@ #define DEBUG_PRINT(fmt, ...) #endif /* DEBUG */ -#define ntohs(x) __constant_ntohs(x) +#define ntohs(x) __constant_ntohs (x) -SEC("maps") -struct bpf_map_def xsks_map = { - .type = BPF_MAP_TYPE_XSKMAP, - .key_size = sizeof(int), - .value_size = sizeof(int), - .max_entries = 64, /* max 64 queues per device */ -}; +#define DEFAULT_QUEUE_IDS 64 -SEC("xdp_sock") -int xdp_sock_prog(struct xdp_md *ctx) { - const void *data = (void *)(long)ctx->data; - const void *data_end = (void *)(long)ctx->data_end; +struct +{ + __uint (type, BPF_MAP_TYPE_XSKMAP); + __uint (key_size, sizeof (int)); + __uint (value_size, sizeof (int)); + __uint (max_entries, DEFAULT_QUEUE_IDS); +} xsks_map SEC (".maps"); - DEBUG_PRINT("rx %ld bytes packet", (long)data_end - (long)data); +struct +{ + __uint (priority, 10); + __uint (XDP_PASS, 1); +} XDP_RUN_CONFIG (xdp_sock_prog); - /* smallest packet we are interesting in is ip-ip */ - if (data + sizeof(struct ethhdr) + 2 * sizeof(struct iphdr) > data_end) { - DEBUG_PRINT("packet too small"); - return XDP_PASS; - } +SEC ("xdp") +int +xdp_sock_prog (struct xdp_md *ctx) +{ + const void *data = (void *) (long) ctx->data; + const void *data_end = (void *) (long) ctx->data_end; + + DEBUG_PRINT ("rx %ld bytes packet", (long) data_end - (long) data); - const struct ethhdr *eth = data; - if (eth->h_proto != ntohs(ETH_P_IP)) { - DEBUG_PRINT("unsupported eth proto %x", (int)eth->h_proto); - return XDP_PASS; + /* smallest packet we are interesting in is ip-ip */ + if (data + sizeof (struct ethhdr) + 2 * sizeof (struct iphdr) > data_end) + { + DEBUG_PRINT ("packet too small"); + return XDP_PASS; } - const struct iphdr *ip = (void *)(eth + 1); - switch (ip->protocol) { - case IPPROTO_UDP: { - const struct udphdr *udp = (void *)(ip + 1); - if (udp->dest != ntohs(4789)) { /* VxLAN dest port */ - DEBUG_PRINT("unsupported udp dst port %x", (int)udp->dest); - return XDP_PASS; - } - } - case IPPROTO_IPIP: - case IPPROTO_ESP: - break; - default: - DEBUG_PRINT("unsupported ip proto %x", (int)ip->protocol); - return XDP_PASS; + const struct ethhdr *eth = data; + if (eth->h_proto != ntohs (ETH_P_IP)) + { + DEBUG_PRINT ("unsupported eth proto %x", (int) eth->h_proto); + return XDP_PASS; } - int qid = ctx->rx_queue_index; - if (!bpf_map_lookup_elem(&xsks_map, &qid)) + const struct iphdr *ip = (void *) (eth + 1); + switch (ip->protocol) + { + case IPPROTO_UDP: { - DEBUG_PRINT("no socket found"); - return XDP_PASS; + const struct udphdr *udp = (void *) (ip + 1); + if (udp->dest != ntohs (4789)) /* VxLAN dest port */ + { + DEBUG_PRINT ("unsupported udp dst port %x", (int) udp->dest); + return XDP_PASS; + } } + case IPPROTO_IPIP: + case IPPROTO_ESP: + break; + default: + DEBUG_PRINT ("unsupported ip proto %x", (int) ip->protocol); + return XDP_PASS; + } - DEBUG_PRINT("going to socket %d", qid); - return bpf_redirect_map(&xsks_map, qid, 0); + return bpf_redirect_map (&xsks_map, ctx->rx_queue_index, XDP_PASS); } /* actually Dual GPLv2/Apache2, but GPLv2 as far as kernel is concerned */ -SEC("license") -char _license[] = "GPL"; +char _license[] SEC ("license") = "GPL"; +__uint (xsk_prog_version, XSK_PROG_VERSION) SEC (XDP_METADATA_SECTION); |