mainline inclusion from mainline-v6.0 commit d5410ac7b0baeca91cf73ff5241d35998ecc8c9e category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5UYT6 CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/dr...
-----------------------------------------------------------------
In my test, balance-alb bonding with two slaves eth0 and eth1, and then Bond0.150 is created with vlan id attached bond0. After adding bond0.150 into one linux bridge, I noted that Bond0, bond0.150 and bridge were assigned to the same MAC as eth0. Once bond0.150 receives a packet whose dest IP is bridge's and dest MAC is eth1's, the linux bridge will not match eth1's MAC entry in FDB, and not handle it as expected. The patch fix the issue, and diagram as below:
eth1(mac:eth1_mac)--bond0(balance-alb,mac:eth0_mac)--eth0(mac:eth0_mac) | bond0.150(mac:eth0_mac) | bridge(ip:br_ip, mac:eth0_mac)--other port
Suggested-by: Hu Yadi huyd12@chinatelecom.cn Signed-off-by: Sun Shouxin sunshouxin@chinatelecom.cn Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sun Shouxin sunshouxin@chinatelecom.cn # openEuler_contributor Signed-off-by: Ctyun Kernel ctyuncommiter01@chinatelecom.cn # openEuler_contributor --- drivers/net/bonding/bond_alb.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 856efe8..f493bcf 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -665,6 +665,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) { struct slave *tx_slave = NULL; + struct net_device *dev; struct arp_pkt *arp;
if (!pskb_network_may_pull(skb, sizeof(*arp))) @@ -677,6 +678,12 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) if (!bond_slave_has_mac_rx(bond, arp->mac_src)) return NULL;
+ dev = ip_dev_find(dev_net(bond->dev), arp->ip_src); + if (dev) { + if (netif_is_bridge_master(dev)) + return NULL; + } + if (arp->op_code == htons(ARPOP_REPLY)) { /* the arp must be sent on the selected rx channel */ tx_slave = rlb_choose_channel(skb, bond, arp);