mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
bpf, xdp: move offload check into dev_xdp_install()
bpf_xdp_link_update() calls dev_xdp_install() directly and skips
dev_xdp_attach(), so the checks in dev_xdp_attach() do not run. A user can
make an XDP link with a normal program and then swap in an offloaded or
device-bound program with BPF_LINK_UPDATE, which puts it on the software
path.
dev_xdp_install() is the one place all three paths go through:
"ip link set xdp" and BPF_LINK_CREATE reach it via dev_xdp_attach(), and
BPF_LINK_UPDATE calls it directly. So move the program checks (offloaded,
bound to another device, device-bound in generic mode, native vs generic,
DEVMAP and CPUMAP) there, and keep only the netlink-flag check
(XDP_FLAGS_UPDATE_IF_NOEXIST) in dev_xdp_attach().
Fixes: 026a4c28e1 ("bpf, xdp: Implement LINK_UPDATE for BPF XDP link")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
24ef02f934
commit
ad27ed7d23
|
|
@ -10333,6 +10333,37 @@ static int dev_xdp_install(struct net_device *dev, enum bpf_xdp_mode mode,
|
|||
|
||||
netdev_assert_locked_ops_compat(dev);
|
||||
|
||||
if (prog) {
|
||||
enum bpf_xdp_mode other_mode = mode == XDP_MODE_SKB
|
||||
? XDP_MODE_DRV : XDP_MODE_SKB;
|
||||
bool offload = mode == XDP_MODE_HW;
|
||||
|
||||
if (!offload && dev_xdp_prog(dev, other_mode)) {
|
||||
NL_SET_ERR_MSG(extack, "Native and generic XDP can't be active at the same time");
|
||||
return -EEXIST;
|
||||
}
|
||||
if (!offload && bpf_prog_is_offloaded(prog->aux)) {
|
||||
NL_SET_ERR_MSG(extack, "Using offloaded program without HW_MODE flag is not supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bpf_prog_is_dev_bound(prog->aux) && !bpf_offload_dev_match(prog, dev)) {
|
||||
NL_SET_ERR_MSG(extack, "Program bound to different device");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bpf_prog_is_dev_bound(prog->aux) && mode == XDP_MODE_SKB) {
|
||||
NL_SET_ERR_MSG(extack, "Can't attach device-bound programs in generic mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (prog->expected_attach_type == BPF_XDP_DEVMAP) {
|
||||
NL_SET_ERR_MSG(extack, "BPF_XDP_DEVMAP programs can not be attached to a device");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (prog->expected_attach_type == BPF_XDP_CPUMAP) {
|
||||
NL_SET_ERR_MSG(extack, "BPF_XDP_CPUMAP programs can not be attached to a device");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->cfg->hds_config == ETHTOOL_TCP_DATA_SPLIT_ENABLED &&
|
||||
prog && !prog->aux->xdp_has_frags) {
|
||||
NL_SET_ERR_MSG(extack, "unable to install XDP to device using tcp-data-split");
|
||||
|
|
@ -10472,38 +10503,10 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
|
|||
new_prog = link->link.prog;
|
||||
|
||||
if (new_prog) {
|
||||
bool offload = mode == XDP_MODE_HW;
|
||||
enum bpf_xdp_mode other_mode = mode == XDP_MODE_SKB
|
||||
? XDP_MODE_DRV : XDP_MODE_SKB;
|
||||
|
||||
if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST) && cur_prog) {
|
||||
NL_SET_ERR_MSG(extack, "XDP program already attached");
|
||||
return -EBUSY;
|
||||
}
|
||||
if (!offload && dev_xdp_prog(dev, other_mode)) {
|
||||
NL_SET_ERR_MSG(extack, "Native and generic XDP can't be active at the same time");
|
||||
return -EEXIST;
|
||||
}
|
||||
if (!offload && bpf_prog_is_offloaded(new_prog->aux)) {
|
||||
NL_SET_ERR_MSG(extack, "Using offloaded program without HW_MODE flag is not supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bpf_prog_is_dev_bound(new_prog->aux) && !bpf_offload_dev_match(new_prog, dev)) {
|
||||
NL_SET_ERR_MSG(extack, "Program bound to different device");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bpf_prog_is_dev_bound(new_prog->aux) && mode == XDP_MODE_SKB) {
|
||||
NL_SET_ERR_MSG(extack, "Can't attach device-bound programs in generic mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (new_prog->expected_attach_type == BPF_XDP_DEVMAP) {
|
||||
NL_SET_ERR_MSG(extack, "BPF_XDP_DEVMAP programs can not be attached to a device");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (new_prog->expected_attach_type == BPF_XDP_CPUMAP) {
|
||||
NL_SET_ERR_MSG(extack, "BPF_XDP_CPUMAP programs can not be attached to a device");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* don't call drivers if the effective program didn't change */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user