summaryrefslogtreecommitdiff
path: root/proto/pipe/pipe.c
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2018-07-03 19:21:42 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2018-07-03 19:21:59 +0200
commitcbfdf6ed057b993d7e107b4c39b8a5b81c081eee (patch)
tree0c6255bb81f037ceff0dfa9409a5829069ea24e1 /proto/pipe/pipe.c
parent822a7ee6d5cd9bf38548026e0dd52fbc4634030d (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 'proto/pipe/pipe.c')
-rw-r--r--proto/pipe/pipe.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c
index 6ef80322..5d0e3c76 100644
--- a/proto/pipe/pipe.c
+++ b/proto/pipe/pipe.c
@@ -230,12 +230,18 @@ pipe_reconfigure(struct proto *P, struct proto_config *new)
if ((oc->peer->table != nc->peer->table) || (oc->mode != nc->mode))
return 0;
+ int import_changed = ! filter_same(new->in_filter, old->in_filter);
+ int export_changed = ! filter_same(new->out_filter, old->out_filter);
+
/* Update output filters in ahooks */
if (P->main_ahook)
{
P->main_ahook->out_filter = new->out_filter;
P->main_ahook->in_limit = new->in_limit;
proto_verify_limits(P->main_ahook);
+
+ if (export_changed)
+ P->main_ahook->last_out_filter_change = now;
}
if (p->peer_ahook)
@@ -243,14 +249,15 @@ pipe_reconfigure(struct proto *P, struct proto_config *new)
p->peer_ahook->out_filter = new->in_filter;
p->peer_ahook->in_limit = new->out_limit;
proto_verify_limits(p->peer_ahook);
+
+ if (import_changed)
+ p->peer_ahook->last_out_filter_change = now;
}
if ((P->proto_state != PS_UP) || (proto_reconfig_type == RECONFIG_SOFT))
return 1;
- if ((new->preference != old->preference)
- || ! filter_same(new->in_filter, old->in_filter)
- || ! filter_same(new->out_filter, old->out_filter))
+ if (import_changed || export_changed || (new->preference != old->preference))
proto_request_feeding(P);
return 1;