|
29 | 29 | #include <linux/slab.h>
|
30 | 30 | #include <linux/export.h>
|
31 | 31 | #include <linux/if_vlan.h>
|
| 32 | +#include <net/dsa.h> |
32 | 33 | #include <net/tcp.h>
|
33 | 34 | #include <net/udp.h>
|
34 | 35 | #include <net/addrconf.h>
|
@@ -657,22 +658,35 @@ EXPORT_SYMBOL_GPL(__netpoll_setup);
|
657 | 658 |
|
658 | 659 | int netpoll_setup(struct netpoll *np)
|
659 | 660 | {
|
660 |
| - struct net_device *ndev = NULL; |
| 661 | + struct net_device *ndev = NULL, *dev = NULL; |
| 662 | + struct net *net = current->nsproxy->net_ns; |
661 | 663 | struct in_device *in_dev;
|
662 | 664 | int err;
|
663 | 665 |
|
664 | 666 | rtnl_lock();
|
665 |
| - if (np->dev_name[0]) { |
666 |
| - struct net *net = current->nsproxy->net_ns; |
| 667 | + if (np->dev_name[0]) |
667 | 668 | ndev = __dev_get_by_name(net, np->dev_name);
|
668 |
| - } |
| 669 | + |
669 | 670 | if (!ndev) {
|
670 | 671 | np_err(np, "%s doesn't exist, aborting\n", np->dev_name);
|
671 | 672 | err = -ENODEV;
|
672 | 673 | goto unlock;
|
673 | 674 | }
|
674 | 675 | dev_hold(ndev);
|
675 | 676 |
|
| 677 | + /* bring up DSA management network devices up first */ |
| 678 | + for_each_netdev(net, dev) { |
| 679 | + if (!netdev_uses_dsa(dev)) |
| 680 | + continue; |
| 681 | + |
| 682 | + err = dev_change_flags(dev, dev->flags | IFF_UP, NULL); |
| 683 | + if (err < 0) { |
| 684 | + np_err(np, "%s failed to open %s\n", |
| 685 | + np->dev_name, dev->name); |
| 686 | + goto put; |
| 687 | + } |
| 688 | + } |
| 689 | + |
676 | 690 | if (netdev_master_upper_dev_get(ndev)) {
|
677 | 691 | np_err(np, "%s is a slave device, aborting\n", np->dev_name);
|
678 | 692 | err = -EBUSY;
|
|
0 commit comments