|
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