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
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. */