]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: On route update context is sometimes indeterminate in post-processing
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 30 Jan 2019 14:31:32 +0000 (09:31 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 30 Jan 2019 14:52:13 +0000 (09:52 -0500)
When we get into rib_process_result and the operation we are handling
is DPLANE_OP_ROUTE_UPDATE *and* the route entry being looked at
is a route replace, we currently have no way to decode to the old_re
and the re due to how we have stored context.  As such they are the
same pointer.

As such the route replace for the same route type is causing the re
to set the installed flag and then immediately unset the installed
flag, leaving us in a state where the kernel has the route but
the rib thinks we are not installed.

Since the true old_re( the one being replaced by the update operation )
is going away( as that it zebra deletes the old one for us already )
this fix is not optimal but will get us moving forward.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zebra/zebra_rib.c

index 1eda55dca00220eccc1b9200099c89cf1b3f1d90..3445136d1f209f74d76c6fafe0703e1ec01f9d57 100644 (file)
@@ -1933,7 +1933,16 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                                UNSET_FLAG(re->status, ROUTE_ENTRY_FAILED);
                                SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
                        }
-                       if (old_re) {
+                       /*
+                        * On an update operation from the same route type
+                        * context retrieval currently has no way to know
+                        * which was the old and which was the new.
+                        * So don't unset our flags that we just set.
+                        * We know redistribution is ok because the
+                        * old_re in this case is used for nothing
+                        * more than knowing whom to contact if necessary.
+                        */
+                       if (old_re && old_re != re) {
                                UNSET_FLAG(old_re->status, ROUTE_ENTRY_FAILED);
                                UNSET_FLAG(old_re->status,
                                           ROUTE_ENTRY_INSTALLED);