]>
Commit | Line | Data |
---|---|---|
0ee3da53 GKH |
1 | From foo@baz Sat Apr 20 16:43:09 CEST 2019 |
2 | From: Hangbin Liu <liuhangbin@gmail.com> | |
3 | Date: Mon, 8 Apr 2019 16:45:17 +0800 | |
4 | Subject: team: set slave to promisc if team is already in promisc mode | |
5 | ||
6 | From: Hangbin Liu <liuhangbin@gmail.com> | |
7 | ||
8 | [ Upstream commit 43c2adb9df7ddd6560fd3546d925b42cef92daa0 ] | |
9 | ||
10 | After adding a team interface to bridge, the team interface will enter | |
11 | promisc mode. Then if we add a new slave to team0, the slave will keep | |
12 | promisc off. Fix it by setting slave to promisc on if team master is | |
13 | already in promisc mode, also do the same for allmulti. | |
14 | ||
15 | v2: add promisc and allmulti checking when delete ports | |
16 | ||
17 | Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device") | |
18 | Signed-off-by: Hangbin Liu <liuhangbin@gmail.com> | |
19 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
21 | --- | |
22 | drivers/net/team/team.c | 26 ++++++++++++++++++++++++++ | |
23 | 1 file changed, 26 insertions(+) | |
24 | ||
25 | --- a/drivers/net/team/team.c | |
26 | +++ b/drivers/net/team/team.c | |
27 | @@ -1247,6 +1247,23 @@ static int team_port_add(struct team *te | |
28 | goto err_option_port_add; | |
29 | } | |
30 | ||
31 | + /* set promiscuity level to new slave */ | |
32 | + if (dev->flags & IFF_PROMISC) { | |
33 | + err = dev_set_promiscuity(port_dev, 1); | |
34 | + if (err) | |
35 | + goto err_set_slave_promisc; | |
36 | + } | |
37 | + | |
38 | + /* set allmulti level to new slave */ | |
39 | + if (dev->flags & IFF_ALLMULTI) { | |
40 | + err = dev_set_allmulti(port_dev, 1); | |
41 | + if (err) { | |
42 | + if (dev->flags & IFF_PROMISC) | |
43 | + dev_set_promiscuity(port_dev, -1); | |
44 | + goto err_set_slave_promisc; | |
45 | + } | |
46 | + } | |
47 | + | |
48 | netif_addr_lock_bh(dev); | |
49 | dev_uc_sync_multiple(port_dev, dev); | |
50 | dev_mc_sync_multiple(port_dev, dev); | |
51 | @@ -1263,6 +1280,9 @@ static int team_port_add(struct team *te | |
52 | ||
53 | return 0; | |
54 | ||
55 | +err_set_slave_promisc: | |
56 | + __team_option_inst_del_port(team, port); | |
57 | + | |
58 | err_option_port_add: | |
59 | team_upper_dev_unlink(team, port); | |
60 | ||
61 | @@ -1308,6 +1328,12 @@ static int team_port_del(struct team *te | |
62 | ||
63 | team_port_disable(team, port); | |
64 | list_del_rcu(&port->list); | |
65 | + | |
66 | + if (dev->flags & IFF_PROMISC) | |
67 | + dev_set_promiscuity(port_dev, -1); | |
68 | + if (dev->flags & IFF_ALLMULTI) | |
69 | + dev_set_allmulti(port_dev, -1); | |
70 | + | |
71 | team_upper_dev_unlink(team, port); | |
72 | netdev_rx_handler_unregister(port_dev); | |
73 | team_port_disable_netpoll(port); |