ofproto-dpif: Flush MACs for deleted ports from every bridge.
authorBen Pfaff <blp@nicira.com>
Fri, 16 Dec 2011 18:02:51 +0000 (10:02 -0800)
committerBen Pfaff <blp@nicira.com>
Fri, 16 Dec 2011 18:03:10 +0000 (10:03 -0800)
commitb44a10b74a1147029f0bdf7d14cd059ba2dfb454
treefc070db076025e6ec848dd8f37e2248f0842e6ca
parent85807ff311923146b46dd3cfc11fdc7a8972612e
ofproto-dpif: Flush MACs for deleted ports from every bridge.

Consider this scenario: two hypervisors HV-1 and HV-2, connected to a
common physical network over SLB bonds.  Two virtual machines VM-1 and VM-2
are both running on HV-1.  Patch ports are in use, so that each VM is not
connected to a bridge with a physical Ethernet port but is actually one
virtual "hop" away across a patch port to a second OVS bridge.  VM-2 is
running a "ping" process directed at VM-1.

Now migrate VM-1 to HV-2.  Suppose that VM-1 fails to send out a gratuitous
ARP following migration, or that the gratuitous ARPs are lost, e.g. because
they are sent before the OpenFlow controller manages to populate the flow
table with rules to allow the VM's traffic

Now we are in a situation where HV-1 has learned that VM-1 is local and
HV-2 has learned that VM-1 is on its bond; both are wrong.  One would
expect the problem to resolve itself as soon the VM-1 sends out its first
packet.  However, SLB bonds (for important reasons documented in
vswitchd/INTERNALS) are very reluctant to learn that a currently local MAC
is actually on the bond: the only ways to learn that the MAC is on the bond
are to receive a gratuitous ARP (which we won't, since they were dropped)
or for the MAC learning entry to expire after 60 seconds. This means that
VM-1 can send out as much ordinary traffic as it wants (even ARP requests
and other broadcasts) but HV-1 will drop all of it at the physical Ethernet
since it believes that VM-1 is local.

(In an ordinary setup with a single bridge, HV-1 would have unlearned the
address for VM-1 when VM-1's port was deleted, but that didn't happen
because HV-1 only learned that VM-1 was on the patch port that leads to the
integration bridge.  The patch port didn't get deleted.)

HV-2 does quickly learn that VM-1 is now local.  SLB bonds are only
reluctant to learn that something they think is local is actually on the
bond, not the reverse.

This commit attempts to work around the problem by flushing the MAC
associated with a port from *every* bridge when a port is deleted.

This commit demonstrates yet another good reason not to use SLB bonds.

Build and unit tested only.
Bug #7978.
Bug #7687.

Signed-off-by: Ben Pfaff <blp@nicira.com>
ofproto/ofproto-dpif.c
tests/ofproto-dpif.at