提交 0489df9a 编写于 作者: D Daniel Borkmann 提交者: David S. Miller

xdp: add flag to enforce driver mode

After commit b5cdae32 ("net: Generic XDP") we automatically fall
back to a generic XDP variant if the driver does not support native
XDP. Allow for an option where the user can specify that always the
native XDP variant should be selected and in case it's not supported
by a driver, just bail out.
Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
Acked-by: NAlexei Starovoitov <ast@kernel.org>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 0a5539f6
...@@ -888,9 +888,11 @@ enum { ...@@ -888,9 +888,11 @@ enum {
/* XDP section */ /* XDP section */
#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0) #define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0)
#define XDP_FLAGS_SKB_MODE (2U << 0) #define XDP_FLAGS_SKB_MODE (1U << 1)
#define XDP_FLAGS_DRV_MODE (1U << 2)
#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \ #define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \
XDP_FLAGS_SKB_MODE) XDP_FLAGS_SKB_MODE | \
XDP_FLAGS_DRV_MODE)
enum { enum {
IFLA_XDP_UNSPEC, IFLA_XDP_UNSPEC,
......
...@@ -6873,6 +6873,8 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack, ...@@ -6873,6 +6873,8 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
ASSERT_RTNL(); ASSERT_RTNL();
xdp_op = ops->ndo_xdp; xdp_op = ops->ndo_xdp;
if (!xdp_op && (flags & XDP_FLAGS_DRV_MODE))
return -EOPNOTSUPP;
if (!xdp_op || (flags & XDP_FLAGS_SKB_MODE)) if (!xdp_op || (flags & XDP_FLAGS_SKB_MODE))
xdp_op = generic_xdp_install; xdp_op = generic_xdp_install;
......
...@@ -2199,6 +2199,11 @@ static int do_setlink(const struct sk_buff *skb, ...@@ -2199,6 +2199,11 @@ static int do_setlink(const struct sk_buff *skb,
err = -EINVAL; err = -EINVAL;
goto errout; goto errout;
} }
if ((xdp_flags & XDP_FLAGS_SKB_MODE) &&
(xdp_flags & XDP_FLAGS_DRV_MODE)) {
err = -EINVAL;
goto errout;
}
} }
if (xdp[IFLA_XDP_FD]) { if (xdp[IFLA_XDP_FD]) {
......
...@@ -62,13 +62,14 @@ static void usage(const char *prog) ...@@ -62,13 +62,14 @@ static void usage(const char *prog)
fprintf(stderr, fprintf(stderr,
"usage: %s [OPTS] IFINDEX\n\n" "usage: %s [OPTS] IFINDEX\n\n"
"OPTS:\n" "OPTS:\n"
" -S use skb-mode\n", " -S use skb-mode\n"
" -N enforce native mode\n",
prog); prog);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
const char *optstr = "S"; const char *optstr = "SN";
char filename[256]; char filename[256];
int opt; int opt;
...@@ -77,6 +78,9 @@ int main(int argc, char **argv) ...@@ -77,6 +78,9 @@ int main(int argc, char **argv)
case 'S': case 'S':
xdp_flags |= XDP_FLAGS_SKB_MODE; xdp_flags |= XDP_FLAGS_SKB_MODE;
break; break;
case 'N':
xdp_flags |= XDP_FLAGS_DRV_MODE;
break;
default: default:
usage(basename(argv[0])); usage(basename(argv[0]));
return 1; return 1;
......
...@@ -79,6 +79,8 @@ static void usage(const char *cmd) ...@@ -79,6 +79,8 @@ static void usage(const char *cmd)
printf(" -m <dest-MAC> Used in sending the IP Tunneled pkt\n"); printf(" -m <dest-MAC> Used in sending the IP Tunneled pkt\n");
printf(" -T <stop-after-X-seconds> Default: 0 (forever)\n"); printf(" -T <stop-after-X-seconds> Default: 0 (forever)\n");
printf(" -P <IP-Protocol> Default is TCP\n"); printf(" -P <IP-Protocol> Default is TCP\n");
printf(" -S use skb-mode\n");
printf(" -N enforce native mode\n");
printf(" -h Display this help\n"); printf(" -h Display this help\n");
} }
...@@ -138,7 +140,7 @@ int main(int argc, char **argv) ...@@ -138,7 +140,7 @@ int main(int argc, char **argv)
{ {
unsigned char opt_flags[256] = {}; unsigned char opt_flags[256] = {};
unsigned int kill_after_s = 0; unsigned int kill_after_s = 0;
const char *optstr = "i:a:p:s:d:m:T:P:Sh"; const char *optstr = "i:a:p:s:d:m:T:P:SNh";
int min_port = 0, max_port = 0; int min_port = 0, max_port = 0;
struct iptnl_info tnl = {}; struct iptnl_info tnl = {};
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
...@@ -206,6 +208,9 @@ int main(int argc, char **argv) ...@@ -206,6 +208,9 @@ int main(int argc, char **argv)
case 'S': case 'S':
xdp_flags |= XDP_FLAGS_SKB_MODE; xdp_flags |= XDP_FLAGS_SKB_MODE;
break; break;
case 'N':
xdp_flags |= XDP_FLAGS_DRV_MODE;
break;
default: default:
usage(argv[0]); usage(argv[0]);
return 1; return 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册