diff options
-rw-r--r-- | include/uapi/linux/if_link.h | 6 | ||||
-rw-r--r-- | net/core/dev.c | 2 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 5 | ||||
-rw-r--r-- | samples/bpf/xdp1_user.c | 8 | ||||
-rw-r--r-- | samples/bpf/xdp_tx_iptunnel_user.c | 7 |
5 files changed, 23 insertions, 5 deletions
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 8e56ac70e0d1..549ac8a98b44 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h | |||
@@ -888,9 +888,11 @@ enum { | |||
888 | /* XDP section */ | 888 | /* XDP section */ |
889 | 889 | ||
890 | #define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0) | 890 | #define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0) |
891 | #define XDP_FLAGS_SKB_MODE (2U << 0) | 891 | #define XDP_FLAGS_SKB_MODE (1U << 1) |
892 | #define XDP_FLAGS_DRV_MODE (1U << 2) | ||
892 | #define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \ | 893 | #define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \ |
893 | XDP_FLAGS_SKB_MODE) | 894 | XDP_FLAGS_SKB_MODE | \ |
895 | XDP_FLAGS_DRV_MODE) | ||
894 | 896 | ||
895 | enum { | 897 | enum { |
896 | IFLA_XDP_UNSPEC, | 898 | IFLA_XDP_UNSPEC, |
diff --git a/net/core/dev.c b/net/core/dev.c index 96cf83da0d66..e56cb71351d4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -6873,6 +6873,8 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack, | |||
6873 | ASSERT_RTNL(); | 6873 | ASSERT_RTNL(); |
6874 | 6874 | ||
6875 | xdp_op = ops->ndo_xdp; | 6875 | xdp_op = ops->ndo_xdp; |
6876 | if (!xdp_op && (flags & XDP_FLAGS_DRV_MODE)) | ||
6877 | return -EOPNOTSUPP; | ||
6876 | if (!xdp_op || (flags & XDP_FLAGS_SKB_MODE)) | 6878 | if (!xdp_op || (flags & XDP_FLAGS_SKB_MODE)) |
6877 | xdp_op = generic_xdp_install; | 6879 | xdp_op = generic_xdp_install; |
6878 | 6880 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index bcb0f610ee42..dda9f1636356 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -2199,6 +2199,11 @@ static int do_setlink(const struct sk_buff *skb, | |||
2199 | err = -EINVAL; | 2199 | err = -EINVAL; |
2200 | goto errout; | 2200 | goto errout; |
2201 | } | 2201 | } |
2202 | if ((xdp_flags & XDP_FLAGS_SKB_MODE) && | ||
2203 | (xdp_flags & XDP_FLAGS_DRV_MODE)) { | ||
2204 | err = -EINVAL; | ||
2205 | goto errout; | ||
2206 | } | ||
2202 | } | 2207 | } |
2203 | 2208 | ||
2204 | if (xdp[IFLA_XDP_FD]) { | 2209 | if (xdp[IFLA_XDP_FD]) { |
diff --git a/samples/bpf/xdp1_user.c b/samples/bpf/xdp1_user.c index 378850c70eb8..17be9ea3ecb2 100644 --- a/samples/bpf/xdp1_user.c +++ b/samples/bpf/xdp1_user.c | |||
@@ -62,13 +62,14 @@ static void usage(const char *prog) | |||
62 | fprintf(stderr, | 62 | fprintf(stderr, |
63 | "usage: %s [OPTS] IFINDEX\n\n" | 63 | "usage: %s [OPTS] IFINDEX\n\n" |
64 | "OPTS:\n" | 64 | "OPTS:\n" |
65 | " -S use skb-mode\n", | 65 | " -S use skb-mode\n" |
66 | " -N enforce native mode\n", | ||
66 | prog); | 67 | prog); |
67 | } | 68 | } |
68 | 69 | ||
69 | int main(int argc, char **argv) | 70 | int main(int argc, char **argv) |
70 | { | 71 | { |
71 | const char *optstr = "S"; | 72 | const char *optstr = "SN"; |
72 | char filename[256]; | 73 | char filename[256]; |
73 | int opt; | 74 | int opt; |
74 | 75 | ||
@@ -77,6 +78,9 @@ int main(int argc, char **argv) | |||
77 | case 'S': | 78 | case 'S': |
78 | xdp_flags |= XDP_FLAGS_SKB_MODE; | 79 | xdp_flags |= XDP_FLAGS_SKB_MODE; |
79 | break; | 80 | break; |
81 | case 'N': | ||
82 | xdp_flags |= XDP_FLAGS_DRV_MODE; | ||
83 | break; | ||
80 | default: | 84 | default: |
81 | usage(basename(argv[0])); | 85 | usage(basename(argv[0])); |
82 | return 1; | 86 | return 1; |
diff --git a/samples/bpf/xdp_tx_iptunnel_user.c b/samples/bpf/xdp_tx_iptunnel_user.c index 92b8bde9337c..631cdcc41c97 100644 --- a/samples/bpf/xdp_tx_iptunnel_user.c +++ b/samples/bpf/xdp_tx_iptunnel_user.c | |||
@@ -79,6 +79,8 @@ static void usage(const char *cmd) | |||
79 | printf(" -m <dest-MAC> Used in sending the IP Tunneled pkt\n"); | 79 | printf(" -m <dest-MAC> Used in sending the IP Tunneled pkt\n"); |
80 | printf(" -T <stop-after-X-seconds> Default: 0 (forever)\n"); | 80 | printf(" -T <stop-after-X-seconds> Default: 0 (forever)\n"); |
81 | printf(" -P <IP-Protocol> Default is TCP\n"); | 81 | printf(" -P <IP-Protocol> Default is TCP\n"); |
82 | printf(" -S use skb-mode\n"); | ||
83 | printf(" -N enforce native mode\n"); | ||
82 | printf(" -h Display this help\n"); | 84 | printf(" -h Display this help\n"); |
83 | } | 85 | } |
84 | 86 | ||
@@ -138,7 +140,7 @@ int main(int argc, char **argv) | |||
138 | { | 140 | { |
139 | unsigned char opt_flags[256] = {}; | 141 | unsigned char opt_flags[256] = {}; |
140 | unsigned int kill_after_s = 0; | 142 | unsigned int kill_after_s = 0; |
141 | const char *optstr = "i:a:p:s:d:m:T:P:Sh"; | 143 | const char *optstr = "i:a:p:s:d:m:T:P:SNh"; |
142 | int min_port = 0, max_port = 0; | 144 | int min_port = 0, max_port = 0; |
143 | struct iptnl_info tnl = {}; | 145 | struct iptnl_info tnl = {}; |
144 | struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; | 146 | struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; |
@@ -206,6 +208,9 @@ int main(int argc, char **argv) | |||
206 | case 'S': | 208 | case 'S': |
207 | xdp_flags |= XDP_FLAGS_SKB_MODE; | 209 | xdp_flags |= XDP_FLAGS_SKB_MODE; |
208 | break; | 210 | break; |
211 | case 'N': | ||
212 | xdp_flags |= XDP_FLAGS_DRV_MODE; | ||
213 | break; | ||
209 | default: | 214 | default: |
210 | usage(argv[0]); | 215 | usage(argv[0]); |
211 | return 1; | 216 | return 1; |