Skip to content

Commit

Permalink
bonding: send learning packets for vlans on slave
Browse files Browse the repository at this point in the history
There was a regression at some point from the intended functionality of
commit f60c370 ("bonding: Fix alb mode to only use first level
vlans.")

Given the return value vlan_get_encap_level() we need to store the nest
level of the bond device, and then compare the vlan's encap level to
this. Without this, this check always fails and learning packets are
never sent.

In addition, this same commit caused a regression in the behavior of
balance_alb, which requires learning packets be sent for all interfaces
using the slave's mac in order to load balance properly. For vlan's
that have not set a user mac, we can send after checking one bit.
Otherwise we need send the set mac, albeit defeating rx load balancing
for that vlan.

Signed-off-by: Debabrata Banerjee <dbanerje@akamai.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Debabrata Banerjee authored and David S. Miller committed May 11, 2018
1 parent 4fa8667 commit 21706ee
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 5 deletions.
13 changes: 8 additions & 5 deletions drivers/net/bonding/bond_alb.c
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,10 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[],
skb->priority = TC_PRIO_CONTROL;
skb->dev = slave->dev;

netdev_dbg(slave->bond->dev,
"Send learning packet: dev %s mac %pM vlan %d\n",
slave->dev->name, mac_addr, vid);

if (vid)
__vlan_hwaccel_put_tag(skb, vlan_proto, vid);

Expand All @@ -965,14 +969,13 @@ static int alb_upper_dev_walk(struct net_device *upper, void *_data)
u8 *mac_addr = data->mac_addr;
struct bond_vlan_tag *tags;

if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0) {
if (strict_match &&
ether_addr_equal_64bits(mac_addr,
upper->dev_addr)) {
if (is_vlan_dev(upper) &&
bond->nest_level == vlan_get_encap_level(upper) - 1) {
if (upper->addr_assign_type == NET_ADDR_STOLEN) {
alb_send_lp_vid(slave, mac_addr,
vlan_dev_vlan_proto(upper),
vlan_dev_vlan_id(upper));
} else if (!strict_match) {
} else {
alb_send_lp_vid(slave, upper->dev_addr,
vlan_dev_vlan_proto(upper),
vlan_dev_vlan_id(upper));
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1738,6 +1738,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
if (bond_mode_uses_xmit_hash(bond))
bond_update_slave_arr(bond, NULL);

bond->nest_level = dev_get_nest_level(bond_dev);

netdev_info(bond_dev, "Enslaving %s as %s interface with %s link\n",
slave_dev->name,
bond_is_active_slave(new_slave) ? "an active" : "a backup",
Expand Down
1 change: 1 addition & 0 deletions include/net/bonding.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ struct bonding {
struct slave __rcu *primary_slave;
struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */
bool force_primary;
u32 nest_level;
s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
int (*recv_probe)(const struct sk_buff *, struct bonding *,
struct slave *);
Expand Down

0 comments on commit 21706ee

Please sign in to comment.