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