lock_debug.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* Copyright Amazon.com Inc. or its affiliates. */
  3. #include <linux/init.h>
  4. #include <linux/netdevice.h>
  5. #include <linux/notifier.h>
  6. #include <linux/rtnetlink.h>
  7. #include <net/net_namespace.h>
  8. #include <net/netdev_lock.h>
  9. #include <net/netns/generic.h>
  10. int netdev_debug_event(struct notifier_block *nb, unsigned long event,
  11. void *ptr)
  12. {
  13. struct net_device *dev = netdev_notifier_info_to_dev(ptr);
  14. struct net *net = dev_net(dev);
  15. enum netdev_cmd cmd = event;
  16. /* Keep enum and don't add default to trigger -Werror=switch */
  17. switch (cmd) {
  18. case NETDEV_XDP_FEAT_CHANGE:
  19. netdev_assert_locked(dev);
  20. fallthrough;
  21. case NETDEV_CHANGE:
  22. case NETDEV_REGISTER:
  23. case NETDEV_UP:
  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. ASSERT_RTNL();
  62. break;
  63. case NETDEV_CHANGENAME:
  64. ASSERT_RTNL_NET(net);
  65. break;
  66. }
  67. return NOTIFY_DONE;
  68. }
  69. EXPORT_SYMBOL_NS_GPL(netdev_debug_event, "NETDEV_INTERNAL");
  70. static int rtnl_net_debug_net_id;
  71. static int __net_init rtnl_net_debug_net_init(struct net *net)
  72. {
  73. struct notifier_block *nb;
  74. nb = net_generic(net, rtnl_net_debug_net_id);
  75. nb->notifier_call = netdev_debug_event;
  76. return register_netdevice_notifier_net(net, nb);
  77. }
  78. static void __net_exit rtnl_net_debug_net_exit(struct net *net)
  79. {
  80. struct notifier_block *nb;
  81. nb = net_generic(net, rtnl_net_debug_net_id);
  82. unregister_netdevice_notifier_net(net, nb);
  83. }
  84. static struct pernet_operations rtnl_net_debug_net_ops __net_initdata = {
  85. .init = rtnl_net_debug_net_init,
  86. .exit = rtnl_net_debug_net_exit,
  87. .id = &rtnl_net_debug_net_id,
  88. .size = sizeof(struct notifier_block),
  89. };
  90. static struct notifier_block rtnl_net_debug_block = {
  91. .notifier_call = netdev_debug_event,
  92. };
  93. static int __init rtnl_net_debug_init(void)
  94. {
  95. int ret;
  96. ret = register_pernet_subsys(&rtnl_net_debug_net_ops);
  97. if (ret)
  98. return ret;
  99. ret = register_netdevice_notifier(&rtnl_net_debug_block);
  100. if (ret)
  101. unregister_pernet_subsys(&rtnl_net_debug_net_ops);
  102. return ret;
  103. }
  104. subsys_initcall(rtnl_net_debug_init);