Commit 93af78d2 authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

Nest: Do not compare rte.flags during rte_update()

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.
parent ae294cc2
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -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;