[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190117010115.18234-3-maciejromanfijalkowski@gmail.com>
Date: Thu, 17 Jan 2019 02:01:11 +0100
From: Maciej Fijalkowski <maciejromanfijalkowski@...il.com>
To: daniel@...earbox.net, ast@...nel.org
Cc: netdev@...r.kernel.org, jakub.kicinski@...ronome.com,
brouer@...hat.com
Subject: [PATCH bpf-next 2/6] samples: bpf: Convert XDP samples to libbpf usage
Some of XDP samples that are attaching the bpf program to the interface
via libbpf's bpf_set_link_xdp_fd are still using the bpf_load.c for
loading and manipulating the ebpf program and maps. Convert them to do
this through libbpf usage and remove bpf_load from the picture.
While at it remove what looks like debug leftover in
xdp_redirect_map_user.c
xdp_redirect_cpu is omitted because of read_trace_pipe() usage, which
doesn't seem to be handled in libbpf ATM.
Signed-off-by: Maciej Fijalkowski <maciejromanfijalkowski@...il.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@...ronome.com>
---
samples/bpf/Makefile | 8 ++--
samples/bpf/xdp_redirect_map_user.c | 47 ++++++++++++++++-------
samples/bpf/xdp_redirect_user.c | 44 +++++++++++++++++-----
samples/bpf/xdp_router_ipv4_user.c | 75 ++++++++++++++++++++++++++-----------
samples/bpf/xdp_tx_iptunnel_user.c | 37 ++++++++++++------
5 files changed, 151 insertions(+), 60 deletions(-)
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 66ae15f27c70..4486fedaf09a 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -87,18 +87,18 @@ test_cgrp2_sock2-objs := bpf_load.o test_cgrp2_sock2.o
xdp1-objs := xdp1_user.o
# reuse xdp1 source intentionally
xdp2-objs := xdp1_user.o
-xdp_router_ipv4-objs := bpf_load.o xdp_router_ipv4_user.o
+xdp_router_ipv4-objs := xdp_router_ipv4_user.o
test_current_task_under_cgroup-objs := bpf_load.o $(CGROUP_HELPERS) \
test_current_task_under_cgroup_user.o
trace_event-objs := bpf_load.o trace_event_user.o $(TRACE_HELPERS)
sampleip-objs := bpf_load.o sampleip_user.o $(TRACE_HELPERS)
tc_l2_redirect-objs := bpf_load.o tc_l2_redirect_user.o
lwt_len_hist-objs := bpf_load.o lwt_len_hist_user.o
-xdp_tx_iptunnel-objs := bpf_load.o xdp_tx_iptunnel_user.o
+xdp_tx_iptunnel-objs := xdp_tx_iptunnel_user.o
test_map_in_map-objs := bpf_load.o test_map_in_map_user.o
per_socket_stats_example-objs := cookie_uid_helper_example.o
-xdp_redirect-objs := bpf_load.o xdp_redirect_user.o
-xdp_redirect_map-objs := bpf_load.o xdp_redirect_map_user.o
+xdp_redirect-objs := xdp_redirect_user.o
+xdp_redirect_map-objs := xdp_redirect_map_user.o
xdp_redirect_cpu-objs := bpf_load.o xdp_redirect_cpu_user.o
xdp_monitor-objs := bpf_load.o xdp_monitor_user.o
xdp_rxq_info-objs := xdp_rxq_info_user.o
diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c
index 4445e76854b5..60d46eea225b 100644
--- a/samples/bpf/xdp_redirect_map_user.c
+++ b/samples/bpf/xdp_redirect_map_user.c
@@ -22,15 +22,16 @@
#include <libgen.h>
#include <sys/resource.h>
-#include "bpf_load.h"
#include "bpf_util.h"
#include <bpf/bpf.h>
+#include "bpf/libbpf.h"
static int ifindex_in;
static int ifindex_out;
static bool ifindex_out_xdp_dummy_attached = true;
static __u32 xdp_flags;
+static int rxcnt_map_fd;
static void int_exit(int sig)
{
@@ -53,7 +54,7 @@ static void poll_stats(int interval, int ifindex)
int i;
sleep(interval);
- assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0);
+ assert(bpf_map_lookup_elem(rxcnt_map_fd, &key, values) == 0);
for (i = 0; i < nr_cpus; i++)
sum += (values[i] - prev[i]);
if (sum)
@@ -76,9 +77,16 @@ static void usage(const char *prog)
int main(int argc, char **argv)
{
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+ struct bpf_prog_load_attr prog_load_attr = {
+ .prog_type = BPF_PROG_TYPE_XDP,
+ };
+ struct bpf_program *prog, *dummy_prog;
+ int prog_fd, dummy_prog_fd;
const char *optstr = "SN";
- char filename[256];
+ struct bpf_object *obj;
int ret, opt, key = 0;
+ char filename[256];
+ int tx_port_map_fd;
while ((opt = getopt(argc, argv, optstr)) != -1) {
switch (opt) {
@@ -109,24 +117,40 @@ int main(int argc, char **argv)
printf("input: %d output: %d\n", ifindex_in, ifindex_out);
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+ prog_load_attr.file = filename;
+
+ if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
+ return 1;
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ prog = bpf_program__next(NULL, obj);
+ dummy_prog = bpf_program__next(prog, obj);
+ if (!prog || !dummy_prog) {
+ printf("finding a prog in obj file failed\n");
+ return 1;
+ }
+ /* bpf_prog_load_xattr gives us the pointer to first prog's fd,
+ * so we're missing only the fd for dummy prog
+ */
+ dummy_prog_fd = bpf_program__fd(dummy_prog);
+ if (prog_fd < 0 || dummy_prog_fd < 0) {
+ printf("bpf_prog_load_xattr: %s\n", strerror(errno));
return 1;
}
- if (!prog_fd[0]) {
- printf("load_bpf_file: %s\n", strerror(errno));
+ tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port");
+ rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt");
+ if (tx_port_map_fd < 0 || rxcnt_map_fd < 0) {
+ printf("bpf_object__find_map_fd_by_name failed\n");
return 1;
}
- if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex_in, prog_fd, xdp_flags) < 0) {
printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
return 1;
}
/* Loading dummy XDP prog on out-device */
- if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
+ if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd,
(xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
ifindex_out_xdp_dummy_attached = false;
@@ -135,11 +159,8 @@ int main(int argc, char **argv)
signal(SIGINT, int_exit);
signal(SIGTERM, int_exit);
- printf("map[0] (vports) = %i, map[1] (map) = %i, map[2] (count) = %i\n",
- map_fd[0], map_fd[1], map_fd[2]);
-
/* populate virtual to physical port map */
- ret = bpf_map_update_elem(map_fd[0], &key, &ifindex_out, 0);
+ ret = bpf_map_update_elem(tx_port_map_fd, &key, &ifindex_out, 0);
if (ret) {
perror("bpf_update_elem");
goto out;
diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c
index 81a69e36cb78..93404820df68 100644
--- a/samples/bpf/xdp_redirect_user.c
+++ b/samples/bpf/xdp_redirect_user.c
@@ -22,15 +22,16 @@
#include <libgen.h>
#include <sys/resource.h>
-#include "bpf_load.h"
#include "bpf_util.h"
#include <bpf/bpf.h>
+#include "bpf/libbpf.h"
static int ifindex_in;
static int ifindex_out;
static bool ifindex_out_xdp_dummy_attached = true;
static __u32 xdp_flags;
+static int rxcnt_map_fd;
static void int_exit(int sig)
{
@@ -53,7 +54,7 @@ static void poll_stats(int interval, int ifindex)
int i;
sleep(interval);
- assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0);
+ assert(bpf_map_lookup_elem(rxcnt_map_fd, &key, values) == 0);
for (i = 0; i < nr_cpus; i++)
sum += (values[i] - prev[i]);
if (sum)
@@ -77,9 +78,16 @@ static void usage(const char *prog)
int main(int argc, char **argv)
{
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+ struct bpf_prog_load_attr prog_load_attr = {
+ .prog_type = BPF_PROG_TYPE_XDP,
+ };
+ struct bpf_program *prog, *dummy_prog;
+ int prog_fd, tx_port_map_fd, opt;
const char *optstr = "SN";
+ struct bpf_object *obj;
char filename[256];
- int ret, opt, key = 0;
+ int dummy_prog_fd;
+ int ret, key = 0;
while ((opt = getopt(argc, argv, optstr)) != -1) {
switch (opt) {
@@ -110,24 +118,40 @@ int main(int argc, char **argv)
printf("input: %d output: %d\n", ifindex_in, ifindex_out);
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+ prog_load_attr.file = filename;
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
+ return 1;
+
+ prog = bpf_program__next(NULL, obj);
+ dummy_prog = bpf_program__next(prog, obj);
+ if (!prog || !dummy_prog) {
+ printf("finding a prog in obj file failed\n");
+ return 1;
+ }
+ /* bpf_prog_load_xattr gives us the pointer to first prog's fd,
+ * so we're missing only the fd for dummy prog
+ */
+ dummy_prog_fd = bpf_program__fd(dummy_prog);
+ if (prog_fd < 0 || dummy_prog_fd < 0) {
+ printf("bpf_prog_load_xattr: %s\n", strerror(errno));
return 1;
}
- if (!prog_fd[0]) {
- printf("load_bpf_file: %s\n", strerror(errno));
+ tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port");
+ rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt");
+ if (tx_port_map_fd < 0 || rxcnt_map_fd < 0) {
+ printf("bpf_object__find_map_fd_by_name failed\n");
return 1;
}
- if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex_in, prog_fd, xdp_flags) < 0) {
printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
return 1;
}
/* Loading dummy XDP prog on out-device */
- if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
+ if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd,
(xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
ifindex_out_xdp_dummy_attached = false;
@@ -137,7 +161,7 @@ int main(int argc, char **argv)
signal(SIGTERM, int_exit);
/* bpf redirect port */
- ret = bpf_map_update_elem(map_fd[0], &key, &ifindex_out, 0);
+ ret = bpf_map_update_elem(tx_port_map_fd, &key, &ifindex_out, 0);
if (ret) {
perror("bpf_update_elem");
goto out;
diff --git a/samples/bpf/xdp_router_ipv4_user.c b/samples/bpf/xdp_router_ipv4_user.c
index b2b4dfa776c8..cea2306f5ab7 100644
--- a/samples/bpf/xdp_router_ipv4_user.c
+++ b/samples/bpf/xdp_router_ipv4_user.c
@@ -15,7 +15,6 @@
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
-#include "bpf_load.h"
#include <bpf/bpf.h>
#include <arpa/inet.h>
#include <fcntl.h>
@@ -25,11 +24,17 @@
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include "bpf_util.h"
+#include "bpf/libbpf.h"
int sock, sock_arp, flags = 0;
static int total_ifindex;
int *ifindex_list;
char buf[8192];
+static int lpm_map_fd;
+static int rxcnt_map_fd;
+static int arp_table_map_fd;
+static int exact_match_map_fd;
+static int tx_port_map_fd;
static int get_route_table(int rtm_family);
static void int_exit(int sig)
@@ -186,7 +191,8 @@ static void read_route(struct nlmsghdr *nh, int nll)
bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
exit(0);
}
- assert(bpf_map_update_elem(map_fd[4], &route.iface, &route.iface, 0) == 0);
+ assert(bpf_map_update_elem(tx_port_map_fd,
+ &route.iface, &route.iface, 0) == 0);
if (rtm_family == AF_INET) {
struct trie_value {
__u8 prefix[4];
@@ -207,11 +213,16 @@ static void read_route(struct nlmsghdr *nh, int nll)
direct_entry.arp.dst = 0;
if (route.dst_len == 32) {
if (nh->nlmsg_type == RTM_DELROUTE) {
- assert(bpf_map_delete_elem(map_fd[3], &route.dst) == 0);
+ assert(bpf_map_delete_elem(exact_match_map_fd,
+ &route.dst) == 0);
} else {
- if (bpf_map_lookup_elem(map_fd[2], &route.dst, &direct_entry.arp.mac) == 0)
+ if (bpf_map_lookup_elem(arp_table_map_fd,
+ &route.dst,
+ &direct_entry.arp.mac) == 0)
direct_entry.arp.dst = route.dst;
- assert(bpf_map_update_elem(map_fd[3], &route.dst, &direct_entry, 0) == 0);
+ assert(bpf_map_update_elem(exact_match_map_fd,
+ &route.dst,
+ &direct_entry, 0) == 0);
}
}
for (i = 0; i < 4; i++)
@@ -225,7 +236,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
route.gw, route.dst_len,
route.metric,
route.iface_name);
- if (bpf_map_lookup_elem(map_fd[0], prefix_key,
+ if (bpf_map_lookup_elem(lpm_map_fd, prefix_key,
prefix_value) < 0) {
for (i = 0; i < 4; i++)
prefix_value->prefix[i] = prefix_key->data[i];
@@ -234,7 +245,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
prefix_value->gw = route.gw;
prefix_value->metric = route.metric;
- assert(bpf_map_update_elem(map_fd[0],
+ assert(bpf_map_update_elem(lpm_map_fd,
prefix_key,
prefix_value, 0
) == 0);
@@ -247,7 +258,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
prefix_key->data[2],
prefix_key->data[3],
prefix_key->prefixlen);
- assert(bpf_map_delete_elem(map_fd[0],
+ assert(bpf_map_delete_elem(lpm_map_fd,
prefix_key
) == 0);
/* Rereading the route table to check if
@@ -275,8 +286,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
prefix_value->ifindex = route.iface;
prefix_value->gw = route.gw;
prefix_value->metric = route.metric;
- assert(bpf_map_update_elem(
- map_fd[0],
+ assert(bpf_map_update_elem(lpm_map_fd,
prefix_key,
prefix_value,
0) == 0);
@@ -401,7 +411,8 @@ static void read_arp(struct nlmsghdr *nh, int nll)
arp_entry.mac = atol(mac);
printf("%x\t\t%llx\n", arp_entry.dst, arp_entry.mac);
if (ndm_family == AF_INET) {
- if (bpf_map_lookup_elem(map_fd[3], &arp_entry.dst,
+ if (bpf_map_lookup_elem(exact_match_map_fd,
+ &arp_entry.dst,
&direct_entry) == 0) {
if (nh->nlmsg_type == RTM_DELNEIGH) {
direct_entry.arp.dst = 0;
@@ -410,16 +421,17 @@ static void read_arp(struct nlmsghdr *nh, int nll)
direct_entry.arp.dst = arp_entry.dst;
direct_entry.arp.mac = arp_entry.mac;
}
- assert(bpf_map_update_elem(map_fd[3],
+ assert(bpf_map_update_elem(exact_match_map_fd,
&arp_entry.dst,
&direct_entry, 0
) == 0);
memset(&direct_entry, 0, sizeof(direct_entry));
}
if (nh->nlmsg_type == RTM_DELNEIGH) {
- assert(bpf_map_delete_elem(map_fd[2], &arp_entry.dst) == 0);
+ assert(bpf_map_delete_elem(arp_table_map_fd,
+ &arp_entry.dst) == 0);
} else if (nh->nlmsg_type == RTM_NEWNEIGH) {
- assert(bpf_map_update_elem(map_fd[2],
+ assert(bpf_map_update_elem(arp_table_map_fd,
&arp_entry.dst,
&arp_entry.mac, 0
) == 0);
@@ -553,7 +565,8 @@ static int monitor_route(void)
for (key = 0; key < nr_keys; key++) {
__u64 sum = 0;
- assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0);
+ assert(bpf_map_lookup_elem(rxcnt_map_fd,
+ &key, values) == 0);
for (i = 0; i < nr_cpus; i++)
sum += (values[i] - prev[key][i]);
if (sum)
@@ -596,11 +609,18 @@ static int monitor_route(void)
int main(int ac, char **argv)
{
+ struct bpf_prog_load_attr prog_load_attr = {
+ .prog_type = BPF_PROG_TYPE_XDP,
+ };
+ struct bpf_object *obj;
char filename[256];
char **ifname_list;
+ int prog_fd;
int i = 1;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+ prog_load_attr.file = filename;
+
if (ac < 2) {
printf("usage: %s [-S] Interface name list\n", argv[0]);
return 1;
@@ -614,15 +634,28 @@ int main(int ac, char **argv)
total_ifindex = ac - 1;
ifname_list = (argv + 1);
}
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+
+ if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
return 1;
- }
+
printf("\n**************loading bpf file*********************\n\n\n");
- if (!prog_fd[0]) {
- printf("load_bpf_file: %s\n", strerror(errno));
+ if (!prog_fd) {
+ printf("bpf_prog_load_xattr: %s\n", strerror(errno));
return 1;
}
+
+ lpm_map_fd = bpf_object__find_map_fd_by_name(obj, "lpm_map");
+ rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt");
+ arp_table_map_fd = bpf_object__find_map_fd_by_name(obj, "arp_table");
+ exact_match_map_fd = bpf_object__find_map_fd_by_name(obj,
+ "exact_match");
+ tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port");
+ if (lpm_map_fd < 0 || rxcnt_map_fd < 0 || arp_table_map_fd < 0 ||
+ exact_match_map_fd < 0 || tx_port_map_fd < 0) {
+ printf("bpf_object__find_map_fd_by_name failed\n");
+ return 1;
+ }
+
ifindex_list = (int *)malloc(total_ifindex * sizeof(int *));
for (i = 0; i < total_ifindex; i++) {
ifindex_list[i] = if_nametoindex(ifname_list[i]);
@@ -633,7 +666,7 @@ int main(int ac, char **argv)
}
}
for (i = 0; i < total_ifindex; i++) {
- if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd[0], flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd, flags) < 0) {
printf("link set xdp fd failed\n");
int recovery_index = i;
diff --git a/samples/bpf/xdp_tx_iptunnel_user.c b/samples/bpf/xdp_tx_iptunnel_user.c
index a4ccc33adac0..5093d8220da5 100644
--- a/samples/bpf/xdp_tx_iptunnel_user.c
+++ b/samples/bpf/xdp_tx_iptunnel_user.c
@@ -17,7 +17,7 @@
#include <netinet/ether.h>
#include <unistd.h>
#include <time.h>
-#include "bpf_load.h"
+#include "bpf/libbpf.h"
#include <bpf/bpf.h>
#include "bpf_util.h"
#include "xdp_tx_iptunnel_common.h"
@@ -26,6 +26,7 @@
static int ifindex = -1;
static __u32 xdp_flags = 0;
+static int rxcnt_map_fd;
static void int_exit(int sig)
{
@@ -53,7 +54,8 @@ static void poll_stats(unsigned int kill_after_s)
for (proto = 0; proto < nr_protos; proto++) {
__u64 sum = 0;
- assert(bpf_map_lookup_elem(map_fd[0], &proto, values) == 0);
+ assert(bpf_map_lookup_elem(rxcnt_map_fd, &proto,
+ values) == 0);
for (i = 0; i < nr_cpus; i++)
sum += (values[i] - prev[proto][i]);
@@ -138,15 +140,19 @@ static int parse_ports(const char *port_str, int *min_port, int *max_port)
int main(int argc, char **argv)
{
+ struct bpf_prog_load_attr prog_load_attr = {
+ .prog_type = BPF_PROG_TYPE_XDP,
+ };
+ struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+ int min_port = 0, max_port = 0, vip2tnl_map_fd;
+ const char *optstr = "i:a:p:s:d:m:T:P:SNh";
unsigned char opt_flags[256] = {};
unsigned int kill_after_s = 0;
- const char *optstr = "i:a:p:s:d:m:T:P:SNh";
- int min_port = 0, max_port = 0;
struct iptnl_info tnl = {};
- struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+ struct bpf_object *obj;
struct vip vip = {};
char filename[256];
- int opt;
+ int opt, prog_fd;
int i;
tnl.family = AF_UNSPEC;
@@ -232,29 +238,36 @@ int main(int argc, char **argv)
}
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+ prog_load_attr.file = filename;
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
return 1;
- }
- if (!prog_fd[0]) {
+ if (!prog_fd) {
printf("load_bpf_file: %s\n", strerror(errno));
return 1;
}
+ rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt");
+ vip2tnl_map_fd = bpf_object__find_map_fd_by_name(obj, "vip2tnl");
+ if (vip2tnl_map_fd < 0 || rxcnt_map_fd < 0) {
+ printf("bpf_object__find_map_fd_by_name failed\n");
+ return 1;
+ }
+
signal(SIGINT, int_exit);
signal(SIGTERM, int_exit);
while (min_port <= max_port) {
vip.dport = htons(min_port++);
- if (bpf_map_update_elem(map_fd[1], &vip, &tnl, BPF_NOEXIST)) {
+ if (bpf_map_update_elem(vip2tnl_map_fd, &vip, &tnl,
+ BPF_NOEXIST)) {
perror("bpf_map_update_elem(&vip2tnl)");
return 1;
}
}
- if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) {
printf("link set xdp fd failed\n");
return 1;
}
--
2.16.1
Powered by blists - more mailing lists