| 1 | |
| 2 |
|
| 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 |
|
| 12 | int 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 |
|
| 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 | case NETDEV_DOWN:
|
| 28 | case NETDEV_GOING_DOWN:
|
| 29 | netdev_assert_locked_ops_compat(dev);
|
| 30 | fallthrough;
|
| 31 | case NETDEV_REBOOT:
|
| 32 | case NETDEV_UNREGISTER:
|
| 33 | case NETDEV_CHANGEMTU:
|
| 34 | case NETDEV_CHANGEADDR:
|
| 35 | case NETDEV_PRE_CHANGEADDR:
|
| 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 | netdev_assert_locked_ops(dev);
|
| 69 | ASSERT_RTNL_NET(net);
|
| 70 | break;
|
| 71 | }
|
| 72 |
|
| 73 | return NOTIFY_DONE;
|
| 74 | }
|
| 75 | EXPORT_SYMBOL_NS_GPL(netdev_debug_event, "NETDEV_INTERNAL");
|
| 76 |
|
| 77 | static int rtnl_net_debug_net_id;
|
| 78 |
|
| 79 | static int __net_init rtnl_net_debug_net_init(struct net *net)
|
| 80 | {
|
| 81 | struct notifier_block *nb;
|
| 82 |
|
| 83 | nb = net_generic(net, rtnl_net_debug_net_id);
|
| 84 | nb->notifier_call = netdev_debug_event;
|
| 85 |
|
| 86 | return register_netdevice_notifier_net(net, nb);
|
| 87 | }
|
| 88 |
|
| 89 | static void __net_exit rtnl_net_debug_net_exit(struct net *net)
|
| 90 | {
|
| 91 | struct notifier_block *nb;
|
| 92 |
|
| 93 | nb = net_generic(net, rtnl_net_debug_net_id);
|
| 94 | unregister_netdevice_notifier_net(net, nb);
|
| 95 | }
|
| 96 |
|
| 97 | static struct pernet_operations rtnl_net_debug_net_ops __net_initdata = {
|
| 98 | .init = rtnl_net_debug_net_init,
|
| 99 | .exit = rtnl_net_debug_net_exit,
|
| 100 | .id = &rtnl_net_debug_net_id,
|
| 101 | .size = sizeof(struct notifier_block),
|
| 102 | };
|
| 103 |
|
| 104 | static struct notifier_block rtnl_net_debug_block = {
|
| 105 | .notifier_call = netdev_debug_event,
|
| 106 | };
|
| 107 |
|
| 108 | static int __init rtnl_net_debug_init(void)
|
| 109 | {
|
| 110 | int ret;
|
| 111 |
|
| 112 | ret = register_pernet_subsys(&rtnl_net_debug_net_ops);
|
| 113 | if (ret)
|
| 114 | return ret;
|
| 115 |
|
| 116 | ret = register_netdevice_notifier(&rtnl_net_debug_block);
|
| 117 | if (ret)
|
| 118 | unregister_pernet_subsys(&rtnl_net_debug_net_ops);
|
| 119 |
|
| 120 | return ret;
|
| 121 | }
|
| 122 |
|
| 123 | subsys_initcall(rtnl_net_debug_init);
|