]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Fixes limit verification during reconfiguration.
authorOndrej Zajicek <santiago@crfreenet.org>
Sat, 26 Apr 2014 22:46:32 +0000 (00:46 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Sat, 26 Apr 2014 22:46:32 +0000 (00:46 +0200)
nest/proto.c
nest/protocol.h
proto/pipe/pipe.c

index fc674ed53e2721edf7314b18b7645dbfa9acefe1..6278580ca0f5f9a0125cf29963f25aee40bdc007 100644 (file)
@@ -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)
index ec7795638cf773408cc267f8a345a7e952812c08..eb43418bed463f50aeb38735f4fd2262d0bcaa5a 100644 (file)
@@ -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)
index 2e20603838944747a7506af3182d4308de32cdfe..22381c3d2825d320544db7ae5d28e76ff884a280 100644 (file)
@@ -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))