Wed, Mar 25, 2009 at 02:40:43PM CET, dada1@xxxxxxxxxxxxx wrote: >Jiri Pirko a écrit : >> (resend) >> >> Hi all. >> >> The problem is described in following bugzilla: >> https://bugzilla.redhat.com/show_bug.cgi?id=487763 >> >> Basically here's what's going on. In every mode, bonding interface uses the same >> mac address for all enslaved devices. Except for mode balance-alb. When you put >> this kind of bond device into a bridge it will only add one of mac adresses into >> a hash list of mac addresses, say X. This mac address is marked as local. But >> this bonding interface also has mac address Y. Now then packet arrives with >> destination address Y, this address is not marked as local and the packed looks >> like it needs to be forwarded. This packet is then lost which is wrong. >> >> Notice that interfaces can be added and removed from bond while it is in bridge. >> >> This patch solves the situation in the bonding without touching bridge code, >> as Patrick suggested. For every incoming frame to bonding it searches the >> destination address in slaves list and if any of slave addresses matches, it >> rewrites the address in frame by the adress of bonding master. This ensures that >> all frames comming thru the bonding in alb mode have the same address. >> >> Jirka >> >> >> Signed-off-by: Jiri Pirko <jpirko@xxxxxxxxxx> >> >> diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c >> index 27fb7f5..2838be0 100644 >> --- a/drivers/net/bonding/bond_alb.c >> +++ b/drivers/net/bonding/bond_alb.c >> @@ -1762,6 +1762,26 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) >> return 0; >> } >> >> +void bond_alb_change_dest(struct sk_buff *skb) >> +{ >> + struct net_device *bond_dev = skb->dev; >> + struct bonding *bond = netdev_priv(bond_dev); >> + unsigned char *dest = eth_hdr(skb)->h_dest; >> + struct slave *slave; >> + int i; >> + >> + if (!memcmp(dest, bond_dev->dev_addr, ETH_ALEN)) >> + return; >> + read_lock(&bond->lock); > > >Its a pity bonding doesnt use RCU and needs this read_lock(&bond->lock) Sure it is... > > >> + bond_for_each_slave(bond, slave, i) { >> + if (!memcmp(slave->dev->dev_addr, dest, ETH_ALEN)) { > >compare_ether_addr() (or even better compare_ether_addr_64bits()) instead of memcmp() ? Okay, I'll use compare_ether_addr_64bits and do the repost later on... > >> + memcpy(dest, bond_dev->dev_addr, ETH_ALEN); >> + break; >> + } >> + } >> + read_unlock(&bond->lock); >> +} >> + > _______________________________________________ Bridge mailing list Bridge@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/bridge