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>
This commit is contained in:
parent
02bdd3f5cb
commit
a3f1b4c719
@ -1,13 +1,14 @@
|
||||
CC?=clang
|
||||
# where to find bpf includes?
|
||||
BPF_ROOT?=/usr/include
|
||||
#BPF_ROOT?=/opt/vpp/external/x86_64/include
|
||||
CC := $(shell which clang)
|
||||
|
||||
CFLAGS:=-O3 -g -Wextra -Wall -target bpf
|
||||
# where to find bpf includes?
|
||||
BPF_ROOT ?= /usr/include
|
||||
#BPF_ROOT ?= /opt/vpp/external/x86_64/include
|
||||
|
||||
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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/* 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 ethhdr *eth = data;
|
||||
if (eth->h_proto != ntohs(ETH_P_IP)) {
|
||||
DEBUG_PRINT("unsupported eth proto %x", (int)eth->h_proto);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user