Add an installation-time flag for requesting that the program be installed only if it can be offloaded to HW. Internally new command for ndo_xdp is added, this way we avoid putting checks into drivers since they all return -EINVAL on an unknown command.
Unified · Split
| @@ -807,6 +807,7 @@ enum xdp_netdev_command { · 806 unmodified lines | |||
| 807 | * when it is no longer used. | 807 | * when it is no longer used. |
| 808 | */ | 808 | */ |
| 809 | XDP_SETUP_PROG, | 809 | XDP_SETUP_PROG, |
| 810 | XDP_SETUP_PROG_HW, | ||
| 810 | /* Check if a bpf program is set on the device. The callee should | 811 | /* Check if a bpf program is set on the device. The callee should |
| 811 | * return true if a program is currently attached and running. | 812 | * return true if a program is currently attached and running. |
| 812 | */ | 813 | */ |
| @@ -891,9 +891,12 @@ enum { · 890 unmodified lines | |||
| 891 | #define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0) | 891 | #define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0) |
| 892 | #define XDP_FLAGS_SKB_MODE (1U << 1) | 892 | #define XDP_FLAGS_SKB_MODE (1U << 1) |
| 893 | #define XDP_FLAGS_DRV_MODE (1U << 2) | 893 | #define XDP_FLAGS_DRV_MODE (1U << 2) |
| 894 | #define XDP_FLAGS_HW_MODE (1U << 3) | ||
| 895 | #define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \ | ||
| 896 | XDP_FLAGS_DRV_MODE | \ | ||
| 897 | XDP_FLAGS_HW_MODE) | ||
| 894 | #define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \ | 898 | #define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \ |
| 895 | XDP_FLAGS_SKB_MODE | \ | 899 | XDP_FLAGS_MODES) |
| 896 | XDP_FLAGS_DRV_MODE) | ||
| 897 | 900 | ||
| 898 | /* These are stored into IFLA_XDP_ATTACHED on dump. */ | 901 | /* These are stored into IFLA_XDP_ATTACHED on dump. */ |
| 899 | enum { | 902 | enum { |
| @@ -6957,7 +6957,10 @@ static int dev_xdp_install(struct net_device *dev, xdp_op_t xdp_op, · 6956 unmodified lines | |||
| 6957 | struct netdev_xdp xdp; | 6957 | struct netdev_xdp xdp; |
| 6958 | 6958 | ||
| 6959 | memset(&xdp, 0, sizeof(xdp)); | 6959 | memset(&xdp, 0, sizeof(xdp)); |
| 6960 | xdp.command = XDP_SETUP_PROG; | 6960 | if (flags & XDP_FLAGS_HW_MODE) |
| 6961 | xdp.command = XDP_SETUP_PROG_HW; | ||
| 6962 | else | ||
| 6963 | xdp.command = XDP_SETUP_PROG; | ||
| 6961 | xdp.extack = extack; | 6964 | xdp.extack = extack; |
| 6962 | xdp.flags = flags; | 6965 | xdp.flags = flags; |
| 6963 | xdp.prog = prog; | 6966 | xdp.prog = prog; |
| @@ -6985,7 +6988,7 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack, · 21 unmodified lines | |||
| 6985 | ASSERT_RTNL(); | 6988 | ASSERT_RTNL(); |
| 6986 | 6989 | ||
| 6987 | xdp_op = xdp_chk = ops->ndo_xdp; | 6990 | xdp_op = xdp_chk = ops->ndo_xdp; |
| 6988 | if (!xdp_op && (flags & XDP_FLAGS_DRV_MODE)) | 6991 | if (!xdp_op && (flags & (XDP_FLAGS_DRV_MODE | XDP_FLAGS_HW_MODE))) |
| 6989 | return -EOPNOTSUPP; | 6992 | return -EOPNOTSUPP; |
| 6990 | if (!xdp_op || (flags & XDP_FLAGS_SKB_MODE)) | 6993 | if (!xdp_op || (flags & XDP_FLAGS_SKB_MODE)) |
| 6991 | xdp_op = generic_xdp_install; | 6994 | xdp_op = generic_xdp_install; |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | * Vitaly E. Lavrov RTA_OK arithmetics was wrong. | 16 | * Vitaly E. Lavrov RTA_OK arithmetics was wrong. |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/bitops.h> | ||
| 19 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
| 20 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 21 | #include <linux/types.h> | 22 | #include <linux/types.h> |
| @@ -2253,8 +2254,7 @@ static int do_setlink(const struct sk_buff *skb, · 2231 unmodified lines | |||
| 2253 | err = -EINVAL; | 2254 | err = -EINVAL; |
| 2254 | goto errout; | 2255 | goto errout; |
| 2255 | } | 2256 | } |
| 2256 | if ((xdp_flags & XDP_FLAGS_SKB_MODE) && | 2257 | if (hweight32(xdp_flags & XDP_FLAGS_MODES) > 1) { |
| 2257 | (xdp_flags & XDP_FLAGS_DRV_MODE)) { | ||
| 2258 | err = -EINVAL; | 2258 | err = -EINVAL; |
| 2259 | goto errout; | 2259 | goto errout; |
| 2260 | } | 2260 | } |