7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9 #include <linux/netdevice.h>
11 #include <linux/string.h>
12 #include <linux/if_arp.h>
17 #include <linux/sched.h>
19 #include <linux/types.h>
21 #include <linux/netlink.h>
25 #include <linux/bitops.h>
26 #include <linux/slab.h>
27 #include <linux/module.h>
34 #include <asm/unaligned.h>
62 static struct genl_family net_drop_monitor_family = {
72 static int dm_hit_limit = 64;
73 static int dm_delay = 1;
74 static unsigned long dm_hw_check_delta = 2*
HZ;
87 al +=
sizeof(
struct nlattr);
104 spin_unlock_irqrestore(&data->
lock, flags);
116 skb = reset_per_cpu_data(data);
127 static void sched_send_work(
unsigned long _data)
146 spin_lock(&data->
lock);
153 nla = genlmsg_data(nlmsg_data(nlh));
155 for (i = 0; i < msg->
entries; i++) {
156 if (!
memcmp(&location, msg->
points[i].pc,
sizeof(
void *))) {
161 if (msg->
entries == dm_hit_limit)
178 spin_unlock_irqrestore(&data->
lock, flags);
181 static void trace_kfree_skb_hit(
void *ignore,
struct sk_buff *skb,
void *location)
183 trace_drop_common(skb, location);
186 static void trace_napi_poll_hit(
void *ignore,
struct napi_struct *
napi)
197 list_for_each_entry_rcu(new_stat, &hw_stats_list,
list) {
204 if ((new_stat->
dev == napi->
dev) &&
216 static int set_all_monitor_traces(
int state)
224 if (state == trace_state) {
236 rc |= register_trace_kfree_skb(trace_kfree_skb_hit,
NULL);
237 rc |= register_trace_napi_poll(trace_napi_poll_hit,
NULL);
241 rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit,
NULL);
242 rc |= unregister_trace_napi_poll(trace_napi_poll_hit,
NULL);
244 tracepoint_synchronize_unregister();
251 list_del_rcu(&new_stat->
list);
276 static int net_dm_cmd_config(
struct sk_buff *skb,
282 static int net_dm_cmd_trace(
struct sk_buff *skb,
287 return set_all_monitor_traces(
TRACE_ON);
290 return set_all_monitor_traces(
TRACE_OFF);
314 list_add_rcu(&new_stat->
list, &hw_stats_list);
320 if (new_stat->
dev == dev) {
323 list_del_rcu(&new_stat->
list);
336 static struct genl_ops dropmon_ops[] = {
339 .doit = net_dm_cmd_config,
343 .doit = net_dm_cmd_trace,
347 .doit = net_dm_cmd_trace,
352 .notifier_call = dropmon_net_event
355 static int __init init_net_drop_monitor(
void)
360 pr_info(
"Initializing network drop monitor service\n");
362 if (
sizeof(
void *) > 8) {
363 pr_err(
"Unable to store program counters on this arch, Drop monitor failed\n");
371 pr_err(
"Could not create drop monitor netlink family\n");
377 pr_crit(
"Failed to register netdevice notifier\n");
384 data = &
per_cpu(dm_cpu_data, cpu);
390 reset_per_cpu_data(data);
402 static void exit_net_drop_monitor(
void)
417 data = &
per_cpu(dm_cpu_data, cpu);