From 3a55ef14838f9552fa824b90599aa2a6493bb04a Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Mon, 12 Oct 2009 13:09:51 -0700 Subject: [PATCH] bonding: Drop unicast packets which have a different learned port. Drop packets received on a bond port if we have learned a different source port for that MAC. We were already doing this for multicast packets but extend the logic to unicast packets as well since the same situation can occur if the connected switch has not learned the MAC address and is flooding. Otherwise vSwitch will learn the bond port as the source of that MAC. Bug #2167 --- vswitchd/INTERNALS | 12 ++++++------ vswitchd/bridge.c | 44 +++++++++++++++++++------------------------- 2 files changed, 25 insertions(+), 31 deletions(-) diff --git a/vswitchd/INTERNALS b/vswitchd/INTERNALS index 49a41588..5873dc17 100644 --- a/vswitchd/INTERNALS +++ b/vswitchd/INTERNALS @@ -83,12 +83,12 @@ received on other slaves are dropped. Otherwise, every multicast packet would be duplicated, once for every bond slave, because the physical switch attached to the bond will flood those packets. -Bonding also drops some multicast packets received on the active -slave: those for the vswitch has learned that the packet's MAC is on a -port other than the bond port itself. This is because it is likely -that the vswitch itself sent the multicast packet out the bond port, -on a slave other than the active slave, and is now receiving the -packet back on the active slave. However, the vswitch makes an +Bonding also drops received packets when the vswitch has learned that +the packet's MAC is on a port other than the bond port itself. This is +because it is likely that the vswitch itself sent the packet out the +bond port on a different slave and is now receiving the packet back. +This occurs when the packet is multicast or the physical switch has not +yet learned the MAC and is flooding it. However, the vswitch makes an exception to this rule for broadcast ARP replies, which indicate that the MAC has moved to another switch, probably due to VM migration. (ARP replies are normally unicast, so this exception does not match diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 3ee964dd..7ce1f25f 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1897,33 +1897,27 @@ process_flow(struct bridge *br, const flow_t *flow, goto done; } - /* Multicast (and broadcast) packets on bonds need special attention, to - * avoid receiving duplicates. */ - if (in_port->n_ifaces > 1 && eth_addr_is_multicast(flow->dl_dst)) { - *tags |= in_port->active_iface_tag; - if (in_port->active_iface != in_iface->port_ifidx) { - /* Drop all multicast packets on inactive slaves. */ - goto done; - } else { - /* Drop all multicast packets for which we have learned a different - * input port, because we probably sent the packet on one slave - * and got it back on the active slave. Broadcast ARP replies are - * an exception to this rule: the host has moved to another - * switch. */ - int src_idx = mac_learning_lookup(br->ml, flow->dl_src, vlan); - if (src_idx != -1 && src_idx != in_port->port_idx) { - if (packet) { - if (!is_bcast_arp_reply(flow, packet)) { - goto done; - } - } else { - /* No way to know whether it's an ARP reply, because the - * flow entry doesn't include enough information and we - * don't have a packet. Punt. */ - return false; - } + /* Packets received on bonds need special attention to avoid duplicates. */ + if (in_port->n_ifaces > 1) { + int src_idx; + + if (eth_addr_is_multicast(flow->dl_dst)) { + *tags |= in_port->active_iface_tag; + if (in_port->active_iface != in_iface->port_ifidx) { + /* Drop all multicast packets on inactive slaves. */ + goto done; } } + + /* Drop all packets for which we have learned a different input + * port, because we probably sent the packet on one slave and got + * it back on the other. Broadcast ARP replies are an exception + * to this rule: the host has moved to another switch. */ + src_idx = mac_learning_lookup(br->ml, flow->dl_src, vlan); + if (src_idx != -1 && src_idx != in_port->port_idx && + (!packet || !is_bcast_arp_reply(flow, packet))) { + goto done; + } } /* MAC learning. */ -- 2.30.2