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 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 /* Keep enum and don't add default to trigger -Werror=switch */ 20 switch (cmd) { 21 case NETDEV_REGISTER: 22 case NETDEV_UP: 23 case NETDEV_CHANGE: 24 netdev_ops_assert_locked(dev); 25 fallthrough; 26 case NETDEV_DOWN: 27 case NETDEV_REBOOT: 28 case NETDEV_UNREGISTER: 29 case NETDEV_CHANGEMTU: 30 case NETDEV_CHANGEADDR: 31 case NETDEV_PRE_CHANGEADDR: 32 case NETDEV_GOING_DOWN: 33 case NETDEV_FEAT_CHANGE: 34 case NETDEV_BONDING_FAILOVER: 35 case NETDEV_PRE_UP: 36 case NETDEV_PRE_TYPE_CHANGE: 37 case NETDEV_POST_TYPE_CHANGE: 38 case NETDEV_POST_INIT: 39 case NETDEV_PRE_UNINIT: 40 case NETDEV_RELEASE: 41 case NETDEV_NOTIFY_PEERS: 42 case NETDEV_JOIN: 43 case NETDEV_CHANGEUPPER: 44 case NETDEV_RESEND_IGMP: 45 case NETDEV_PRECHANGEMTU: 46 case NETDEV_CHANGEINFODATA: 47 case NETDEV_BONDING_INFO: 48 case NETDEV_PRECHANGEUPPER: 49 case NETDEV_CHANGELOWERSTATE: 50 case NETDEV_UDP_TUNNEL_PUSH_INFO: 51 case NETDEV_UDP_TUNNEL_DROP_INFO: 52 case NETDEV_CHANGE_TX_QUEUE_LEN: 53 case NETDEV_CVLAN_FILTER_PUSH_INFO: 54 case NETDEV_CVLAN_FILTER_DROP_INFO: 55 case NETDEV_SVLAN_FILTER_PUSH_INFO: 56 case NETDEV_SVLAN_FILTER_DROP_INFO: 57 case NETDEV_OFFLOAD_XSTATS_ENABLE: 58 case NETDEV_OFFLOAD_XSTATS_DISABLE: 59 case NETDEV_OFFLOAD_XSTATS_REPORT_USED: 60 case NETDEV_OFFLOAD_XSTATS_REPORT_DELTA: 61 case NETDEV_XDP_FEAT_CHANGE: 62 ASSERT_RTNL(); 63 break; 64 65 case NETDEV_CHANGENAME: 66 ASSERT_RTNL_NET(net); 67 break; 68 } 69 70 return NOTIFY_DONE; 71 } 72 EXPORT_SYMBOL_NS_GPL(netdev_debug_event, "NETDEV_INTERNAL"); 73 74 static int rtnl_net_debug_net_id; 75 76 static int __net_init rtnl_net_debug_net_init(struct net *net) 77 { 78 struct notifier_block *nb; 79 80 nb = net_generic(net, rtnl_net_debug_net_id); 81 nb->notifier_call = netdev_debug_event; 82 83 return register_netdevice_notifier_net(net, nb); 84 } 85 86 static void __net_exit rtnl_net_debug_net_exit(struct net *net) 87 { 88 struct notifier_block *nb; 89 90 nb = net_generic(net, rtnl_net_debug_net_id); 91 unregister_netdevice_notifier_net(net, nb); 92 } 93 94 static struct pernet_operations rtnl_net_debug_net_ops __net_initdata = { 95 .init = rtnl_net_debug_net_init, 96 .exit = rtnl_net_debug_net_exit, 97 .id = &rtnl_net_debug_net_id, 98 .size = sizeof(struct notifier_block), 99 }; 100 101 static struct notifier_block rtnl_net_debug_block = { 102 .notifier_call = netdev_debug_event, 103 }; 104 105 static int __init rtnl_net_debug_init(void) 106 { 107 int ret; 108 109 ret = register_pernet_subsys(&rtnl_net_debug_net_ops); 110 if (ret) 111 return ret; 112 113 ret = register_netdevice_notifier(&rtnl_net_debug_block); 114 if (ret) 115 unregister_pernet_subsys(&rtnl_net_debug_net_ops); 116 117 return ret; 118 } 119 120 subsys_initcall(rtnl_net_debug_init); 121