drop_monitor: Add basic infrastructure for hardware drops

Export a function that can be invoked in order to report packets that
were dropped by the underlying hardware along with metadata.

Subsequent patches will add support for the different alert modes.

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:
Ido Schimmel 2019-08-17 16:28:12 +03:00 committed by David S. Miller
parent cac1174fa1
commit edd3d0074c
3 changed files with 62 additions and 0 deletions

View File

@ -11156,6 +11156,7 @@ S: Maintained
W: https://fedorahosted.org/dropwatch/ W: https://fedorahosted.org/dropwatch/
F: net/core/drop_monitor.c F: net/core/drop_monitor.c
F: include/uapi/linux/net_dropmon.h F: include/uapi/linux/net_dropmon.h
F: include/net/drop_monitor.h
NETWORKING DRIVERS NETWORKING DRIVERS
M: "David S. Miller" <davem@davemloft.net> M: "David S. Miller" <davem@davemloft.net>

View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _NET_DROP_MONITOR_H_
#define _NET_DROP_MONITOR_H_
#include <linux/ktime.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
/**
* struct net_dm_hw_metadata - Hardware-supplied packet metadata.
* @trap_group_name: Hardware trap group name.
* @trap_name: Hardware trap name.
* @input_dev: Input netdevice.
*/
struct net_dm_hw_metadata {
const char *trap_group_name;
const char *trap_name;
struct net_device *input_dev;
};
#if IS_ENABLED(CONFIG_NET_DROP_MONITOR)
void net_dm_hw_report(struct sk_buff *skb,
const struct net_dm_hw_metadata *hw_metadata);
#else
static inline void
net_dm_hw_report(struct sk_buff *skb,
const struct net_dm_hw_metadata *hw_metadata)
{
}
#endif
#endif /* _NET_DROP_MONITOR_H_ */

View File

@ -26,6 +26,7 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/drop_monitor.h>
#include <net/genetlink.h> #include <net/genetlink.h>
#include <net/netevent.h> #include <net/netevent.h>
@ -43,6 +44,7 @@
* netlink alerts * netlink alerts
*/ */
static int trace_state = TRACE_OFF; static int trace_state = TRACE_OFF;
static bool monitor_hw;
/* net_dm_mutex /* net_dm_mutex
* *
@ -93,6 +95,8 @@ struct net_dm_alert_ops {
void (*napi_poll_probe)(void *ignore, struct napi_struct *napi, void (*napi_poll_probe)(void *ignore, struct napi_struct *napi,
int work, int budget); int work, int budget);
void (*work_item_func)(struct work_struct *work); void (*work_item_func)(struct work_struct *work);
void (*hw_probe)(struct sk_buff *skb,
const struct net_dm_hw_metadata *hw_metadata);
}; };
struct net_dm_skb_cb { struct net_dm_skb_cb {
@ -267,10 +271,17 @@ static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi,
rcu_read_unlock(); rcu_read_unlock();
} }
static void
net_dm_hw_summary_probe(struct sk_buff *skb,
const struct net_dm_hw_metadata *hw_metadata)
{
}
static const struct net_dm_alert_ops net_dm_alert_summary_ops = { static const struct net_dm_alert_ops net_dm_alert_summary_ops = {
.kfree_skb_probe = trace_kfree_skb_hit, .kfree_skb_probe = trace_kfree_skb_hit,
.napi_poll_probe = trace_napi_poll_hit, .napi_poll_probe = trace_napi_poll_hit,
.work_item_func = send_dm_alert, .work_item_func = send_dm_alert,
.hw_probe = net_dm_hw_summary_probe,
}; };
static void net_dm_packet_trace_kfree_skb_hit(void *ignore, static void net_dm_packet_trace_kfree_skb_hit(void *ignore,
@ -482,10 +493,17 @@ static void net_dm_packet_work(struct work_struct *work)
net_dm_packet_report(skb); net_dm_packet_report(skb);
} }
static void
net_dm_hw_packet_probe(struct sk_buff *skb,
const struct net_dm_hw_metadata *hw_metadata)
{
}
static const struct net_dm_alert_ops net_dm_alert_packet_ops = { static const struct net_dm_alert_ops net_dm_alert_packet_ops = {
.kfree_skb_probe = net_dm_packet_trace_kfree_skb_hit, .kfree_skb_probe = net_dm_packet_trace_kfree_skb_hit,
.napi_poll_probe = net_dm_packet_trace_napi_poll_hit, .napi_poll_probe = net_dm_packet_trace_napi_poll_hit,
.work_item_func = net_dm_packet_work, .work_item_func = net_dm_packet_work,
.hw_probe = net_dm_hw_packet_probe,
}; };
static const struct net_dm_alert_ops *net_dm_alert_ops_arr[] = { static const struct net_dm_alert_ops *net_dm_alert_ops_arr[] = {
@ -493,6 +511,16 @@ static const struct net_dm_alert_ops *net_dm_alert_ops_arr[] = {
[NET_DM_ALERT_MODE_PACKET] = &net_dm_alert_packet_ops, [NET_DM_ALERT_MODE_PACKET] = &net_dm_alert_packet_ops,
}; };
void net_dm_hw_report(struct sk_buff *skb,
const struct net_dm_hw_metadata *hw_metadata)
{
if (!monitor_hw)
return;
net_dm_alert_ops_arr[net_dm_alert_mode]->hw_probe(skb, hw_metadata);
}
EXPORT_SYMBOL_GPL(net_dm_hw_report);
static int net_dm_trace_on_set(struct netlink_ext_ack *extack) static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
{ {
const struct net_dm_alert_ops *ops; const struct net_dm_alert_ops *ops;