bpf, xdp: allow to pass flags to dev_change_xdp_fd
Add an IFLA_XDP_FLAGS attribute that can be passed for setting up XDP along with IFLA_XDP_FD, which eventually allows user space to implement typical add/replace/delete logic for programs. Right now, calling into dev_change_xdp_fd() will always replace previous programs. When passed XDP_FLAGS_UPDATE_IF_NOEXIST, we can handle this more graceful when requested by returning -EBUSY in case we try to attach a new program, but we find that another one is already attached. This will be used by upcoming front-end for iproute2 as well. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
0f29f05bd7
commit
85de8576a0
@@ -6692,26 +6692,42 @@ EXPORT_SYMBOL(dev_change_proto_down);
|
||||
* dev_change_xdp_fd - set or clear a bpf program for a device rx path
|
||||
* @dev: device
|
||||
* @fd: new program fd or negative value to clear
|
||||
* @flags: xdp-related flags
|
||||
*
|
||||
* Set or clear a bpf program for a device
|
||||
*/
|
||||
int dev_change_xdp_fd(struct net_device *dev, int fd)
|
||||
int dev_change_xdp_fd(struct net_device *dev, int fd, u32 flags)
|
||||
{
|
||||
const struct net_device_ops *ops = dev->netdev_ops;
|
||||
struct bpf_prog *prog = NULL;
|
||||
struct netdev_xdp xdp = {};
|
||||
struct netdev_xdp xdp;
|
||||
int err;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (!ops->ndo_xdp)
|
||||
return -EOPNOTSUPP;
|
||||
if (fd >= 0) {
|
||||
if (flags & XDP_FLAGS_UPDATE_IF_NOEXIST) {
|
||||
memset(&xdp, 0, sizeof(xdp));
|
||||
xdp.command = XDP_QUERY_PROG;
|
||||
|
||||
err = ops->ndo_xdp(dev, &xdp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (xdp.prog_attached)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_XDP);
|
||||
if (IS_ERR(prog))
|
||||
return PTR_ERR(prog);
|
||||
}
|
||||
|
||||
memset(&xdp, 0, sizeof(xdp));
|
||||
xdp.command = XDP_SETUP_PROG;
|
||||
xdp.prog = prog;
|
||||
|
||||
err = ops->ndo_xdp(dev, &xdp);
|
||||
if (err < 0 && prog)
|
||||
bpf_prog_put(prog);
|
||||
|
Reference in New Issue
Block a user