Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-or-later
2/* Copyright Amazon.com Inc. or its affiliates. */
3
4#include <linux/init.h>
5#include <linux/netdevice.h>
6#include <linux/notifier.h>
7#include <linux/rtnetlink.h>
8#include <net/net_namespace.h>
9#include <net/netdev_lock.h>
10#include <net/netns/generic.h>
11
12int netdev_debug_event(struct notifier_block *nb, unsigned long event,
13 void *ptr)
14{
15 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
16 struct net *net = dev_net(dev);
17 enum netdev_cmd cmd = event;
18
19 /* Keep enum and don't add default to trigger -Werror=switch */
20 switch (cmd) {
21 case NETDEV_XDP_FEAT_CHANGE:
22 netdev_assert_locked(dev);
23 fallthrough;
24 case NETDEV_CHANGE:
25 case NETDEV_REGISTER:
26 case NETDEV_UP:
27 netdev_ops_assert_locked(dev);
28 fallthrough;
29 case NETDEV_DOWN:
30 case NETDEV_REBOOT:
31 case NETDEV_UNREGISTER:
32 case NETDEV_CHANGEMTU:
33 case NETDEV_CHANGEADDR:
34 case NETDEV_PRE_CHANGEADDR:
35 case NETDEV_GOING_DOWN:
36 case NETDEV_FEAT_CHANGE:
37 case NETDEV_BONDING_FAILOVER:
38 case NETDEV_PRE_UP:
39 case NETDEV_PRE_TYPE_CHANGE:
40 case NETDEV_POST_TYPE_CHANGE:
41 case NETDEV_POST_INIT:
42 case NETDEV_PRE_UNINIT:
43 case NETDEV_RELEASE:
44 case NETDEV_NOTIFY_PEERS:
45 case NETDEV_JOIN:
46 case NETDEV_CHANGEUPPER:
47 case NETDEV_RESEND_IGMP:
48 case NETDEV_PRECHANGEMTU:
49 case NETDEV_CHANGEINFODATA:
50 case NETDEV_BONDING_INFO:
51 case NETDEV_PRECHANGEUPPER:
52 case NETDEV_CHANGELOWERSTATE:
53 case NETDEV_UDP_TUNNEL_PUSH_INFO:
54 case NETDEV_UDP_TUNNEL_DROP_INFO:
55 case NETDEV_CHANGE_TX_QUEUE_LEN:
56 case NETDEV_CVLAN_FILTER_PUSH_INFO:
57 case NETDEV_CVLAN_FILTER_DROP_INFO:
58 case NETDEV_SVLAN_FILTER_PUSH_INFO:
59 case NETDEV_SVLAN_FILTER_DROP_INFO:
60 case NETDEV_OFFLOAD_XSTATS_ENABLE:
61 case NETDEV_OFFLOAD_XSTATS_DISABLE:
62 case NETDEV_OFFLOAD_XSTATS_REPORT_USED:
63 case NETDEV_OFFLOAD_XSTATS_REPORT_DELTA:
64 ASSERT_RTNL();
65 break;
66
67 case NETDEV_CHANGENAME:
68 ASSERT_RTNL_NET(net);
69 break;
70 }
71
72 return NOTIFY_DONE;
73}
74EXPORT_SYMBOL_NS_GPL(netdev_debug_event, "NETDEV_INTERNAL");
75
76static int rtnl_net_debug_net_id;
77
78static int __net_init rtnl_net_debug_net_init(struct net *net)
79{
80 struct notifier_block *nb;
81
82 nb = net_generic(net, rtnl_net_debug_net_id);
83 nb->notifier_call = netdev_debug_event;
84
85 return register_netdevice_notifier_net(net, nb);
86}
87
88static void __net_exit rtnl_net_debug_net_exit(struct net *net)
89{
90 struct notifier_block *nb;
91
92 nb = net_generic(net, rtnl_net_debug_net_id);
93 unregister_netdevice_notifier_net(net, nb);
94}
95
96static struct pernet_operations rtnl_net_debug_net_ops __net_initdata = {
97 .init = rtnl_net_debug_net_init,
98 .exit = rtnl_net_debug_net_exit,
99 .id = &rtnl_net_debug_net_id,
100 .size = sizeof(struct notifier_block),
101};
102
103static struct notifier_block rtnl_net_debug_block = {
104 .notifier_call = netdev_debug_event,
105};
106
107static int __init rtnl_net_debug_init(void)
108{
109 int ret;
110
111 ret = register_pernet_subsys(&rtnl_net_debug_net_ops);
112 if (ret)
113 return ret;
114
115 ret = register_netdevice_notifier(&rtnl_net_debug_block);
116 if (ret)
117 unregister_pernet_subsys(&rtnl_net_debug_net_ops);
118
119 return ret;
120}
121
122subsys_initcall(rtnl_net_debug_init);