From 984d734944a39b70a59f74e57f0e6fc3f720dd48 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sun, 27 Apr 2014 00:46:32 +0200 Subject: [PATCH] Fixes limit verification during reconfiguration. --- nest/proto.c | 47 ++++++++++++++++++++++++++--------------------- nest/protocol.h | 1 + proto/pipe/pipe.c | 2 ++ 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/nest/proto.c b/nest/proto.c index fc674ed5..6278580c 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -403,7 +403,6 @@ int proto_reconfig_type; /* Hack to propagate type info to pipe reconfigure hoo static int proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config *nc, int type) { - struct announce_hook *ah = p->main_ahook; /* If the protocol is DOWN, we just restart it */ if (p->proto_state == PS_DOWN) return 0; @@ -435,31 +434,16 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config /* Update filters and limits in the main announce hook Note that this also resets limit state */ - if (ah) - { + if (p->main_ahook) + { + struct announce_hook *ah = p->main_ahook; ah->in_filter = nc->in_filter; ah->out_filter = nc->out_filter; ah->rx_limit = nc->rx_limit; ah->in_limit = nc->in_limit; ah->out_limit = nc->out_limit; ah->in_keep_filtered = nc->in_keep_filtered; - - if (p->proto_state == PS_UP) /* Recheck export/import/receive limit */ - { - struct proto_stats *stats = ah->stats; - struct proto_limit *l = ah->in_limit; - u32 all_routes = stats->imp_routes + stats->filt_routes; - - if (l && (stats->imp_routes >= l->limit)) proto_notify_limit(ah, l, PLD_IN, stats->imp_routes); - - l = ah->rx_limit; - - if (l && ( all_routes >= l->limit)) proto_notify_limit(ah, l, PLD_RX, all_routes ); - - l = ah->out_limit; - - if (l && ( stats->exp_routes >= l->limit)) proto_notify_limit(ah, l, PLD_OUT, stats->exp_routes); - } + proto_verify_limits(ah); } /* Update routes when filters changed. If the protocol in not UP, @@ -1198,11 +1182,32 @@ proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32 case PLA_RESTART: case PLA_DISABLE: l->state = PLS_BLOCKED; - proto_schedule_down(p, l->action == PLA_RESTART, dir_down[dir]); + if (p->proto_state == PS_UP) + proto_schedule_down(p, l->action == PLA_RESTART, dir_down[dir]); break; } } +void +proto_verify_limits(struct announce_hook *ah) +{ + struct proto_limit *l; + struct proto_stats *stats = ah->stats; + u32 all_routes = stats->imp_routes + stats->filt_routes; + + l = ah->rx_limit; + if (l && (all_routes > l->limit)) + proto_notify_limit(ah, l, PLD_RX, all_routes); + + l = ah->in_limit; + if (l && (stats->imp_routes > l->limit)) + proto_notify_limit(ah, l, PLD_IN, stats->imp_routes); + + l = ah->out_limit; + if (l && (stats->exp_routes > l->limit)) + proto_notify_limit(ah, l, PLD_OUT, stats->exp_routes); +} + static void proto_want_core_up(struct proto *p) diff --git a/nest/protocol.h b/nest/protocol.h index ec779563..eb43418b 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -423,6 +423,7 @@ struct proto_limit { }; void proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32 rt_count); +void proto_verify_limits(struct announce_hook *ah); static inline void proto_reset_limit(struct proto_limit *l) diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index 2e206038..22381c3d 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -235,12 +235,14 @@ pipe_reconfigure(struct proto *P, struct proto_config *new) { P->main_ahook->out_filter = new->out_filter; P->main_ahook->in_limit = new->in_limit; + proto_verify_limits(P->main_ahook); } if (p->peer_ahook) { p->peer_ahook->out_filter = new->in_filter; p->peer_ahook->in_limit = new->out_limit; + proto_verify_limits(p->peer_ahook); } if ((P->proto_state != PS_UP) || (proto_reconfig_type == RECONFIG_SOFT))