diff options
author | Vlad Yasevich <vyasevic@redhat.com> | 2014-06-05 00:23:38 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-05 02:13:54 +0400 |
commit | 14af9963ba1e5e8400c9de9267bdcab895109f6a (patch) | |
tree | 55e2be9506708df787f2158e11454b8ac2b7c36a /drivers/net/bonding/bond_alb.c | |
parent | 4c9912556867bf89e7bb6946fd218a40b1d12139 (diff) | |
download | linux-14af9963ba1e5e8400c9de9267bdcab895109f6a.tar.xz |
bonding: Support macvlans on top of tlb/rlb mode bonds
To make TLB mode work, the patch allows learning packets
to be sent using mac addresses assigned to macvlan devices,
also taking into an account vlans that may be between the
bond and macvlan device.
To make RLB work, all we have to do is accept ARP packets
for addresses added to the bond dev->uc list. Since RLB
mode will take care to update the peers directly with
correct mac addresses, learning packets for these addresses
do not have be send to switch.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 7bbbf1ca0887..76c0dade233f 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -755,7 +755,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) /* Don't modify or load balance ARPs that do not originate locally * (e.g.,arrive via a bridge). */ - if (!bond_slave_has_mac_rcu(bond, arp->mac_src)) + if (!bond_slave_has_mac_rx(bond, arp->mac_src)) return NULL; if (arp->op_code == htons(ARPOP_REPLY)) { @@ -1039,11 +1039,14 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], struct bonding *bond = bond_get_bond_by_slave(slave); struct net_device *upper; struct list_head *iter; + struct bond_vlan_tag tags[BOND_MAX_VLAN_ENCAP]; /* send untagged */ alb_send_lp_vid(slave, mac_addr, 0, 0); - /* loop through vlans and send one packet for each */ + /* loop through all devices and see if we need to send a packet + * for that device. + */ rcu_read_lock(); netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0) { @@ -1059,6 +1062,16 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], vlan_dev_vlan_id(upper)); } } + + /* If this is a macvlan device, then only send updates + * when strict_match is turned off. + */ + if (netif_is_macvlan(upper) && !strict_match) { + memset(tags, 0, sizeof(tags)); + bond_verify_device_path(bond->dev, upper, tags); + alb_send_lp_vid(slave, upper->dev_addr, + tags[0].vlan_proto, tags[0].vlan_id); + } } rcu_read_unlock(); } @@ -1560,8 +1573,10 @@ void bond_alb_monitor(struct work_struct *work) /* If updating current_active, use all currently * user mac addreses (!strict_match). Otherwise, only * use mac of the slave device. + * In RLB mode, we always use strict matches. */ - strict_match = (slave != bond->curr_active_slave); + strict_match = (slave != bond->curr_active_slave || + bond_info->rlb_enabled); alb_send_learning_packets(slave, slave->dev->dev_addr, strict_match); } |