diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-02-22 02:16:39 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-02-22 02:16:39 +0100 |
commit | 93af78d2d29ce11e20d46f60cfe1d3ef68052e5c (patch) | |
tree | cbd230280bf93c843b2e1d2fff41eb49c62e1e71 /nest/rt-table.c | |
parent | ae294cc2d02ec02cbea11c275b64e7637ba0ea68 (diff) |
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.
Diffstat (limited to 'nest/rt-table.c')
-rw-r--r-- | nest/rt-table.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/nest/rt-table.c b/nest/rt-table.c index 85afe838..6bf07a09 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -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; |