Commit 743e568c authored by Maciej Fijalkowski's avatar Maciej Fijalkowski Committed by Daniel Borkmann

samples/bpf: Add a "force" flag to XDP samples

Make xdp samples consistent with iproute2 behavior and set the
XDP_FLAGS_UPDATE_IF_NOEXIST by default when setting the xdp program on
interface. Provide an option for user to force the program loading,
which as a result will not include the mentioned flag in
bpf_set_link_xdp_fd call.
Signed-off-by: default avatarMaciej Fijalkowski <maciej.fijalkowski@intel.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 01dde20c
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "bpf/libbpf.h" #include "bpf/libbpf.h"
static int ifindex; static int ifindex;
static __u32 xdp_flags; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static void int_exit(int sig) static void int_exit(int sig)
{ {
...@@ -63,7 +63,8 @@ static void usage(const char *prog) ...@@ -63,7 +63,8 @@ static void usage(const char *prog)
"usage: %s [OPTS] IFACE\n\n" "usage: %s [OPTS] IFACE\n\n"
"OPTS:\n" "OPTS:\n"
" -S use skb-mode\n" " -S use skb-mode\n"
" -N enforce native mode\n", " -N enforce native mode\n"
" -F force loading prog\n",
prog); prog);
} }
...@@ -73,7 +74,7 @@ int main(int argc, char **argv) ...@@ -73,7 +74,7 @@ int main(int argc, char **argv)
struct bpf_prog_load_attr prog_load_attr = { struct bpf_prog_load_attr prog_load_attr = {
.prog_type = BPF_PROG_TYPE_XDP, .prog_type = BPF_PROG_TYPE_XDP,
}; };
const char *optstr = "SN"; const char *optstr = "FSN";
int prog_fd, map_fd, opt; int prog_fd, map_fd, opt;
struct bpf_object *obj; struct bpf_object *obj;
struct bpf_map *map; struct bpf_map *map;
...@@ -87,6 +88,9 @@ int main(int argc, char **argv) ...@@ -87,6 +88,9 @@ int main(int argc, char **argv)
case 'N': case 'N':
xdp_flags |= XDP_FLAGS_DRV_MODE; xdp_flags |= XDP_FLAGS_DRV_MODE;
break; break;
case 'F':
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
break;
default: default:
usage(basename(argv[0])); usage(basename(argv[0]));
return 1; return 1;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#define STATS_INTERVAL_S 2U #define STATS_INTERVAL_S 2U
static int ifindex = -1; static int ifindex = -1;
static __u32 xdp_flags; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static void int_exit(int sig) static void int_exit(int sig)
{ {
...@@ -60,6 +60,7 @@ static void usage(const char *cmd) ...@@ -60,6 +60,7 @@ static void usage(const char *cmd)
printf(" -T <stop-after-X-seconds> Default: 0 (forever)\n"); printf(" -T <stop-after-X-seconds> Default: 0 (forever)\n");
printf(" -S use skb-mode\n"); printf(" -S use skb-mode\n");
printf(" -N enforce native mode\n"); printf(" -N enforce native mode\n");
printf(" -F force loading prog\n");
printf(" -h Display this help\n"); printf(" -h Display this help\n");
} }
...@@ -70,8 +71,8 @@ int main(int argc, char **argv) ...@@ -70,8 +71,8 @@ int main(int argc, char **argv)
.prog_type = BPF_PROG_TYPE_XDP, .prog_type = BPF_PROG_TYPE_XDP,
}; };
unsigned char opt_flags[256] = {}; unsigned char opt_flags[256] = {};
const char *optstr = "i:T:SNFh";
unsigned int kill_after_s = 0; unsigned int kill_after_s = 0;
const char *optstr = "i:T:SNh";
int i, prog_fd, map_fd, opt; int i, prog_fd, map_fd, opt;
struct bpf_object *obj; struct bpf_object *obj;
struct bpf_map *map; struct bpf_map *map;
...@@ -96,6 +97,9 @@ int main(int argc, char **argv) ...@@ -96,6 +97,9 @@ int main(int argc, char **argv)
case 'N': case 'N':
xdp_flags |= XDP_FLAGS_DRV_MODE; xdp_flags |= XDP_FLAGS_DRV_MODE;
break; break;
case 'F':
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
break;
default: default:
usage(argv[0]); usage(argv[0]);
return 1; return 1;
......
...@@ -33,7 +33,7 @@ static int ifindex = -1; ...@@ -33,7 +33,7 @@ static int ifindex = -1;
static char ifname_buf[IF_NAMESIZE]; static char ifname_buf[IF_NAMESIZE];
static char *ifname; static char *ifname;
static __u32 xdp_flags; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static int cpu_map_fd; static int cpu_map_fd;
static int rx_cnt_map_fd; static int rx_cnt_map_fd;
static int redirect_err_cnt_map_fd; static int redirect_err_cnt_map_fd;
...@@ -62,6 +62,7 @@ static const struct option long_options[] = { ...@@ -62,6 +62,7 @@ static const struct option long_options[] = {
{"cpu", required_argument, NULL, 'c' }, {"cpu", required_argument, NULL, 'c' },
{"stress-mode", no_argument, NULL, 'x' }, {"stress-mode", no_argument, NULL, 'x' },
{"no-separators", no_argument, NULL, 'z' }, {"no-separators", no_argument, NULL, 'z' },
{"force", no_argument, NULL, 'F' },
{0, 0, NULL, 0 } {0, 0, NULL, 0 }
}; };
...@@ -651,7 +652,7 @@ int main(int argc, char **argv) ...@@ -651,7 +652,7 @@ int main(int argc, char **argv)
mark_cpus_unavailable(); mark_cpus_unavailable();
/* Parse commands line args */ /* Parse commands line args */
while ((opt = getopt_long(argc, argv, "hSd:", while ((opt = getopt_long(argc, argv, "hSd:s:p:q:c:xzF",
long_options, &longindex)) != -1) { long_options, &longindex)) != -1) {
switch (opt) { switch (opt) {
case 'd': case 'd':
...@@ -700,6 +701,9 @@ int main(int argc, char **argv) ...@@ -700,6 +701,9 @@ int main(int argc, char **argv)
case 'q': case 'q':
qsize = atoi(optarg); qsize = atoi(optarg);
break; break;
case 'F':
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
break;
case 'h': case 'h':
error: error:
default: default:
......
...@@ -30,7 +30,7 @@ static int ifindex_in; ...@@ -30,7 +30,7 @@ static int ifindex_in;
static int ifindex_out; static int ifindex_out;
static bool ifindex_out_xdp_dummy_attached = true; static bool ifindex_out_xdp_dummy_attached = true;
static __u32 xdp_flags; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static int rxcnt_map_fd; static int rxcnt_map_fd;
static void int_exit(int sig) static void int_exit(int sig)
...@@ -70,7 +70,8 @@ static void usage(const char *prog) ...@@ -70,7 +70,8 @@ static void usage(const char *prog)
"usage: %s [OPTS] IFINDEX_IN IFINDEX_OUT\n\n" "usage: %s [OPTS] IFINDEX_IN IFINDEX_OUT\n\n"
"OPTS:\n" "OPTS:\n"
" -S use skb-mode\n" " -S use skb-mode\n"
" -N enforce native mode\n", " -N enforce native mode\n"
" -F force loading prog\n",
prog); prog);
} }
...@@ -82,7 +83,7 @@ int main(int argc, char **argv) ...@@ -82,7 +83,7 @@ int main(int argc, char **argv)
}; };
struct bpf_program *prog, *dummy_prog; struct bpf_program *prog, *dummy_prog;
int prog_fd, dummy_prog_fd; int prog_fd, dummy_prog_fd;
const char *optstr = "SN"; const char *optstr = "FSN";
struct bpf_object *obj; struct bpf_object *obj;
int ret, opt, key = 0; int ret, opt, key = 0;
char filename[256]; char filename[256];
...@@ -96,6 +97,9 @@ int main(int argc, char **argv) ...@@ -96,6 +97,9 @@ int main(int argc, char **argv)
case 'N': case 'N':
xdp_flags |= XDP_FLAGS_DRV_MODE; xdp_flags |= XDP_FLAGS_DRV_MODE;
break; break;
case 'F':
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
break;
default: default:
usage(basename(argv[0])); usage(basename(argv[0]));
return 1; return 1;
......
...@@ -30,7 +30,7 @@ static int ifindex_in; ...@@ -30,7 +30,7 @@ static int ifindex_in;
static int ifindex_out; static int ifindex_out;
static bool ifindex_out_xdp_dummy_attached = true; static bool ifindex_out_xdp_dummy_attached = true;
static __u32 xdp_flags; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static int rxcnt_map_fd; static int rxcnt_map_fd;
static void int_exit(int sig) static void int_exit(int sig)
...@@ -70,7 +70,8 @@ static void usage(const char *prog) ...@@ -70,7 +70,8 @@ static void usage(const char *prog)
"usage: %s [OPTS] IFINDEX_IN IFINDEX_OUT\n\n" "usage: %s [OPTS] IFINDEX_IN IFINDEX_OUT\n\n"
"OPTS:\n" "OPTS:\n"
" -S use skb-mode\n" " -S use skb-mode\n"
" -N enforce native mode\n", " -N enforce native mode\n"
" -F force loading prog\n",
prog); prog);
} }
...@@ -83,7 +84,7 @@ int main(int argc, char **argv) ...@@ -83,7 +84,7 @@ int main(int argc, char **argv)
}; };
struct bpf_program *prog, *dummy_prog; struct bpf_program *prog, *dummy_prog;
int prog_fd, tx_port_map_fd, opt; int prog_fd, tx_port_map_fd, opt;
const char *optstr = "SN"; const char *optstr = "FSN";
struct bpf_object *obj; struct bpf_object *obj;
char filename[256]; char filename[256];
int dummy_prog_fd; int dummy_prog_fd;
...@@ -97,6 +98,9 @@ int main(int argc, char **argv) ...@@ -97,6 +98,9 @@ int main(int argc, char **argv)
case 'N': case 'N':
xdp_flags |= XDP_FLAGS_DRV_MODE; xdp_flags |= XDP_FLAGS_DRV_MODE;
break; break;
case 'F':
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
break;
default: default:
usage(basename(argv[0])); usage(basename(argv[0]));
return 1; return 1;
......
...@@ -26,8 +26,9 @@ ...@@ -26,8 +26,9 @@
#include "bpf_util.h" #include "bpf_util.h"
#include "bpf/libbpf.h" #include "bpf/libbpf.h"
#include <sys/resource.h> #include <sys/resource.h>
#include <libgen.h>
int sock, sock_arp, flags = 0; int sock, sock_arp, flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static int total_ifindex; static int total_ifindex;
int *ifindex_list; int *ifindex_list;
char buf[8192]; char buf[8192];
...@@ -608,33 +609,56 @@ static int monitor_route(void) ...@@ -608,33 +609,56 @@ static int monitor_route(void)
return ret; return ret;
} }
static void usage(const char *prog)
{
fprintf(stderr,
"%s: %s [OPTS] interface name list\n\n"
"OPTS:\n"
" -S use skb-mode\n"
" -F force loading prog\n",
__func__, prog);
}
int main(int ac, char **argv) int main(int ac, char **argv)
{ {
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
struct bpf_prog_load_attr prog_load_attr = { struct bpf_prog_load_attr prog_load_attr = {
.prog_type = BPF_PROG_TYPE_XDP, .prog_type = BPF_PROG_TYPE_XDP,
}; };
const char *optstr = "SF";
struct bpf_object *obj; struct bpf_object *obj;
char filename[256]; char filename[256];
char **ifname_list; char **ifname_list;
int prog_fd; int prog_fd, opt;
int i = 1; int i = 1;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
prog_load_attr.file = filename; prog_load_attr.file = filename;
if (ac < 2) { total_ifindex = ac - 1;
printf("usage: %s [-S] Interface name list\n", argv[0]); ifname_list = (argv + 1);
return 1;
while ((opt = getopt(ac, argv, optstr)) != -1) {
switch (opt) {
case 'S':
flags |= XDP_FLAGS_SKB_MODE;
total_ifindex--;
ifname_list++;
break;
case 'F':
flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
total_ifindex--;
ifname_list++;
break;
default:
usage(basename(argv[0]));
return 1;
}
} }
if (!strcmp(argv[1], "-S")) {
flags = XDP_FLAGS_SKB_MODE; if (optind == ac) {
total_ifindex = ac - 2; usage(basename(argv[0]));
ifname_list = (argv + 2); return 1;
} else {
flags = 0;
total_ifindex = ac - 1;
ifname_list = (argv + 1);
} }
if (setrlimit(RLIMIT_MEMLOCK, &r)) { if (setrlimit(RLIMIT_MEMLOCK, &r)) {
......
...@@ -30,7 +30,7 @@ static int ifindex = -1; ...@@ -30,7 +30,7 @@ static int ifindex = -1;
static char ifname_buf[IF_NAMESIZE]; static char ifname_buf[IF_NAMESIZE];
static char *ifname; static char *ifname;
static __u32 xdp_flags; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static struct bpf_map *stats_global_map; static struct bpf_map *stats_global_map;
static struct bpf_map *rx_queue_index_map; static struct bpf_map *rx_queue_index_map;
...@@ -52,6 +52,7 @@ static const struct option long_options[] = { ...@@ -52,6 +52,7 @@ static const struct option long_options[] = {
{"action", required_argument, NULL, 'a' }, {"action", required_argument, NULL, 'a' },
{"readmem", no_argument, NULL, 'r' }, {"readmem", no_argument, NULL, 'r' },
{"swapmac", no_argument, NULL, 'm' }, {"swapmac", no_argument, NULL, 'm' },
{"force", no_argument, NULL, 'F' },
{0, 0, NULL, 0 } {0, 0, NULL, 0 }
}; };
...@@ -487,7 +488,7 @@ int main(int argc, char **argv) ...@@ -487,7 +488,7 @@ int main(int argc, char **argv)
} }
/* Parse commands line args */ /* Parse commands line args */
while ((opt = getopt_long(argc, argv, "hSd:", while ((opt = getopt_long(argc, argv, "FhSrmzd:s:a:",
long_options, &longindex)) != -1) { long_options, &longindex)) != -1) {
switch (opt) { switch (opt) {
case 'd': case 'd':
...@@ -524,6 +525,9 @@ int main(int argc, char **argv) ...@@ -524,6 +525,9 @@ int main(int argc, char **argv)
case 'm': case 'm':
cfg_options |= SWAP_MAC; cfg_options |= SWAP_MAC;
break; break;
case 'F':
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
break;
case 'h': case 'h':
error: error:
default: default:
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include <libbpf.h> #include <libbpf.h>
#include <bpf/bpf.h> #include <bpf/bpf.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <libgen.h>
#include <linux/if_link.h>
#include "perf-sys.h" #include "perf-sys.h"
#include "trace_helpers.h" #include "trace_helpers.h"
...@@ -21,12 +23,13 @@ ...@@ -21,12 +23,13 @@
static int pmu_fds[MAX_CPUS], if_idx; static int pmu_fds[MAX_CPUS], if_idx;
static struct perf_event_mmap_page *headers[MAX_CPUS]; static struct perf_event_mmap_page *headers[MAX_CPUS];
static char *if_name; static char *if_name;
static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static int do_attach(int idx, int fd, const char *name) static int do_attach(int idx, int fd, const char *name)
{ {
int err; int err;
err = bpf_set_link_xdp_fd(idx, fd, 0); err = bpf_set_link_xdp_fd(idx, fd, xdp_flags);
if (err < 0) if (err < 0)
printf("ERROR: failed to attach program to %s\n", name); printf("ERROR: failed to attach program to %s\n", name);
...@@ -98,21 +101,42 @@ static void sig_handler(int signo) ...@@ -98,21 +101,42 @@ static void sig_handler(int signo)
exit(0); exit(0);
} }
static void usage(const char *prog)
{
fprintf(stderr,
"%s: %s [OPTS] <ifname|ifindex>\n\n"
"OPTS:\n"
" -F force loading prog\n",
__func__, prog);
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
struct bpf_prog_load_attr prog_load_attr = { struct bpf_prog_load_attr prog_load_attr = {
.prog_type = BPF_PROG_TYPE_XDP, .prog_type = BPF_PROG_TYPE_XDP,
}; };
const char *optstr = "F";
int prog_fd, map_fd, opt;
struct bpf_object *obj; struct bpf_object *obj;
struct bpf_map *map; struct bpf_map *map;
int prog_fd, map_fd;
char filename[256]; char filename[256];
int ret, err, i; int ret, err, i;
int numcpus; int numcpus;
if (argc < 2) { while ((opt = getopt(argc, argv, optstr)) != -1) {
printf("Usage: %s <ifname>\n", argv[0]); switch (opt) {
case 'F':
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
break;
default:
usage(basename(argv[0]));
return 1;
}
}
if (optind == argc) {
usage(basename(argv[0]));
return 1; return 1;
} }
...@@ -143,16 +167,16 @@ int main(int argc, char **argv) ...@@ -143,16 +167,16 @@ int main(int argc, char **argv)
} }
map_fd = bpf_map__fd(map); map_fd = bpf_map__fd(map);
if_idx = if_nametoindex(argv[1]); if_idx = if_nametoindex(argv[optind]);
if (!if_idx) if (!if_idx)
if_idx = strtoul(argv[1], NULL, 0); if_idx = strtoul(argv[optind], NULL, 0);
if (!if_idx) { if (!if_idx) {
fprintf(stderr, "Invalid ifname\n"); fprintf(stderr, "Invalid ifname\n");
return 1; return 1;
} }
if_name = argv[1]; if_name = argv[optind];
err = do_attach(if_idx, prog_fd, argv[1]); err = do_attach(if_idx, prog_fd, if_name);
if (err) if (err)
return err; return err;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#define STATS_INTERVAL_S 2U #define STATS_INTERVAL_S 2U
static int ifindex = -1; static int ifindex = -1;
static __u32 xdp_flags = 0; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static int rxcnt_map_fd; static int rxcnt_map_fd;
static void int_exit(int sig) static void int_exit(int sig)
...@@ -83,6 +83,7 @@ static void usage(const char *cmd) ...@@ -83,6 +83,7 @@ static void usage(const char *cmd)
printf(" -P <IP-Protocol> Default is TCP\n"); printf(" -P <IP-Protocol> Default is TCP\n");
printf(" -S use skb-mode\n"); printf(" -S use skb-mode\n");
printf(" -N enforce native mode\n"); printf(" -N enforce native mode\n");
printf(" -F Force loading the XDP prog\n");
printf(" -h Display this help\n"); printf(" -h Display this help\n");
} }
...@@ -145,7 +146,7 @@ int main(int argc, char **argv) ...@@ -145,7 +146,7 @@ int main(int argc, char **argv)
}; };
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
int min_port = 0, max_port = 0, vip2tnl_map_fd; int min_port = 0, max_port = 0, vip2tnl_map_fd;
const char *optstr = "i:a:p:s:d:m:T:P:SNh"; const char *optstr = "i:a:p:s:d:m:T:P:FSNh";
unsigned char opt_flags[256] = {}; unsigned char opt_flags[256] = {};
unsigned int kill_after_s = 0; unsigned int kill_after_s = 0;
struct iptnl_info tnl = {}; struct iptnl_info tnl = {};
...@@ -217,6 +218,9 @@ int main(int argc, char **argv) ...@@ -217,6 +218,9 @@ int main(int argc, char **argv)
case 'N': case 'N':
xdp_flags |= XDP_FLAGS_DRV_MODE; xdp_flags |= XDP_FLAGS_DRV_MODE;
break; break;
case 'F':
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
break;
default: default:
usage(argv[0]); usage(argv[0]);
return 1; return 1;
......
...@@ -68,7 +68,7 @@ enum benchmark_type { ...@@ -68,7 +68,7 @@ enum benchmark_type {
}; };
static enum benchmark_type opt_bench = BENCH_RXDROP; static enum benchmark_type opt_bench = BENCH_RXDROP;
static u32 opt_xdp_flags; static u32 opt_xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static const char *opt_if = ""; static const char *opt_if = "";
static int opt_ifindex; static int opt_ifindex;
static int opt_queue; static int opt_queue;
...@@ -682,7 +682,7 @@ static void parse_command_line(int argc, char **argv) ...@@ -682,7 +682,7 @@ static void parse_command_line(int argc, char **argv)
opterr = 0; opterr = 0;
for (;;) { for (;;) {
c = getopt_long(argc, argv, "rtli:q:psSNn:cz", long_options, c = getopt_long(argc, argv, "Frtli:q:psSNn:cz", long_options,
&option_index); &option_index);
if (c == -1) if (c == -1)
break; break;
...@@ -725,6 +725,9 @@ static void parse_command_line(int argc, char **argv) ...@@ -725,6 +725,9 @@ static void parse_command_line(int argc, char **argv)
case 'c': case 'c':
opt_xdp_bind_flags |= XDP_COPY; opt_xdp_bind_flags |= XDP_COPY;
break; break;
case 'F':
opt_xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
break;
default: default:
usage(basename(argv[0])); usage(basename(argv[0]));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment