Skip to content

Commit

Permalink
samples/bpf: Add support for SKB_MODE to set_link_xdp_fd
Browse files Browse the repository at this point in the history
Based on upstream:
 3993f2cb983b ("samples/bpf: Add support for SKB_MODE to xdp1 and xdp_tx_iptunnel")
 From: David Ahern <dsa@cumulusnetworks.com>

Adjusted to use __u32 instead of signed int, as kernel commit:
 6387d0111ca4 ("samples/bpf: fix SKB_MODE flag to be a 32-bit unsigned int")

Adjust users of set_link_xdp_fd() which now takes a flag.

The --skb-mode flag XDP_FLAGS_SKB_MODE allow enabling the network stack
generic XDP mode, even on NIC that support XDP inside the driver.  This
is practical for testing the overhead associated with invoking the normal
network stack. As described in:

 kernel/Documentation/blogposts/xdp25_eval_generic_xdp_tx.rst
 http://prototype-kernel.readthedocs.io/en/latest/blogposts/xdp25_eval_generic_xdp_tx.html

The Generic XDP for normal net_device's were introduced in
 kernel commit b5cdae3291f7 ("net: Generic XDP")

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
  • Loading branch information
netoptimizer committed May 16, 2017
1 parent 9f3c159 commit a0dfbbc
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 18 deletions.
19 changes: 16 additions & 3 deletions kernel/samples/bpf/bpf_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ struct ksym *ksym_search(long key)
return &syms[0];
}

int set_link_xdp_fd(int ifindex, int fd)
int set_link_xdp_fd(int ifindex, int fd, __u32 flags)
{
struct sockaddr_nl sa;
int sock, seq = 0, len, ret = -1;
Expand Down Expand Up @@ -558,15 +558,28 @@ int set_link_xdp_fd(int ifindex, int fd)
req.nh.nlmsg_seq = ++seq;
req.ifinfo.ifi_family = AF_UNSPEC;
req.ifinfo.ifi_index = ifindex;

/* started nested attribute for XDP */
nla = (struct nlattr *)(((char *)&req)
+ NLMSG_ALIGN(req.nh.nlmsg_len));
nla->nla_type = NLA_F_NESTED | 43/*IFLA_XDP*/;
nla->nla_len = NLA_HDRLEN;

nla_xdp = (struct nlattr *)((char *)nla + NLA_HDRLEN);
/* add XDP fd */
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
nla_xdp->nla_type = 1/*IFLA_XDP_FD*/;
nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
nla->nla_len = NLA_HDRLEN + nla_xdp->nla_len;
nla->nla_len += nla_xdp->nla_len;

/* if user passed in any flags, add those too */
if (flags) {
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
nla_xdp->nla_type = 3/*IFLA_XDP_FLAGS*/;
nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
nla->nla_len += nla_xdp->nla_len;
}

req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);

Expand Down
9 changes: 8 additions & 1 deletion kernel/samples/bpf/bpf_load.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,12 @@ struct ksym {

int load_kallsyms(void);
struct ksym *ksym_search(long key);
int set_link_xdp_fd(int ifindex, int fd);

#ifndef XDP_FLAGS_SKB_MODE
#define XDP_FLAGS_SKB_MODE (2U << 0)
/* Avail in include/uapi/linux/if_link.h
* at kernel commit b5cdae3291f7 ("net: Generic XDP")
*/
#endif
int set_link_xdp_fd(int ifindex, int fd, __u32 flags);
#endif
12 changes: 9 additions & 3 deletions kernel/samples/bpf/xdp_bench01_mem_access_cost_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ static const char *__doc__=
#include <time.h>

#include <arpa/inet.h>
#include <linux/if_link.h>

#include "bpf_load.h"
#include "bpf_util.h"
Expand All @@ -27,6 +28,7 @@ static const char *__doc__=
static int ifindex = -1;
static char ifname_buf[IF_NAMESIZE];
static char *ifname = NULL;
static __u32 xdp_flags = 0;

/* Exit return codes */
#define EXIT_OK 0
Expand All @@ -40,7 +42,7 @@ static void int_exit(int sig)
"Interrupted: Removing XDP program on ifindex:%d device:%s\n",
ifindex, ifname);
if (ifindex > -1)
set_link_xdp_fd(ifindex, -1);
set_link_xdp_fd(ifindex, -1, xdp_flags);
exit(EXIT_OK);
}

Expand All @@ -51,6 +53,7 @@ static const struct option long_options[] = {
{"action", required_argument, NULL, 'a' },
{"readmem", no_argument, NULL, 'r' },
{"swapmac", no_argument, NULL, 'm' },
{"skb-mode", no_argument, NULL, 'S' },
{0, 0, NULL, 0 }
};

Expand Down Expand Up @@ -296,7 +299,7 @@ int main(int argc, char **argv)
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);

/* Parse commands line args */
while ((opt = getopt_long(argc, argv, "hd:s:",
while ((opt = getopt_long(argc, argv, "hSd:s:",
long_options, &longindex)) != -1) {
switch (opt) {
case 'd':
Expand Down Expand Up @@ -327,6 +330,9 @@ int main(int argc, char **argv)
case 'm':
touch_mem |= SWAP_MAC;
break;
case 'S':
xdp_flags |= XDP_FLAGS_SKB_MODE;
break;
case 'h':
error:
default:
Expand Down Expand Up @@ -382,7 +388,7 @@ int main(int argc, char **argv)
/* Remove XDP program when program is interrupted */
signal(SIGINT, int_exit);

if (set_link_xdp_fd(ifindex, prog_fd[0]) < 0) {
if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
fprintf(stderr, "link set xdp fd failed\n");
return EXIT_FAIL_XDP;
}
Expand Down
12 changes: 9 additions & 3 deletions kernel/samples/bpf/xdp_bench02_drop_pattern_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ static const char *__doc__=
#include <time.h>

#include <arpa/inet.h>
#include <linux/if_link.h>

#include "bpf_load.h"
#include "bpf_util.h"
#include "libbpf.h"

static int ifindex = -1;
static __u32 xdp_flags = 0;
static char ifname_buf[IF_NAMESIZE];
static char *ifname = NULL;

Expand All @@ -45,7 +47,7 @@ static void int_exit(int sig)
"Interrupted: Removing XDP program on ifindex:%d device:%s\n",
ifindex, ifname);
if (ifindex > -1)
set_link_xdp_fd(ifindex, -1);
set_link_xdp_fd(ifindex, -1, xdp_flags);
exit(EXIT_OK);
}

Expand All @@ -56,6 +58,7 @@ static const struct option long_options[] = {
{"pattern1", required_argument, NULL, '1' },
{"action", required_argument, NULL, 'a' },
{"notouch", no_argument, NULL, 'n' },
{"skbmode", no_argument, NULL, 'S' },
{0, 0, NULL, 0 }
};

Expand Down Expand Up @@ -362,7 +365,7 @@ int main(int argc, char **argv)
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);

/* Parse commands line args */
while ((opt = getopt_long(argc, argv, "hd:s:",
while ((opt = getopt_long(argc, argv, "hSd:s:",
long_options, &longindex)) != -1) {
switch (opt) {
case 'd':
Expand Down Expand Up @@ -393,6 +396,9 @@ int main(int argc, char **argv)
case 'n':
touch_mem = NO_TOUCH;
break;
case 'S':
xdp_flags |= XDP_FLAGS_SKB_MODE;
break;
case 'h':
error:
default:
Expand Down Expand Up @@ -443,7 +449,7 @@ int main(int argc, char **argv)
/* Remove XDP program when program is interrupted */
signal(SIGINT, int_exit);

if (set_link_xdp_fd(ifindex, prog_fd[0]) < 0) {
if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
fprintf(stderr, "link set xdp fd failed\n");
return EXIT_FAIL_XDP;
}
Expand Down
18 changes: 12 additions & 6 deletions kernel/samples/bpf/xdp_ddos01_blacklist_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static const char *__doc__=
#include <libgen.h> /* dirname */

#include <arpa/inet.h>
#include <linux/if_link.h>

#include "bpf_load.h"
#include "bpf_util.h"
Expand All @@ -44,13 +45,13 @@ static char ifname_buf[IF_NAMESIZE];
static char *ifname = NULL;
static int ifindex = -1;

static void remove_xdp_program(int ifindex, const char *ifname)
static void remove_xdp_program(int ifindex, const char *ifname, __u32 xdp_flags)
{
int i;
fprintf(stderr, "Removing XDP program on ifindex:%d device:%s\n",
ifindex, ifname);
if (ifindex > -1)
set_link_xdp_fd(ifindex, -1);
set_link_xdp_fd(ifindex, -1, xdp_flags);
if (unlink(file_blacklist) < 0) {
printf("WARN: cannot remove map file:%s err(%d):%s\n",
file_blacklist, errno, strerror(errno));
Expand All @@ -77,6 +78,7 @@ static const struct option long_options[] = {
{"dev", required_argument, NULL, 'd' },
{"quite", no_argument, NULL, 'q' },
{"owner", required_argument, NULL, 'o' },
{"skb-mode", no_argument, NULL, 'S' },
{0, 0, NULL, 0 }
};

Expand Down Expand Up @@ -192,20 +194,21 @@ int main(int argc, char **argv)
{
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
bool rm_xdp_prog = false;
struct passwd *pwd = NULL;
__u32 xdp_flags = 0;
char filename[256];
int longindex = 0;
int fd_bpf_prog;
uid_t owner = -1; /* -1 result in now change of owner */
gid_t group = -1;
struct passwd *pwd = NULL;
int res;
int opt;
int i;

snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);

/* Parse commands line args */
while ((opt = getopt_long(argc, argv, "hrqd:",
while ((opt = getopt_long(argc, argv, "hSrqd:",
long_options, &longindex)) != -1) {
switch (opt) {
case 'q':
Expand Down Expand Up @@ -239,6 +242,9 @@ int main(int argc, char **argv)
goto error;
}
break;
case 'S':
xdp_flags |= XDP_FLAGS_SKB_MODE;
break;
case 'h':
error:
default:
Expand All @@ -253,7 +259,7 @@ int main(int argc, char **argv)
return EXIT_FAIL_OPTION;
}
if (rm_xdp_prog) {
remove_xdp_program(ifindex, ifname);
remove_xdp_program(ifindex, ifname, xdp_flags);
return EXIT_OK;
}
if (verbose) {
Expand Down Expand Up @@ -320,7 +326,7 @@ int main(int argc, char **argv)
return 1;
}

if (set_link_xdp_fd(ifindex, prog_fd[0]) < 0) {
if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
printf("link set xdp fd failed\n");
return EXIT_FAIL_XDP;
}
Expand Down
4 changes: 2 additions & 2 deletions kernel/samples/bpf/xdp_ttl_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static void int_exit(int sig)
fprintf(stderr, "Interrupted: Removing XDP program on ifindex:%d\n",
ifindex);
if (ifindex > -1)
set_link_xdp_fd(ifindex, -1);
set_link_xdp_fd(ifindex, -1, 0);
exit(0);
}

Expand Down Expand Up @@ -192,7 +192,7 @@ int main(int argc, char **argv)
/* Remove XDP program when program is interrupted */
signal(SIGINT, int_exit);

if (set_link_xdp_fd(ifindex, prog_fd[0]) < 0) {
if (set_link_xdp_fd(ifindex, prog_fd[0], 0) < 0) {
printf("link set xdp fd failed\n");
return EXIT_FAIL_XDP;
}
Expand Down

0 comments on commit a0dfbbc

Please sign in to comment.