af_xdp: update custom XDP program example 09/38009/6
authorYulong Pei <yulong.pei@intel.com>
Wed, 25 Jan 2023 08:05:03 +0000 (08:05 +0000)
committerBeno�t Ganne <bganne@cisco.com>
Thu, 2 Feb 2023 12:51:45 +0000 (12:51 +0000)
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>
extras/bpf/Makefile
extras/bpf/af_xdp.bpf.c

index 77b0643..9ad26ea 100644 (file)
@@ -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
 
index eddd2b0..c9ca019 100644 (file)
@@ -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.
 #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);