<div>> Hello:</div><div><includetail><div style="font:Verdana normal 14px;color:#000;"><div style="position:relative;">> <br>> As commented by Nate and Brian, and myself in [2] and [3], I prefer [2]. I understand this is a fix<br>> only for OVS, but:<br>> - It limits the solution to the external GW port plugging process, where the problem appears.<br>> - The second solution, as you commented, can introduce a race condition between the L3 agent and<br>> keepalived process, and a possible delay in the HA switch process.<br>> <br>> Regards.<br><br>We have run that code [3] for a long time, and no state change delay was seen.</div><div style="position:relative;">So I may wonder is there any test results show a delay? <br><br>On Fri, 2020-03-20 at 14:40 -0400, Brian Haley wrote:<br>> On 3/20/20 11:57 AM, Nate Johnston wrote:<br>> > On Fri, Mar 20, 2020 at 03:37:49PM +0100, Slawek Kaplonski wrote:<br>> > > Hi,<br>> > > <br>> > > We have bug [1] to solve. Basically, when node which is backup node for some<br>> > > router, connectivity to external gateway may be broken for some time. It's like<br>> > > that because when host is up and L3 agent is configuring qrouter namespace, it<br>> > > flush all IPv6 addresses from the qg- interface. And due to that some MLDv2<br>> > > packets are sent from this interface which may cause that ToR switch will learn<br>> > > qg port's mac address on wrong (backup) node.<br>> > > <br>> > > This don't happens every time and for every router because it is a race between<br>> > > L3 agent and OVS agent. When L3 agent creates qg interface in br-int, it sets<br>> > > tag 4095 for it and traffic sent with such vlan tag is always dropped in br-int.<br>> > > So if L3 agent will flush IPv6 addresses before OVS agent wires the port and<br>> > > sets correct tag for it, then all is fine. But if OVS agent is first, then MLDv2<br>> > > packets are sent to the wire and there is this connectivity break.<br>> > > <br>> > > There are proposed 2 ways of fixing this:<br>> > >   - [2] which propsoes to add some kind of "communication" between L3 agent and<br>> > >     OVS agent and tell OVS agent that tag can be changed only after IPv6 config<br>> > >     is finished by L3 agent.</div><div style="position:relative;"><br></div><div style="position:relative;">What if ovs-agent has finished the port processing, and then L3 agent just set the port to "INTERNAL_STATUS_ACTIVE = "active"".</div><div style="position:relative;">I don't think the port will be processed again. So it will 4095 forever? Is that a race condition?</div><div style="position:relative;"><br>> > >     Downside of this solution is that it works for OVS agent only, Linuxbridge<br>> > >     agent may still hit the same issue. But plus is that after initial<br>> > >     configuration of the router, everything else regarding to failover is handled<br>> > >     by keepalived only - in same way like it is now.</div><div style="position:relative;"><br></div><div style="position:relative;">HA router failover is one case, add HA router a schedule instance (neutron l3-agent-router-add) to a new</div><div style="position:relative;">L3-agent is facing the same root cause of IPv6 related packets.</div><div style="position:relative;"><br>> > >   - [3] which sets qg NIC to be DOWN always on backup nodes. So when keepalived<br>> > >     failover active router to new node, L3 agent needs to come and switch<br>> > >     interfaces to be UP before it will work.<br>> > >     The plus of this solution is that it works for all OVS and<br>> > >     Linuxbridge L2 agents (and probably for others too) but downside is that<br>> > >     failover process is a bit longer and there may be potentially another race<br>> > >     condition between L3 agent and keepalived. Keepalived tries to sent gARP<br>> > >     packets after switch node to be active, first attempt will always fail as<br>> > >     interface is still DOWN. But keepalived will retry those gARPs after some<br>> > >     time and this should be fine if L3 agent will already bring interface to be<br>> > >     UP.</div><div style="position:relative;"><br></div><div style="position:relative;">This is what the patch <a href="https://review.opendev.org/#/c/712474/">https://review.opendev.org/#/c/712474/</a> is doing now.</div><div style="position:relative;"><div style="position:relative;">The keepalived will try to send 5 times garp (default value of vrrp_garp_master_repeat) after transition to</div><div style="position:relative;">MASTER. And there is a delay (vrrp_garp_interval) between gratuitous ARP messages sent on an interface</div><div style="position:relative;">(https://www.keepalived.org/manpage.html). The default value is zero that means if one get failed, try</div><div style="position:relative;">next time immediately. In some extreme situations the keepalived may get failed to send the garp</div><div style="position:relative;">packets out due to the device or underlay dataplane is not ready.</div></div><div style="position:relative;">Actually with the help of the fix [3] and related testing, we just found out the potential lacks of the Keepalived</div><div style="position:relative;">config options. So it should be a good change to tune it.</div><div style="position:relative;"><br></div><div style="position:relative;">So about the race condition I may say it was not seen locally. If there are any test results,</div><div style="position:relative;">that would be very useful for distinguishing problems.</div><div style="position:relative;"><br>> > <br>> > Personally I find [2] more appealing.  I think that if we find many linuxbridge<br>> > users hitting this issue then we can replicate the solution for linuxbridge at<br>> > that time, but until then let's not worry about it - the majority of users use<br>> > OVS.  And the gARP timegap for solution #3 to me seems like a possbility for<br>> > problems or downtime.</div><div style="position:relative;"><br></div><div style="position:relative;">Linux bridge driver meets the same issue. The driver is still alive, and for stable branches the fix is also worth to do.</div><div style="position:relative;">It is very simple to simulate the issue, just link up a veth pair device, you will dump the packets on the interface.</div><div style="position:relative;"><br></div><div style="position:relative;">> <br>> I would agree, it seemed easier to understand to me as well.<br>> <br>> -Brian</div><div style="position:relative;"><br></div><div style="position:relative;">For a running cloud you need to restart ovs-agent and l3-agent to achive the fix [2], and mostly the centralized</div><div style="position:relative;">network node may have tons of ports which will take significant time to "re-added" for the ovs-agent. And absolutely,</div><div style="position:relative;">restart time for L3-agent is also needed.</div><div style="position:relative;">And my opinions at the very beginning, the fix [2] is trying to expand the HA logical</div><div style="position:relative;">from L3 to L2, and introduce protential fail point in ovs-agent for HA routers. That could have some side-effect like unexpected code</div><div style="position:relative;">aggression on ovs-agent. Someday a guy may say: "I just changed the ovs-agent code, but why HA router does not work?"</div><div style="position:relative;"><br></div><div style="position:relative;">> <br>> > > Both patches are waiting for pretty long time in gerrit and I want to bring more<br>> > > visibility for both of them. Please check them and maybe You will have some<br>> > > opinions about which solution would be better and which we should go with.<br>> > > <br>> > > [1] https://bugs.launchpad.net/neutron/+bug/1859832<br>> > > [2] https://review.opendev.org/#/c/702856/<br>> > > [3] https://review.opendev.org/#/c/707406/<br>> > > <br>> > > -- <br>> > > Slawek Kaplonski<br>> > > Senior software engineer<br>> > > Red Hat<br>> > > <br>> > > <br><br>Seems we are repeating the discuss here, why not back to gerrit? since all the code links are pasted here.<br><br></div><div style="position:relative;">Regards,</div><div style="position:relative;">LIU Yulong</div></div><!--<![endif]--></includetail></div>