]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Nest: Do not compare rte.flags during rte_update()
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Fri, 22 Feb 2019 01:16:39 +0000 (02:16 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Fri, 22 Feb 2019 01:16:39 +0000 (02:16 +0100)
Route flags are mosty internal state of rtable, they are not significant
to whether a route has changed. With the old code, all routes received as
a part of enhanced route refresh are always re-announced to other peers
due to change in REF_STALE.

nest/rt-table.c

index 85afe83866d072976eebc98abe5e6bb0844b6542..6bf07a091359a70fb208d5b91499646749ac8f7d 100644 (file)
@@ -1007,12 +1007,13 @@ rte_free_quick(rte *e)
 static int
 rte_same(rte *x, rte *y)
 {
+  /* rte.flags are not checked, as they are mostly internal to rtable */
   return
     x->attrs == y->attrs &&
-    x->flags == y->flags &&
     x->pflags == y->pflags &&
     x->pref == y->pref &&
-    (!x->attrs->src->proto->rte_same || x->attrs->src->proto->rte_same(x, y));
+    (!x->attrs->src->proto->rte_same || x->attrs->src->proto->rte_same(x, y)) &&
+    rte_is_filtered(x) == rte_is_filtered(y);
 }
 
 static inline int rte_is_ok(rte *e) { return e && !rte_is_filtered(e); }
@@ -1056,7 +1057,9 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
 
          if (new && rte_same(old, new))
            {
-             /* No changes, ignore the new route */
+             /* No changes, ignore the new route and refresh the old one */
+
+             old->flags &= ~(REF_STALE | REF_DISCARD | REF_MODIFY);
 
              if (!rte_is_filtered(new))
                {
@@ -2362,7 +2365,16 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
     if (old->attrs->src == src)
     {
       if (new && rte_same(old, new))
+      {
+       /* Refresh the old rte, continue with update to main rtable */
+       if (old->flags & (REF_STALE | REF_DISCARD | REF_MODIFY))
+       {
+         old->flags &= ~(REF_STALE | REF_DISCARD | REF_MODIFY);
+         return 1;
+       }
+
        goto drop_update;
+      }
 
       /* Remove the old rte */
       *pos = old->next;