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_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 } 74 EXPORT_SYMBOL_NS_GPL(netdev_debug_event, "NETDEV_INTERNAL"); 75 76 static int rtnl_net_debug_net_id; 77 78 static 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 88 static 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 96 static 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 103 static struct notifier_block rtnl_net_debug_block = { 104 .notifier_call = netdev_debug_event, 105 }; 106 107 static 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 122 subsys_initcall(rtnl_net_debug_init); 123