#define pr_fmt(fmt) …
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/string.h>
#include <linux/if_arp.h>
#include <linux/inetdevice.h>
#include <linux/inet.h>
#include <linux/interrupt.h>
#include <linux/netpoll.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include <linux/netlink.h>
#include <linux/net_dropmon.h>
#include <linux/bitfield.h>
#include <linux/percpu.h>
#include <linux/timer.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <net/genetlink.h>
#include <net/netevent.h>
#include <net/flow_offload.h>
#include <net/dropreason.h>
#include <net/devlink.h>
#include <trace/events/skb.h>
#include <trace/events/napi.h>
#include <trace/events/devlink.h>
#include <asm/unaligned.h>
#define TRACE_ON …
#define TRACE_OFF …
static int trace_state = …;
static bool monitor_hw;
static DEFINE_MUTEX(net_dm_mutex);
struct net_dm_stats { … };
#define NET_DM_MAX_HW_TRAP_NAME_LEN …
struct net_dm_hw_entry { … };
struct net_dm_hw_entries { … };
struct per_cpu_dm_data { … };
struct dm_hw_stat_delta { … };
static struct genl_family net_drop_monitor_family;
static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data);
static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_hw_cpu_data);
static int dm_hit_limit = …;
static int dm_delay = …;
static unsigned long dm_hw_check_delta = …;
static enum net_dm_alert_mode net_dm_alert_mode = …;
static u32 net_dm_trunc_len;
static u32 net_dm_queue_len = …;
struct net_dm_alert_ops { … };
struct net_dm_skb_cb { … };
#define NET_DM_SKB_CB(__skb) …
static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
{ … }
static const struct genl_multicast_group dropmon_mcgrps[] = …;
static void send_dm_alert(struct work_struct *work)
{ … }
static void sched_send_work(struct timer_list *t)
{ … }
static void trace_drop_common(struct sk_buff *skb, void *location)
{ … }
static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb,
void *location,
enum skb_drop_reason reason,
struct sock *rx_sk)
{ … }
static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi,
int work, int budget)
{ … }
static struct net_dm_hw_entries *
net_dm_hw_reset_per_cpu_data(struct per_cpu_dm_data *hw_data)
{ … }
static int net_dm_hw_entry_put(struct sk_buff *msg,
const struct net_dm_hw_entry *hw_entry)
{ … }
static int net_dm_hw_entries_put(struct sk_buff *msg,
const struct net_dm_hw_entries *hw_entries)
{ … }
static int
net_dm_hw_summary_report_fill(struct sk_buff *msg,
const struct net_dm_hw_entries *hw_entries)
{ … }
static void net_dm_hw_summary_work(struct work_struct *work)
{ … }
static void
net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink,
struct sk_buff *skb,
const struct devlink_trap_metadata *metadata)
{ … }
static const struct net_dm_alert_ops net_dm_alert_summary_ops = …;
static void net_dm_packet_trace_kfree_skb_hit(void *ignore,
struct sk_buff *skb,
void *location,
enum skb_drop_reason reason,
struct sock *rx_sk)
{ … }
static void net_dm_packet_trace_napi_poll_hit(void *ignore,
struct napi_struct *napi,
int work, int budget)
{ … }
static size_t net_dm_in_port_size(void)
{ … }
#define NET_DM_MAX_SYMBOL_LEN …
#define NET_DM_MAX_REASON_LEN …
static size_t net_dm_packet_report_size(size_t payload_len)
{ … }
static int net_dm_packet_report_in_port_put(struct sk_buff *msg, int ifindex,
const char *name)
{ … }
static int net_dm_packet_report_fill(struct sk_buff *msg, struct sk_buff *skb,
size_t payload_len)
{ … }
#define NET_DM_MAX_PACKET_SIZE …
static void net_dm_packet_report(struct sk_buff *skb)
{ … }
static void net_dm_packet_work(struct work_struct *work)
{ … }
static size_t
net_dm_flow_action_cookie_size(const struct devlink_trap_metadata *hw_metadata)
{ … }
static size_t
net_dm_hw_packet_report_size(size_t payload_len,
const struct devlink_trap_metadata *hw_metadata)
{ … }
static int net_dm_hw_packet_report_fill(struct sk_buff *msg,
struct sk_buff *skb, size_t payload_len)
{ … }
static struct devlink_trap_metadata *
net_dm_hw_metadata_copy(const struct devlink_trap_metadata *metadata)
{ … }
static void
net_dm_hw_metadata_free(struct devlink_trap_metadata *hw_metadata)
{ … }
static void net_dm_hw_packet_report(struct sk_buff *skb)
{ … }
static void net_dm_hw_packet_work(struct work_struct *work)
{ … }
static void
net_dm_hw_trap_packet_probe(void *ignore, const struct devlink *devlink,
struct sk_buff *skb,
const struct devlink_trap_metadata *metadata)
{ … }
static const struct net_dm_alert_ops net_dm_alert_packet_ops = …;
static const struct net_dm_alert_ops *net_dm_alert_ops_arr[] = …;
#if IS_ENABLED(CONFIG_NET_DEVLINK)
static int net_dm_hw_probe_register(const struct net_dm_alert_ops *ops)
{ … }
static void net_dm_hw_probe_unregister(const struct net_dm_alert_ops *ops)
{ … }
#else
static int net_dm_hw_probe_register(const struct net_dm_alert_ops *ops)
{
return -EOPNOTSUPP;
}
static void net_dm_hw_probe_unregister(const struct net_dm_alert_ops *ops)
{
}
#endif
static int net_dm_hw_monitor_start(struct netlink_ext_ack *extack)
{ … }
static void net_dm_hw_monitor_stop(struct netlink_ext_ack *extack)
{ … }
static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
{ … }
static void net_dm_trace_off_set(void)
{ … }
static int set_all_monitor_traces(int state, struct netlink_ext_ack *extack)
{ … }
static bool net_dm_is_monitoring(void)
{ … }
static int net_dm_alert_mode_get_from_info(struct genl_info *info,
enum net_dm_alert_mode *p_alert_mode)
{ … }
static int net_dm_alert_mode_set(struct genl_info *info)
{ … }
static void net_dm_trunc_len_set(struct genl_info *info)
{ … }
static void net_dm_queue_len_set(struct genl_info *info)
{ … }
static int net_dm_cmd_config(struct sk_buff *skb,
struct genl_info *info)
{ … }
static int net_dm_monitor_start(bool set_sw, bool set_hw,
struct netlink_ext_ack *extack)
{ … }
static void net_dm_monitor_stop(bool set_sw, bool set_hw,
struct netlink_ext_ack *extack)
{ … }
static int net_dm_cmd_trace(struct sk_buff *skb,
struct genl_info *info)
{ … }
static int net_dm_config_fill(struct sk_buff *msg, struct genl_info *info)
{ … }
static int net_dm_cmd_config_get(struct sk_buff *skb, struct genl_info *info)
{ … }
static void net_dm_stats_read(struct net_dm_stats *stats)
{ … }
static int net_dm_stats_put(struct sk_buff *msg)
{ … }
static void net_dm_hw_stats_read(struct net_dm_stats *stats)
{ … }
static int net_dm_hw_stats_put(struct sk_buff *msg)
{ … }
static int net_dm_stats_fill(struct sk_buff *msg, struct genl_info *info)
{ … }
static int net_dm_cmd_stats_get(struct sk_buff *skb, struct genl_info *info)
{ … }
static int dropmon_net_event(struct notifier_block *ev_block,
unsigned long event, void *ptr)
{ … }
static const struct nla_policy net_dm_nl_policy[NET_DM_ATTR_MAX + 1] = …;
static const struct genl_small_ops dropmon_ops[] = …;
static int net_dm_nl_pre_doit(const struct genl_split_ops *ops,
struct sk_buff *skb, struct genl_info *info)
{ … }
static void net_dm_nl_post_doit(const struct genl_split_ops *ops,
struct sk_buff *skb, struct genl_info *info)
{ … }
static struct genl_family net_drop_monitor_family __ro_after_init = …;
static struct notifier_block dropmon_net_notifier = …;
static void __net_dm_cpu_data_init(struct per_cpu_dm_data *data)
{ … }
static void __net_dm_cpu_data_fini(struct per_cpu_dm_data *data)
{ … }
static void net_dm_cpu_data_init(int cpu)
{ … }
static void net_dm_cpu_data_fini(int cpu)
{ … }
static void net_dm_hw_cpu_data_init(int cpu)
{ … }
static void net_dm_hw_cpu_data_fini(int cpu)
{ … }
static int __init init_net_drop_monitor(void)
{ … }
static void exit_net_drop_monitor(void)
{ … }
module_init(…) …;
module_exit(exit_net_drop_monitor);
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
MODULE_ALIAS_GENL_FAMILY(…) …;
MODULE_DESCRIPTION(…) …;