diff options
Diffstat (limited to 'drivers/net/netconsole.c')
-rw-r--r-- | drivers/net/netconsole.c | 108 |
1 files changed, 35 insertions, 73 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index eb41e44921e6..dfc82720065a 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -242,34 +242,6 @@ static struct netconsole_target *to_target(struct config_item *item) } /* - * Wrapper over simple_strtol (base 10) with sanity and range checking. - * We return (signed) long only because we may want to return errors. - * Do not use this to convert numbers that are allowed to be negative. - */ -static long strtol10_check_range(const char *cp, long min, long max) -{ - long ret; - char *p = (char *) cp; - - WARN_ON(min < 0); - WARN_ON(max < min); - - ret = simple_strtol(p, &p, 10); - - if (*p && (*p != '\n')) { - printk(KERN_ERR "netconsole: invalid input\n"); - return -EINVAL; - } - if ((ret < min) || (ret > max)) { - printk(KERN_ERR "netconsole: input %ld must be between " - "%ld and %ld\n", ret, min, max); - return -EINVAL; - } - - return ret; -} - -/* * Attribute operations for netconsole_target. */ @@ -327,12 +299,14 @@ static ssize_t store_enabled(struct netconsole_target *nt, const char *buf, size_t count) { + int enabled; int err; - long enabled; - enabled = strtol10_check_range(buf, 0, 1); - if (enabled < 0) - return enabled; + err = kstrtoint(buf, 10, &enabled); + if (err < 0) + return err; + if (enabled < 0 || enabled > 1) + return -EINVAL; if (enabled) { /* 1 */ @@ -384,8 +358,7 @@ static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, size_t count) { - long local_port; -#define __U16_MAX ((__u16) ~0U) + int rv; if (nt->enabled) { printk(KERN_ERR "netconsole: target (%s) is enabled, " @@ -394,12 +367,9 @@ static ssize_t store_local_port(struct netconsole_target *nt, return -EINVAL; } - local_port = strtol10_check_range(buf, 0, __U16_MAX); - if (local_port < 0) - return local_port; - - nt->np.local_port = local_port; - + rv = kstrtou16(buf, 10, &nt->np.local_port); + if (rv < 0) + return rv; return strnlen(buf, count); } @@ -407,8 +377,7 @@ static ssize_t store_remote_port(struct netconsole_target *nt, const char *buf, size_t count) { - long remote_port; -#define __U16_MAX ((__u16) ~0U) + int rv; if (nt->enabled) { printk(KERN_ERR "netconsole: target (%s) is enabled, " @@ -417,12 +386,9 @@ static ssize_t store_remote_port(struct netconsole_target *nt, return -EINVAL; } - remote_port = strtol10_check_range(buf, 0, __U16_MAX); - if (remote_port < 0) - return remote_port; - - nt->np.remote_port = remote_port; - + rv = kstrtou16(buf, 10, &nt->np.remote_port); + if (rv < 0) + return rv; return strnlen(buf, count); } @@ -463,8 +429,6 @@ static ssize_t store_remote_mac(struct netconsole_target *nt, size_t count) { u8 remote_mac[ETH_ALEN]; - char *p = (char *) buf; - int i; if (nt->enabled) { printk(KERN_ERR "netconsole: target (%s) is enabled, " @@ -473,23 +437,13 @@ static ssize_t store_remote_mac(struct netconsole_target *nt, return -EINVAL; } - for (i = 0; i < ETH_ALEN - 1; i++) { - remote_mac[i] = simple_strtoul(p, &p, 16); - if (*p != ':') - goto invalid; - p++; - } - remote_mac[ETH_ALEN - 1] = simple_strtoul(p, &p, 16); - if (*p && (*p != '\n')) - goto invalid; - + if (!mac_pton(buf, remote_mac)) + return -EINVAL; + if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n') + return -EINVAL; memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN); return strnlen(buf, count); - -invalid: - printk(KERN_ERR "netconsole: invalid input\n"); - return -EINVAL; } /* @@ -667,11 +621,10 @@ static int netconsole_netdev_event(struct notifier_block *this, bool stopped = false; if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER || - event == NETDEV_BONDING_DESLAVE || event == NETDEV_GOING_DOWN)) + event == NETDEV_RELEASE || event == NETDEV_JOIN)) goto done; spin_lock_irqsave(&target_list_lock, flags); -restart: list_for_each_entry(nt, &target_list, list) { netconsole_target_get(nt); if (nt->np.dev == dev) { @@ -679,6 +632,8 @@ restart: case NETDEV_CHANGENAME: strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); break; + case NETDEV_RELEASE: + case NETDEV_JOIN: case NETDEV_UNREGISTER: /* * rtnl_lock already held @@ -693,11 +648,7 @@ restart: dev_put(nt->np.dev); nt->np.dev = NULL; netconsole_target_put(nt); - goto restart; } - /* Fall through */ - case NETDEV_GOING_DOWN: - case NETDEV_BONDING_DESLAVE: nt->enabled = 0; stopped = true; break; @@ -706,10 +657,21 @@ restart: netconsole_target_put(nt); } spin_unlock_irqrestore(&target_list_lock, flags); - if (stopped && (event == NETDEV_UNREGISTER || event == NETDEV_BONDING_DESLAVE)) + if (stopped) { printk(KERN_INFO "netconsole: network logging stopped on " - "interface %s as it %s\n", dev->name, - event == NETDEV_UNREGISTER ? "unregistered" : "released slaves"); + "interface %s as it ", dev->name); + switch (event) { + case NETDEV_UNREGISTER: + printk(KERN_CONT "unregistered\n"); + break; + case NETDEV_RELEASE: + printk(KERN_CONT "released slaves\n"); + break; + case NETDEV_JOIN: + printk(KERN_CONT "is joining a master device\n"); + break; + } + } done: return NOTIFY_DONE; |