<div dir="ltr"><br><br>On Tue, Aug 20, 2019 at 4:57 PM Ben Pfaff &lt;<a href="mailto:blp@ovn.org">blp@ovn.org</a>&gt; wrote:<br>&gt;<br>&gt; Let me see if I&#39;m following this correctly.  This is what currently<br>&gt; happens:<br>&gt;<br>&gt; - HV1 needs a MAC address for an IP so it broadcasts an ARP request.<br>&gt;<br>&gt; - The port with the IP address, on HV2, causes the MAC_Binding to be<br>&gt;   inserted.<br>&gt;<br>&gt; - Every ovn-controller inserts an OF flow for the binding.  HV1 and<br>&gt;   perhaps other ovn-controllers use this flow to populate the MAC<br>&gt;   address for subsequent packets destined to the IP address in question.<br>&gt;<br>&gt; This proposal augments that with:<br>&gt;<br>&gt; - After a while, the binding goes idle and isn&#39;t used.  The<br>&gt;   ovn-controllers gradually notice this and delete their OF flows for<br>&gt;   it.<br>&gt;<br>&gt; - HV3 eventually needs the binding again.  It broadcasts an ARP request.<br>&gt;<br>&gt; - The port with the IP address causes the MAC_Binding to be inserted.<br>&gt;   This might still be on HV2 if the port hasn&#39;t moved, or it might be on<br>&gt;   HV4 if it has.<br>&gt;<br>&gt; Is that what you mean?  It might work OK.<br>&gt;<br>&gt; Please do update the lifetime description in ovn-sb(5) under the<br>&gt; MAC_Binding table regardless of what you implement.<br>&gt;<br>&gt; Thanks,<br>&gt;<br>&gt; Ben.<br>&gt;<br>&gt; On Tue, Aug 20, 2019 at 09:03:57AM +0200, Daniel Alvarez Sanchez wrote:<br>&gt; &gt; Hi folks,<br>&gt; &gt;<br><div>&gt; &gt; Reviving this thread as we&#39;re seeing this more and more problematic.</div>&gt; &gt; Combining the ideas mentioned up thread, Dumitru, Numan, Lucas and I<br>&gt; &gt; had some internal discussion where we came up with a possible approach<br>&gt; &gt; and we&#39;d love to get feedback from you:<br>&gt; &gt;<br>&gt; &gt; - Local ovn-controller will always insert an OF rule per MAC_Binding<br>&gt; &gt; entry to match on src_ip + src_mac that will be sampled with a meter<br>&gt; &gt; to ovn-controller.<br>&gt; &gt; - When ovn-controller sees that one entry has not been hit &quot;for a<br>&gt; &gt; while&quot;, it&#39;ll delete the OpenFlow rule in table 65 that fills the<br><div>&gt; &gt; eth.dst field with the MAC_Binding info.</div><div><br></div><div>I assume the rules in table 65 can be &quot;extended&quot; for this purpose, instead of adding extra rules for this.<br></div><div><br></div>&gt; &gt; - This will result in further ARP requests from the instance(s) that<br>&gt; &gt; will refresh the MAC_Binding entries in the database.<br>&gt; &gt;<br>&gt; &gt; This could make troubleshooting a bit harder so at some point it&#39;ll be<br>&gt; &gt; great to have a mechanism in OVS where we could disable a flow instead<br>&gt; &gt; of deleting it. This way, one can tell that the flows in table 65 have<br><div>&gt; &gt; been disabled due to the aging mechanism in the local node.</div><div><br></div><div>Sorry that I didn&#39;t understand this. Why do you want the flow being disabled instead of deleted? I think if we want to avoid stale entries, we do want to delete them, so that the stale data doesn&#39;t occupy the space in flow table, neither in SB DB. It may be ok to add debug log for deleting a aged entry in ovn-controller, for trouble shooting purpose?<br></div><div><br></div>&gt; &gt;<br>&gt; &gt; Thoughts? Is there any performance consideration regarding the extra<br><div>&gt; &gt; flows and meters?</div><div><br></div><div>Are you proposing shared meters or one meter per mac-binding? If it is per mac-binding, I would be worried about the scalability considering that we may have &gt;10k of mac-bindings. Or should I be worried? Maybe Justin and Ben can comment on the meter scalability. If it is a concern, I would suggest the feature be configurable (i.e. enable/disable), so that it can be enabled in environments where aging is required but number of mac-bindings are not very high.<br></div><div><br></div>&gt; &gt;<br>&gt; &gt; Thanks a lot!<br>&gt; &gt; Daniel<br>&gt; &gt;<br>&gt; &gt;<br>&gt; &gt; On Tue, Jul 9, 2019 at 7:19 AM Ben Pfaff &lt;<a href="mailto:blp@ovn.org">blp@ovn.org</a>&gt; wrote:<br>&gt; &gt; &gt;<br>&gt; &gt; &gt; On Mon, Jul 08, 2019 at 06:19:23PM -0700, Han Zhou wrote:<br>&gt; &gt; &gt; &gt; On Thu, Jun 27, 2019 at 6:44 AM Ben Pfaff &lt;<a href="mailto:blp@ovn.org">blp@ovn.org</a>&gt; wrote:<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt; On Tue, Jun 25, 2019 at 01:05:21PM +0200, Daniel Alvarez Sanchez wrote:<br>&gt; &gt; &gt; &gt; &gt; &gt; Lately we&#39;ve been trying to solve certain issues related to stale<br>&gt; &gt; &gt; &gt; &gt; &gt; entries in the MAC_Binding table (e.g. [0]). On the other hand, for<br>&gt; &gt; &gt; &gt; &gt; &gt; the OpenStack + Octavia (Load Balancing service) use case, we see that<br>&gt; &gt; &gt; &gt; &gt; &gt; a reused VIP can be as well affected by stale entries in this table<br>&gt; &gt; &gt; &gt; &gt; &gt; due to the fact that it&#39;s never bound to a VIF so ovn-controller won&#39;t<br>&gt; &gt; &gt; &gt; &gt; &gt; claim it and send the GARPs to update the neighbors.<br>&gt; &gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt; &gt; I&#39;m not sure if other scenarios may suffer from this issue but seems<br>&gt; &gt; &gt; &gt; &gt; &gt; reasonable to have an aging mechanism (as we discussed at some point<br>&gt; &gt; &gt; &gt; &gt; &gt; in the past) that makes unused/old entries to expire. After talking to<br>&gt; &gt; &gt; &gt; &gt; &gt; Numan on IRC, since a new pinctrl thread has been introduced recently<br>&gt; &gt; &gt; &gt; &gt; &gt; [1], it&#39;d be nice to implement this aging mechanism there.<br>&gt; &gt; &gt; &gt; &gt; &gt; At the same time we&#39;d be also reducing the amount of entries for long<br>&gt; &gt; &gt; &gt; &gt; &gt; lived systems as it&#39;d grow indefinitely.<br>&gt; &gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt; &gt; Any thoughts?<br>&gt; &gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt; &gt; Thanks!<br>&gt; &gt; &gt; &gt; &gt; &gt; Daniel<br>&gt; &gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt; &gt; PS. With regards to the &#39;unused&#39; vs &#39;old&#39; entries I think it has to be<br>&gt; &gt; &gt; &gt; &gt; &gt; &#39;old&#39; rather than &#39;unused&#39; as I don&#39;t see a way to reset the TTL of a<br>&gt; &gt; &gt; &gt; &gt; &gt; MAC_Binding entry when we see packets coming. The implication is that<br>&gt; &gt; &gt; &gt; &gt; &gt; we&#39;ll be seeing ARPs sent out more often when perhaps they&#39;re not<br>&gt; &gt; &gt; &gt; &gt; &gt; needed. This also leads to the discussion of making the cache timeout<br>&gt; &gt; &gt; &gt; &gt; &gt; configurable.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt; I&#39;ve always considered the MAC_Binding implementation incomplete because<br>&gt; &gt; &gt; &gt; &gt; of this issue and others.  ovn/TODO.rst says:<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;     * Dynamic IP to MAC binding enhancements.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;       OVN has basic support for establishing IP to MAC bindings<br>&gt; &gt; &gt; &gt; dynamically, using<br>&gt; &gt; &gt; &gt; &gt;       ARP.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;       * Ratelimiting.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;         From casual observation, Linux appears to generate at most one<br>&gt; &gt; &gt; &gt; ARP per<br>&gt; &gt; &gt; &gt; &gt;         second per destination.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;         This might be supported by adding a new OVN logical action for<br>&gt; &gt; &gt; &gt; &gt;         rate-limiting.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;       * Tracking queries<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;          It&#39;s probably best to only record in the database responses to<br>&gt; &gt; &gt; &gt; queries<br>&gt; &gt; &gt; &gt; &gt;          actually issued by an L3 logical router, so somehow they have to<br>&gt; &gt; &gt; &gt; be<br>&gt; &gt; &gt; &gt; &gt;          tracked, probably by putting a tentative binding without a MAC<br>&gt; &gt; &gt; &gt; address<br>&gt; &gt; &gt; &gt; &gt;          into the database.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;       * Renewal and expiration.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;         Something needs to make sure that bindings remain valid and<br>&gt; &gt; &gt; &gt; expire those<br>&gt; &gt; &gt; &gt; &gt;         that become stale.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;         One way to do this might be to add some support for time to the<br>&gt; &gt; &gt; &gt; database<br>&gt; &gt; &gt; &gt; &gt;         server itself.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;       * Table size limiting.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;         The table of MAC bindings must not be allowed to grow<br>&gt; &gt; &gt; &gt; unreasonably large.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt;       * MTU handling (fragmentation on output)<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt; So, what do we do about it?  First, I think that adding support for time<br>&gt; &gt; &gt; &gt; &gt; to the database server is a terrible idea (even though I think I wrote<br>&gt; &gt; &gt; &gt; &gt; the above originally).  Let&#39;s not do that.  The following is some<br>&gt; &gt; &gt; &gt; &gt; &quot;thinking out loud&quot; on the subject.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt; I think there&#39;s a challenge around which ovn-controller should take care<br>&gt; &gt; &gt; &gt; &gt; of a given MAC_Binding.  We don&#39;t want every ovn-controller expiring<br>&gt; &gt; &gt; &gt; &gt; every binding.  Ideally, we want exactly one ovn-controller expiring a<br>&gt; &gt; &gt; &gt; &gt; binding.  One way would be to add an owner column (but it would be<br>&gt; &gt; &gt; &gt; &gt; better if we don&#39;t need it).<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; &gt; If we want to keep track of &quot;unused&quot; bindings, I can imagine a<br>&gt; &gt; &gt; &gt; &gt; statistical mechanism to do that.  Any user of a binding occasionally<br>&gt; &gt; &gt; &gt; &gt; and probabilistically changes a serial number column that we&#39;d introduce<br>&gt; &gt; &gt; &gt; &gt; into the MAC_Binding table (this could be optimized to not bother if it<br>&gt; &gt; &gt; &gt; &gt; has changed recently).  The owner checks the serial number every so<br>&gt; &gt; &gt; &gt; &gt; often and if it hasn&#39;t changed then it deletes the row.<br>&gt; &gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; Thanks Ben for the advice. Since the user of a binding is simply a OpenFlow<br>&gt; &gt; &gt; &gt; rule matching, I guess we will need &quot;controller&quot; action to trigger the<br>&gt; &gt; &gt; &gt; serial number column update in ovn-controller, combined with a meter action<br>&gt; &gt; &gt; &gt; so that only small number of packets trigger the update. Is this what you<br>&gt; &gt; &gt; &gt; are suggesting?<br>&gt; &gt; &gt;<br>&gt; &gt; &gt; I had not thought that far ahead!  That approach would work, although<br>&gt; &gt; &gt; the trigger percentage would be difficult to figure out--it seems like<br>&gt; &gt; &gt; really we&#39;d want &quot;every Nth second&quot;, not &quot;every Nth packet&quot;.  Another<br>&gt; &gt; &gt; approach that might work would be for ovn-controller to notice the<br>&gt; &gt; &gt; statistics on appropriate OpenFlow flows changing, or to use &quot;learn&quot;<br>&gt; &gt; &gt; actions as a way to make a controller action trigger only every so<br>&gt; &gt; &gt; often.</div>