net: add ndo to setup/query xdp prog in adapter rx
Add one new netdev op for drivers implementing the BPF_PROG_TYPE_XDP filter. The single op is used for both setup/query of the xdp program, modelled after ndo_setup_tc. Change-Id: Ie46dec0b47e417e97d5fed19d7f2b143eab4ea73 Signed-off-by: Brenden Blanco <bblanco@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
Asriadi Rahim
parent
20d86f5283
commit
6fdce8a496
@@ -60,6 +60,7 @@ struct wireless_dev;
|
||||
/* 802.15.4 specific */
|
||||
struct wpan_dev;
|
||||
struct mpls_dev;
|
||||
struct bpf_prog;
|
||||
|
||||
void netdev_set_default_ethtool_ops(struct net_device *dev,
|
||||
const struct ethtool_ops *ops);
|
||||
@@ -777,6 +778,34 @@ static inline bool netdev_phys_item_id_same(struct netdev_phys_item_id *a,
|
||||
typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
|
||||
struct sk_buff *skb);
|
||||
|
||||
/* These structures hold the attributes of xdp state that are being passed
|
||||
* to the netdevice through the xdp op.
|
||||
*/
|
||||
enum xdp_netdev_command {
|
||||
/* Set or clear a bpf program used in the earliest stages of packet
|
||||
* rx. The prog will have been loaded as BPF_PROG_TYPE_XDP. The callee
|
||||
* is responsible for calling bpf_prog_put on any old progs that are
|
||||
* stored. In case of error, the callee need not release the new prog
|
||||
* reference, but on success it takes ownership and must bpf_prog_put
|
||||
* when it is no longer used.
|
||||
*/
|
||||
XDP_SETUP_PROG,
|
||||
/* Check if a bpf program is set on the device. The callee should
|
||||
* return true if a program is currently attached and running.
|
||||
*/
|
||||
XDP_QUERY_PROG,
|
||||
};
|
||||
|
||||
struct netdev_xdp {
|
||||
enum xdp_netdev_command command;
|
||||
union {
|
||||
/* XDP_SETUP_PROG */
|
||||
struct bpf_prog *prog;
|
||||
/* XDP_QUERY_PROG */
|
||||
bool prog_attached;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure defines the management hooks for network devices.
|
||||
* The following hooks can be defined; unless noted otherwise, they are
|
||||
@@ -1065,6 +1094,9 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
|
||||
* appropriate rx headroom value allows avoiding skb head copy on
|
||||
* forward. Setting a negative value reset the rx headroom to the
|
||||
* default value.
|
||||
* int (*ndo_xdp)(struct net_device *dev, struct netdev_xdp *xdp);
|
||||
* This function is used to set or query state related to XDP on the
|
||||
* netdevice. See definition of enum xdp_netdev_command for details.
|
||||
*
|
||||
*/
|
||||
struct net_device_ops {
|
||||
@@ -1244,6 +1276,8 @@ struct net_device_ops {
|
||||
struct sk_buff *skb);
|
||||
void (*ndo_set_rx_headroom)(struct net_device *dev,
|
||||
int needed_headroom);
|
||||
int (*ndo_xdp)(struct net_device *dev,
|
||||
struct netdev_xdp *xdp);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -3168,6 +3202,7 @@ int dev_get_phys_port_id(struct net_device *dev,
|
||||
int dev_get_phys_port_name(struct net_device *dev,
|
||||
char *name, size_t len);
|
||||
int dev_change_proto_down(struct net_device *dev, bool proto_down);
|
||||
int dev_change_xdp_fd(struct net_device *dev, int fd);
|
||||
struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev);
|
||||
struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
struct netdev_queue *txq, int *ret);
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
@@ -6321,6 +6322,38 @@ int dev_change_proto_down(struct net_device *dev, bool proto_down)
|
||||
}
|
||||
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
|
||||
*
|
||||
* Set or clear a bpf program for a device
|
||||
*/
|
||||
int dev_change_xdp_fd(struct net_device *dev, int fd)
|
||||
{
|
||||
const struct net_device_ops *ops = dev->netdev_ops;
|
||||
struct bpf_prog *prog = NULL;
|
||||
struct netdev_xdp xdp = {};
|
||||
int err;
|
||||
|
||||
if (!ops->ndo_xdp)
|
||||
return -EOPNOTSUPP;
|
||||
if (fd >= 0) {
|
||||
prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_XDP);
|
||||
if (IS_ERR(prog))
|
||||
return PTR_ERR(prog);
|
||||
}
|
||||
|
||||
xdp.command = XDP_SETUP_PROG;
|
||||
xdp.prog = prog;
|
||||
err = ops->ndo_xdp(dev, &xdp);
|
||||
if (err < 0 && prog)
|
||||
bpf_prog_put(prog);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(dev_change_xdp_fd);
|
||||
|
||||
/**
|
||||
* dev_new_index - allocate an ifindex
|
||||
* @net: the applicable net namespace
|
||||
|
||||
Reference in New Issue
Block a user