Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3722985b authored by Florian Fainelli's avatar Florian Fainelli Committed by Greg Kroah-Hartman
Browse files

net: Have netpoll bring-up DSA management interface



[ Upstream commit 1532b9778478577152201adbafa7738b1e844868 ]

DSA network devices rely on having their DSA management interface up and
running otherwise their ndo_open() will return -ENETDOWN. Without doing
this it would not be possible to use DSA devices as netconsole when
configured on the command line. These devices also do not utilize the
upper/lower linking so the check about the netpoll device having upper
is not going to be a problem.

The solution adopted here is identical to the one done for
net/ipv4/ipconfig.c with 728c0208 ("net: ipv4: handle DSA enabled
master network devices"), with the network namespace scope being
restricted to that of the process configuring netpoll.

Fixes: 04ff53f9 ("net: dsa: Add netconsole support")
Tested-by: default avatarVladimir Oltean <olteanv@gmail.com>
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Link: https://lore.kernel.org/r/20201117035236.22658-1-f.fainelli@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 41456415
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/if_vlan.h>
#include <net/dsa.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/addrconf.h>
@@ -661,15 +662,15 @@ EXPORT_SYMBOL_GPL(__netpoll_setup);

int netpoll_setup(struct netpoll *np)
{
	struct net_device *ndev = NULL;
	struct net_device *ndev = NULL, *dev = NULL;
	struct net *net = current->nsproxy->net_ns;
	struct in_device *in_dev;
	int err;

	rtnl_lock();
	if (np->dev_name[0]) {
		struct net *net = current->nsproxy->net_ns;
	if (np->dev_name[0])
		ndev = __dev_get_by_name(net, np->dev_name);
	}

	if (!ndev) {
		np_err(np, "%s doesn't exist, aborting\n", np->dev_name);
		err = -ENODEV;
@@ -677,6 +678,19 @@ int netpoll_setup(struct netpoll *np)
	}
	dev_hold(ndev);

	/* bring up DSA management network devices up first */
	for_each_netdev(net, dev) {
		if (!netdev_uses_dsa(dev))
			continue;

		err = dev_change_flags(dev, dev->flags | IFF_UP);
		if (err < 0) {
			np_err(np, "%s failed to open %s\n",
			       np->dev_name, dev->name);
			goto put;
		}
	}

	if (netdev_master_upper_dev_get(ndev)) {
		np_err(np, "%s is a slave device, aborting\n", np->dev_name);
		err = -EBUSY;