aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>2015-11-28 07:45:28 -0500
committerDavid S. Miller <davem@davemloft.net>2015-12-01 15:31:57 -0500
commit02fff96a79775b7adc34eb599fc6b0476ccda520 (patch)
treeb8b5ccf5a9c21f47ef78f563ff8c6c734567be64
parent27a70af3f4cf633a1b86c0ac7b426e2fe16ad2e5 (diff)
net: add support for netdev notifier error injection
This module allows to insert errors in some of netdevice's notifier events. All network drivers use these notifiers to signal various events and to check if they are allowed, e.g. PRECHANGEMTU and CHANGEMTU afterwards. Until recently I had to run failure tests by injecting a custom module, but now this infrastructure makes it trivial to test these failure paths. Some of the recent bugs I fixed were found using this module. Here's an example: $ cd /sys/kernel/debug/notifier-error-inject/netdev $ echo -22 > actions/NETDEV_CHANGEMTU/error $ ip link set eth0 mtu 1024 RTNETLINK answers: Invalid argument CC: Akinobu Mita <akinobu.mita@gmail.com> CC: "David S. Miller" <davem@davemloft.net> CC: netdev <netdev@vger.kernel.org> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/fault-injection/notifier-error-inject.txt24
-rw-r--r--lib/Kconfig.debug23
-rw-r--r--lib/Makefile1
-rw-r--r--lib/netdev-notifier-error-inject.c54
4 files changed, 102 insertions, 0 deletions
diff --git a/Documentation/fault-injection/notifier-error-inject.txt b/Documentation/fault-injection/notifier-error-inject.txt
index 09adabef513f..71e638a4c497 100644
--- a/Documentation/fault-injection/notifier-error-inject.txt
+++ b/Documentation/fault-injection/notifier-error-inject.txt
@@ -10,6 +10,7 @@ modules that can be used to test the following notifiers.
10 * PM notifier 10 * PM notifier
11 * Memory hotplug notifier 11 * Memory hotplug notifier
12 * powerpc pSeries reconfig notifier 12 * powerpc pSeries reconfig notifier
13 * Netdevice notifier
13 14
14CPU notifier error injection module 15CPU notifier error injection module
15----------------------------------- 16-----------------------------------
@@ -87,6 +88,29 @@ Possible pSeries reconfig notifier events to be failed are:
87 * PSERIES_DRCONF_MEM_ADD 88 * PSERIES_DRCONF_MEM_ADD
88 * PSERIES_DRCONF_MEM_REMOVE 89 * PSERIES_DRCONF_MEM_REMOVE
89 90
91Netdevice notifier error injection module
92----------------------------------------------
93This feature is controlled through debugfs interface
94/sys/kernel/debug/notifier-error-inject/netdev/actions/<notifier event>/error
95
96Netdevice notifier events which can be failed are:
97
98 * NETDEV_REGISTER
99 * NETDEV_CHANGEMTU
100 * NETDEV_CHANGENAME
101 * NETDEV_PRE_UP
102 * NETDEV_PRE_TYPE_CHANGE
103 * NETDEV_POST_INIT
104 * NETDEV_PRECHANGEMTU
105 * NETDEV_PRECHANGEUPPER
106
107Example: Inject netdevice mtu change error (-22 == -EINVAL)
108
109 # cd /sys/kernel/debug/notifier-error-inject/netdev
110 # echo -22 > actions/NETDEV_CHANGEMTU/error
111 # ip link set eth0 mtu 1024
112 RTNETLINK answers: Invalid argument
113
90For more usage examples 114For more usage examples
91----------------------- 115-----------------------
92There are tools/testing/selftests using the notifier error injection features 116There are tools/testing/selftests using the notifier error injection features
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 8c15b29d5adc..0d76ecce27bb 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1484,6 +1484,29 @@ config OF_RECONFIG_NOTIFIER_ERROR_INJECT
1484 1484
1485 If unsure, say N. 1485 If unsure, say N.
1486 1486
1487config NETDEV_NOTIFIER_ERROR_INJECT
1488 tristate "Netdev notifier error injection module"
1489 depends on NET && NOTIFIER_ERROR_INJECTION
1490 help
1491 This option provides the ability to inject artificial errors to
1492 netdevice notifier chain callbacks. It is controlled through debugfs
1493 interface /sys/kernel/debug/notifier-error-inject/netdev
1494
1495 If the notifier call chain should be failed with some events
1496 notified, write the error code to "actions/<notifier event>/error".
1497
1498 Example: Inject netdevice mtu change error (-22 = -EINVAL)
1499
1500 # cd /sys/kernel/debug/notifier-error-inject/netdev
1501 # echo -22 > actions/NETDEV_CHANGEMTU/error
1502 # ip link set eth0 mtu 1024
1503 RTNETLINK answers: Invalid argument
1504
1505 To compile this code as a module, choose M here: the module will
1506 be called netdev-notifier-error-inject.
1507
1508 If unsure, say N.
1509
1487config FAULT_INJECTION 1510config FAULT_INJECTION
1488 bool "Fault-injection framework" 1511 bool "Fault-injection framework"
1489 depends on DEBUG_KERNEL 1512 depends on DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index 7f1de26613d2..180dd4d0dd41 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -120,6 +120,7 @@ obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
120obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o 120obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o
121obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o 121obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
122obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o 122obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o
123obj-$(CONFIG_NETDEV_NOTIFIER_ERROR_INJECT) += netdev-notifier-error-inject.o
123obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o 124obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o
124obj-$(CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT) += \ 125obj-$(CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT) += \
125 of-reconfig-notifier-error-inject.o 126 of-reconfig-notifier-error-inject.o
diff --git a/lib/netdev-notifier-error-inject.c b/lib/netdev-notifier-error-inject.c
new file mode 100644
index 000000000000..b2b856675d61
--- /dev/null
+++ b/lib/netdev-notifier-error-inject.c
@@ -0,0 +1,54 @@
1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/netdevice.h>
4
5#include "notifier-error-inject.h"
6
7static int priority;
8module_param(priority, int, 0);
9MODULE_PARM_DESC(priority, "specify netdevice notifier priority");
10
11static struct notifier_err_inject netdev_notifier_err_inject = {
12 .actions = {
13 { NOTIFIER_ERR_INJECT_ACTION(NETDEV_REGISTER) },
14 { NOTIFIER_ERR_INJECT_ACTION(NETDEV_CHANGEMTU) },
15 { NOTIFIER_ERR_INJECT_ACTION(NETDEV_CHANGENAME) },
16 { NOTIFIER_ERR_INJECT_ACTION(NETDEV_PRE_UP) },
17 { NOTIFIER_ERR_INJECT_ACTION(NETDEV_PRE_TYPE_CHANGE) },
18 { NOTIFIER_ERR_INJECT_ACTION(NETDEV_POST_INIT) },
19 { NOTIFIER_ERR_INJECT_ACTION(NETDEV_PRECHANGEMTU) },
20 { NOTIFIER_ERR_INJECT_ACTION(NETDEV_PRECHANGEUPPER) },
21 {}
22 }
23};
24
25static struct dentry *dir;
26
27static int netdev_err_inject_init(void)
28{
29 int err;
30
31 dir = notifier_err_inject_init("netdev", notifier_err_inject_dir,
32 &netdev_notifier_err_inject, priority);
33 if (IS_ERR(dir))
34 return PTR_ERR(dir);
35
36 err = register_netdevice_notifier(&netdev_notifier_err_inject.nb);
37 if (err)
38 debugfs_remove_recursive(dir);
39
40 return err;
41}
42
43static void netdev_err_inject_exit(void)
44{
45 unregister_netdevice_notifier(&netdev_notifier_err_inject.nb);
46 debugfs_remove_recursive(dir);
47}
48
49module_init(netdev_err_inject_init);
50module_exit(netdev_err_inject_exit);
51
52MODULE_DESCRIPTION("Netdevice notifier error injection module");
53MODULE_LICENSE("GPL");
54MODULE_AUTHOR("Nikolay Aleksandrov <razor@blackwall.org>");