1*09c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
202fff96aSNikolay Aleksandrov #include <linux/kernel.h>
302fff96aSNikolay Aleksandrov #include <linux/module.h>
402fff96aSNikolay Aleksandrov #include <linux/netdevice.h>
502fff96aSNikolay Aleksandrov
602fff96aSNikolay Aleksandrov #include "notifier-error-inject.h"
702fff96aSNikolay Aleksandrov
802fff96aSNikolay Aleksandrov static int priority;
902fff96aSNikolay Aleksandrov module_param(priority, int, 0);
1002fff96aSNikolay Aleksandrov MODULE_PARM_DESC(priority, "specify netdevice notifier priority");
1102fff96aSNikolay Aleksandrov
1202fff96aSNikolay Aleksandrov static struct notifier_err_inject netdev_notifier_err_inject = {
1302fff96aSNikolay Aleksandrov .actions = {
1402fff96aSNikolay Aleksandrov { NOTIFIER_ERR_INJECT_ACTION(NETDEV_REGISTER) },
1502fff96aSNikolay Aleksandrov { NOTIFIER_ERR_INJECT_ACTION(NETDEV_CHANGEMTU) },
1602fff96aSNikolay Aleksandrov { NOTIFIER_ERR_INJECT_ACTION(NETDEV_CHANGENAME) },
1702fff96aSNikolay Aleksandrov { NOTIFIER_ERR_INJECT_ACTION(NETDEV_PRE_UP) },
1802fff96aSNikolay Aleksandrov { NOTIFIER_ERR_INJECT_ACTION(NETDEV_PRE_TYPE_CHANGE) },
1902fff96aSNikolay Aleksandrov { NOTIFIER_ERR_INJECT_ACTION(NETDEV_POST_INIT) },
2002fff96aSNikolay Aleksandrov { NOTIFIER_ERR_INJECT_ACTION(NETDEV_PRECHANGEMTU) },
2102fff96aSNikolay Aleksandrov { NOTIFIER_ERR_INJECT_ACTION(NETDEV_PRECHANGEUPPER) },
22c39d0454SIdo Schimmel { NOTIFIER_ERR_INJECT_ACTION(NETDEV_CHANGEUPPER) },
2302fff96aSNikolay Aleksandrov {}
2402fff96aSNikolay Aleksandrov }
2502fff96aSNikolay Aleksandrov };
2602fff96aSNikolay Aleksandrov
2702fff96aSNikolay Aleksandrov static struct dentry *dir;
2802fff96aSNikolay Aleksandrov
netdev_err_inject_init(void)2902fff96aSNikolay Aleksandrov static int netdev_err_inject_init(void)
3002fff96aSNikolay Aleksandrov {
3102fff96aSNikolay Aleksandrov int err;
3202fff96aSNikolay Aleksandrov
3302fff96aSNikolay Aleksandrov dir = notifier_err_inject_init("netdev", notifier_err_inject_dir,
3402fff96aSNikolay Aleksandrov &netdev_notifier_err_inject, priority);
3502fff96aSNikolay Aleksandrov if (IS_ERR(dir))
3602fff96aSNikolay Aleksandrov return PTR_ERR(dir);
3702fff96aSNikolay Aleksandrov
3802fff96aSNikolay Aleksandrov err = register_netdevice_notifier(&netdev_notifier_err_inject.nb);
3902fff96aSNikolay Aleksandrov if (err)
4002fff96aSNikolay Aleksandrov debugfs_remove_recursive(dir);
4102fff96aSNikolay Aleksandrov
4202fff96aSNikolay Aleksandrov return err;
4302fff96aSNikolay Aleksandrov }
4402fff96aSNikolay Aleksandrov
netdev_err_inject_exit(void)4502fff96aSNikolay Aleksandrov static void netdev_err_inject_exit(void)
4602fff96aSNikolay Aleksandrov {
4702fff96aSNikolay Aleksandrov unregister_netdevice_notifier(&netdev_notifier_err_inject.nb);
4802fff96aSNikolay Aleksandrov debugfs_remove_recursive(dir);
4902fff96aSNikolay Aleksandrov }
5002fff96aSNikolay Aleksandrov
5102fff96aSNikolay Aleksandrov module_init(netdev_err_inject_init);
5202fff96aSNikolay Aleksandrov module_exit(netdev_err_inject_exit);
5302fff96aSNikolay Aleksandrov
5402fff96aSNikolay Aleksandrov MODULE_DESCRIPTION("Netdevice notifier error injection module");
5502fff96aSNikolay Aleksandrov MODULE_LICENSE("GPL");
5602fff96aSNikolay Aleksandrov MODULE_AUTHOR("Nikolay Aleksandrov <razor@blackwall.org>");
57