diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2018-07-03 19:21:42 +0200 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2018-07-03 19:21:59 +0200 |
commit | cbfdf6ed057b993d7e107b4c39b8a5b81c081eee (patch) | |
tree | 0c6255bb81f037ceff0dfa9409a5829069ea24e1 /nest/proto.c | |
parent | 822a7ee6d5cd9bf38548026e0dd52fbc4634030d (diff) |
Nest: Fix race condition during reconfiguration
If export filter is changed during reconfiguration and a route disappears
between reconfiguration and refeed (e.g., if the route is a static route
also removed during the reconfiguration), the route is not withdrawn.
The patch fixes that by adding tx reconfiguration timestamp.
Diffstat (limited to 'nest/proto.c')
-rw-r--r-- | nest/proto.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/nest/proto.c b/nest/proto.c index 552d53ae..565b238f 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -433,10 +433,17 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config if (p->proto->multitable) return 1; + int import_changed = ! filter_same(nc->in_filter, oc->in_filter); + int export_changed = ! filter_same(nc->out_filter, oc->out_filter); + + /* We treat a change in preferences by reimporting routes */ + if (nc->preference != oc->preference) + import_changed = 1; + /* Update filters and limits in the main announce hook Note that this also resets limit state */ if (p->main_ahook) - { + { struct announce_hook *ah = p->main_ahook; ah->in_filter = nc->in_filter; ah->out_filter = nc->out_filter; @@ -445,6 +452,9 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config ah->out_limit = nc->out_limit; ah->in_keep_filtered = nc->in_keep_filtered; proto_verify_limits(ah); + + if (export_changed) + ah->last_out_filter_change = now; } /* Update routes when filters changed. If the protocol in not UP, @@ -452,13 +462,6 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config if ((p->proto_state != PS_UP) || (type == RECONFIG_SOFT)) return 1; - int import_changed = ! filter_same(nc->in_filter, oc->in_filter); - int export_changed = ! filter_same(nc->out_filter, oc->out_filter); - - /* We treat a change in preferences by reimporting routes */ - if (nc->preference != oc->preference) - import_changed = 1; - if (import_changed || export_changed) log(L_INFO "Reloading protocol %s", p->name); |