Skip to content

Commit

Permalink
net: Have netpoll bring-up DSA management interface
Browse files Browse the repository at this point in the history
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 728c020 ("net: ipv4: handle DSA enabled
master network devices"), with the network namespace scope being
restricted to that of the process configuring netpoll.

Fixes: 04ff53f ("net: dsa: Add netconsole support")
Tested-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Link: https://lore.kernel.org/r/20201117035236.22658-1-f.fainelli@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
ffainelli authored and kuba-moo committed Nov 18, 2020
1 parent 3a36060 commit 1532b97
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions net/core/netpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,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>
Expand Down Expand Up @@ -657,22 +658,35 @@ 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;
goto unlock;
}
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, NULL);
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;
Expand Down

0 comments on commit 1532b97

Please sign in to comment.