devlink: Add packet trap infrastructure
Add the basic packet trap infrastructure that allows device drivers to register their supported packet traps and trap groups with devlink. Each driver is expected to provide basic information about each supported trap, such as name and ID, but also the supported metadata types that will accompany each packet trapped via the trap. The currently supported metadata type is just the input port, but more will be added in the future. For example, output port and traffic class. Trap groups allow users to set the action of all member traps. In addition, users can retrieve per-group statistics in case per-trap statistics are too narrow. In the future, the trap group object can be extended with more attributes, such as policer settings which will limit the amount of traffic generated by member traps towards the CPU. Beside registering their packet traps with devlink, drivers are also expected to report trapped packets to devlink along with relevant metadata. devlink will maintain packets and bytes statistics for each packet trap and will potentially report the trapped packet with its metadata to user space via drop monitor netlink channel. The interface towards the drivers is simple and allows devlink to set the action of the trap. Currently, only two actions are supported: 'trap' and 'drop'. When set to 'trap', the device is expected to provide the sole copy of the packet to the driver which will pass it to devlink. When set to 'drop', the device is expected to drop the packet and not send a copy to the driver. In the future, more actions can be added, such as 'mirror'. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8e94c3bc92
commit
0f420b6c52
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/refcount.h>
|
||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
#include <uapi/linux/devlink.h>
|
#include <uapi/linux/devlink.h>
|
||||||
|
|
||||||
|
@ -31,6 +32,8 @@ struct devlink {
|
||||||
struct list_head reporter_list;
|
struct list_head reporter_list;
|
||||||
struct mutex reporters_lock; /* protects reporter_list */
|
struct mutex reporters_lock; /* protects reporter_list */
|
||||||
struct devlink_dpipe_headers *dpipe_headers;
|
struct devlink_dpipe_headers *dpipe_headers;
|
||||||
|
struct list_head trap_list;
|
||||||
|
struct list_head trap_group_list;
|
||||||
const struct devlink_ops *ops;
|
const struct devlink_ops *ops;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
possible_net_t _net;
|
possible_net_t _net;
|
||||||
|
@ -497,6 +500,89 @@ struct devlink_health_reporter_ops {
|
||||||
struct devlink_fmsg *fmsg);
|
struct devlink_fmsg *fmsg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct devlink_trap_group - Immutable packet trap group attributes.
|
||||||
|
* @name: Trap group name.
|
||||||
|
* @id: Trap group identifier.
|
||||||
|
* @generic: Whether the trap group is generic or not.
|
||||||
|
*
|
||||||
|
* Describes immutable attributes of packet trap groups that drivers register
|
||||||
|
* with devlink.
|
||||||
|
*/
|
||||||
|
struct devlink_trap_group {
|
||||||
|
const char *name;
|
||||||
|
u16 id;
|
||||||
|
bool generic;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT BIT(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct devlink_trap - Immutable packet trap attributes.
|
||||||
|
* @type: Trap type.
|
||||||
|
* @init_action: Initial trap action.
|
||||||
|
* @generic: Whether the trap is generic or not.
|
||||||
|
* @id: Trap identifier.
|
||||||
|
* @name: Trap name.
|
||||||
|
* @group: Immutable packet trap group attributes.
|
||||||
|
* @metadata_cap: Metadata types that can be provided by the trap.
|
||||||
|
*
|
||||||
|
* Describes immutable attributes of packet traps that drivers register with
|
||||||
|
* devlink.
|
||||||
|
*/
|
||||||
|
struct devlink_trap {
|
||||||
|
enum devlink_trap_type type;
|
||||||
|
enum devlink_trap_action init_action;
|
||||||
|
bool generic;
|
||||||
|
u16 id;
|
||||||
|
const char *name;
|
||||||
|
struct devlink_trap_group group;
|
||||||
|
u32 metadata_cap;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum devlink_trap_generic_id {
|
||||||
|
/* Add new generic trap IDs above */
|
||||||
|
__DEVLINK_TRAP_GENERIC_ID_MAX,
|
||||||
|
DEVLINK_TRAP_GENERIC_ID_MAX = __DEVLINK_TRAP_GENERIC_ID_MAX - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum devlink_trap_group_generic_id {
|
||||||
|
/* Add new generic trap group IDs above */
|
||||||
|
__DEVLINK_TRAP_GROUP_GENERIC_ID_MAX,
|
||||||
|
DEVLINK_TRAP_GROUP_GENERIC_ID_MAX =
|
||||||
|
__DEVLINK_TRAP_GROUP_GENERIC_ID_MAX - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEVLINK_TRAP_GENERIC(_type, _init_action, _id, _group, _metadata_cap) \
|
||||||
|
{ \
|
||||||
|
.type = DEVLINK_TRAP_TYPE_##_type, \
|
||||||
|
.init_action = DEVLINK_TRAP_ACTION_##_init_action, \
|
||||||
|
.generic = true, \
|
||||||
|
.id = DEVLINK_TRAP_GENERIC_ID_##_id, \
|
||||||
|
.name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
|
||||||
|
.group = _group, \
|
||||||
|
.metadata_cap = _metadata_cap, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEVLINK_TRAP_DRIVER(_type, _init_action, _id, _name, _group, \
|
||||||
|
_metadata_cap) \
|
||||||
|
{ \
|
||||||
|
.type = DEVLINK_TRAP_TYPE_##_type, \
|
||||||
|
.init_action = DEVLINK_TRAP_ACTION_##_init_action, \
|
||||||
|
.generic = false, \
|
||||||
|
.id = _id, \
|
||||||
|
.name = _name, \
|
||||||
|
.group = _group, \
|
||||||
|
.metadata_cap = _metadata_cap, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEVLINK_TRAP_GROUP_GENERIC(_id) \
|
||||||
|
{ \
|
||||||
|
.name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
|
||||||
|
.id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
|
||||||
|
.generic = true, \
|
||||||
|
}
|
||||||
|
|
||||||
struct devlink_ops {
|
struct devlink_ops {
|
||||||
int (*reload)(struct devlink *devlink, struct netlink_ext_ack *extack);
|
int (*reload)(struct devlink *devlink, struct netlink_ext_ack *extack);
|
||||||
int (*port_type_set)(struct devlink_port *devlink_port,
|
int (*port_type_set)(struct devlink_port *devlink_port,
|
||||||
|
@ -558,6 +644,38 @@ struct devlink_ops {
|
||||||
int (*flash_update)(struct devlink *devlink, const char *file_name,
|
int (*flash_update)(struct devlink *devlink, const char *file_name,
|
||||||
const char *component,
|
const char *component,
|
||||||
struct netlink_ext_ack *extack);
|
struct netlink_ext_ack *extack);
|
||||||
|
/**
|
||||||
|
* @trap_init: Trap initialization function.
|
||||||
|
*
|
||||||
|
* Should be used by device drivers to initialize the trap in the
|
||||||
|
* underlying device. Drivers should also store the provided trap
|
||||||
|
* context, so that they could efficiently pass it to
|
||||||
|
* devlink_trap_report() when the trap is triggered.
|
||||||
|
*/
|
||||||
|
int (*trap_init)(struct devlink *devlink,
|
||||||
|
const struct devlink_trap *trap, void *trap_ctx);
|
||||||
|
/**
|
||||||
|
* @trap_fini: Trap de-initialization function.
|
||||||
|
*
|
||||||
|
* Should be used by device drivers to de-initialize the trap in the
|
||||||
|
* underlying device.
|
||||||
|
*/
|
||||||
|
void (*trap_fini)(struct devlink *devlink,
|
||||||
|
const struct devlink_trap *trap, void *trap_ctx);
|
||||||
|
/**
|
||||||
|
* @trap_action_set: Trap action set function.
|
||||||
|
*/
|
||||||
|
int (*trap_action_set)(struct devlink *devlink,
|
||||||
|
const struct devlink_trap *trap,
|
||||||
|
enum devlink_trap_action action);
|
||||||
|
/**
|
||||||
|
* @trap_group_init: Trap group initialization function.
|
||||||
|
*
|
||||||
|
* Should be used by device drivers to initialize the trap group in the
|
||||||
|
* underlying device.
|
||||||
|
*/
|
||||||
|
int (*trap_group_init)(struct devlink *devlink,
|
||||||
|
const struct devlink_trap_group *group);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void *devlink_priv(struct devlink *devlink)
|
static inline void *devlink_priv(struct devlink *devlink)
|
||||||
|
@ -774,6 +892,17 @@ void devlink_flash_update_status_notify(struct devlink *devlink,
|
||||||
unsigned long done,
|
unsigned long done,
|
||||||
unsigned long total);
|
unsigned long total);
|
||||||
|
|
||||||
|
int devlink_traps_register(struct devlink *devlink,
|
||||||
|
const struct devlink_trap *traps,
|
||||||
|
size_t traps_count, void *priv);
|
||||||
|
void devlink_traps_unregister(struct devlink *devlink,
|
||||||
|
const struct devlink_trap *traps,
|
||||||
|
size_t traps_count);
|
||||||
|
void devlink_trap_report(struct devlink *devlink,
|
||||||
|
struct sk_buff *skb, void *trap_ctx,
|
||||||
|
struct devlink_port *in_devlink_port);
|
||||||
|
void *devlink_trap_ctx_priv(void *trap_ctx);
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_NET_DEVLINK)
|
#if IS_ENABLED(CONFIG_NET_DEVLINK)
|
||||||
|
|
||||||
void devlink_compat_running_version(struct net_device *dev,
|
void devlink_compat_running_version(struct net_device *dev,
|
||||||
|
|
|
@ -107,6 +107,16 @@ enum devlink_command {
|
||||||
DEVLINK_CMD_FLASH_UPDATE_END, /* notification only */
|
DEVLINK_CMD_FLASH_UPDATE_END, /* notification only */
|
||||||
DEVLINK_CMD_FLASH_UPDATE_STATUS, /* notification only */
|
DEVLINK_CMD_FLASH_UPDATE_STATUS, /* notification only */
|
||||||
|
|
||||||
|
DEVLINK_CMD_TRAP_GET, /* can dump */
|
||||||
|
DEVLINK_CMD_TRAP_SET,
|
||||||
|
DEVLINK_CMD_TRAP_NEW,
|
||||||
|
DEVLINK_CMD_TRAP_DEL,
|
||||||
|
|
||||||
|
DEVLINK_CMD_TRAP_GROUP_GET, /* can dump */
|
||||||
|
DEVLINK_CMD_TRAP_GROUP_SET,
|
||||||
|
DEVLINK_CMD_TRAP_GROUP_NEW,
|
||||||
|
DEVLINK_CMD_TRAP_GROUP_DEL,
|
||||||
|
|
||||||
/* add new commands above here */
|
/* add new commands above here */
|
||||||
__DEVLINK_CMD_MAX,
|
__DEVLINK_CMD_MAX,
|
||||||
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
|
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
|
||||||
|
@ -194,6 +204,47 @@ enum devlink_param_fw_load_policy_value {
|
||||||
DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH,
|
DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DEVLINK_ATTR_STATS_RX_PACKETS, /* u64 */
|
||||||
|
DEVLINK_ATTR_STATS_RX_BYTES, /* u64 */
|
||||||
|
|
||||||
|
__DEVLINK_ATTR_STATS_MAX,
|
||||||
|
DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum devlink_trap_action - Packet trap action.
|
||||||
|
* @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
|
||||||
|
* sent to the CPU.
|
||||||
|
* @DEVLINK_TRAP_ACTION_TRAP: The sole copy of the packet is sent to the CPU.
|
||||||
|
*/
|
||||||
|
enum devlink_trap_action {
|
||||||
|
DEVLINK_TRAP_ACTION_DROP,
|
||||||
|
DEVLINK_TRAP_ACTION_TRAP,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum devlink_trap_type - Packet trap type.
|
||||||
|
* @DEVLINK_TRAP_TYPE_DROP: Trap reason is a drop. Trapped packets are only
|
||||||
|
* processed by devlink and not injected to the
|
||||||
|
* kernel's Rx path.
|
||||||
|
* @DEVLINK_TRAP_TYPE_EXCEPTION: Trap reason is an exception. Packet was not
|
||||||
|
* forwarded as intended due to an exception
|
||||||
|
* (e.g., missing neighbour entry) and trapped to
|
||||||
|
* control plane for resolution. Trapped packets
|
||||||
|
* are processed by devlink and injected to
|
||||||
|
* the kernel's Rx path.
|
||||||
|
*/
|
||||||
|
enum devlink_trap_type {
|
||||||
|
DEVLINK_TRAP_TYPE_DROP,
|
||||||
|
DEVLINK_TRAP_TYPE_EXCEPTION,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/* Trap can report input port as metadata */
|
||||||
|
DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT,
|
||||||
|
};
|
||||||
|
|
||||||
enum devlink_attr {
|
enum devlink_attr {
|
||||||
/* don't change the order or add anything between, this is ABI! */
|
/* don't change the order or add anything between, this is ABI! */
|
||||||
DEVLINK_ATTR_UNSPEC,
|
DEVLINK_ATTR_UNSPEC,
|
||||||
|
@ -348,6 +399,17 @@ enum devlink_attr {
|
||||||
DEVLINK_ATTR_PORT_PCI_PF_NUMBER, /* u16 */
|
DEVLINK_ATTR_PORT_PCI_PF_NUMBER, /* u16 */
|
||||||
DEVLINK_ATTR_PORT_PCI_VF_NUMBER, /* u16 */
|
DEVLINK_ATTR_PORT_PCI_VF_NUMBER, /* u16 */
|
||||||
|
|
||||||
|
DEVLINK_ATTR_STATS, /* nested */
|
||||||
|
|
||||||
|
DEVLINK_ATTR_TRAP_NAME, /* string */
|
||||||
|
/* enum devlink_trap_action */
|
||||||
|
DEVLINK_ATTR_TRAP_ACTION, /* u8 */
|
||||||
|
/* enum devlink_trap_type */
|
||||||
|
DEVLINK_ATTR_TRAP_TYPE, /* u8 */
|
||||||
|
DEVLINK_ATTR_TRAP_GENERIC, /* flag */
|
||||||
|
DEVLINK_ATTR_TRAP_METADATA, /* nested */
|
||||||
|
DEVLINK_ATTR_TRAP_GROUP_NAME, /* string */
|
||||||
|
|
||||||
/* add new attributes above here, update the policy in devlink.c */
|
/* add new attributes above here, update the policy in devlink.c */
|
||||||
|
|
||||||
__DEVLINK_ATTR_MAX,
|
__DEVLINK_ATTR_MAX,
|
||||||
|
|
|
@ -430,6 +430,7 @@ config NET_SOCK_MSG
|
||||||
config NET_DEVLINK
|
config NET_DEVLINK
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
imply NET_DROP_MONITOR
|
||||||
|
|
||||||
config PAGE_POOL
|
config PAGE_POOL
|
||||||
bool
|
bool
|
||||||
|
|
1068
net/core/devlink.c
1068
net/core/devlink.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue