aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netconsole.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netconsole.c')
-rw-r--r--drivers/net/netconsole.c112
1 files changed, 41 insertions, 71 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index dfb67eb2a94b..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,7 +621,7 @@ 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);
@@ -678,18 +632,23 @@ static int netconsole_netdev_event(struct notifier_block *this,
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
*/
if (nt->np.dev) {
+ spin_unlock_irqrestore(
+ &target_list_lock,
+ flags);
__netpoll_cleanup(&nt->np);
+ spin_lock_irqsave(&target_list_lock,
+ flags);
dev_put(nt->np.dev);
nt->np.dev = NULL;
+ netconsole_target_put(nt);
}
- /* Fall through */
- case NETDEV_GOING_DOWN:
- case NETDEV_BONDING_DESLAVE:
nt->enabled = 0;
stopped = true;
break;
@@ -698,10 +657,21 @@ static int netconsole_netdev_event(struct notifier_block *this,
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;