]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Better flushing of interfaces.
authorOndrej Zajicek <santiago@crfreenet.org>
Sat, 27 Feb 2010 15:00:07 +0000 (16:00 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Sat, 27 Feb 2010 15:00:07 +0000 (16:00 +0100)
When device protocol goes down, interfaces should be flushed
asynchronously (in the same way like routes from protocols are flushed),
when protocol goes to DOWN/HUNGRY.

This fixes the problem with static routes staying in kernel routing
table after BIRD shutdown.

nest/iface.c
nest/iface.h
nest/proto.c
proto/static/static.c
sysdep/unix/krt.c

index 5e88b21bf4187bbc904972d588307cfc5e5702d0..82dead35f4249920606bbcbcc2ab98e173aff24e 100644 (file)
@@ -336,6 +336,15 @@ if_end_update(void)
     }
 }
 
+void
+if_flush_ifaces(struct proto *p)
+{
+  if (p->debug & D_EVENTS)
+    log(L_TRACE "%s: Flushing interfaces", p->name);
+  if_start_update();
+  if_end_update();
+}
+
 /**
  * if_feed_baby - advertise interfaces to a new protocol
  * @p: protocol to feed
index 02129ac6efaa5f0f7a83032fc6b859473d1bfa7b..8fc2567df79e79429aeab73834109c4513a1c518 100644 (file)
@@ -75,8 +75,9 @@ struct iface *if_update(struct iface *);
 struct ifa *ifa_update(struct ifa *);
 void ifa_delete(struct ifa *);
 void if_start_update(void);
-void if_end_update(void);
 void if_end_partial_update(struct iface *);
+void if_end_update(void);
+void if_flush_ifaces(struct proto *p);
 void if_feed_baby(struct proto *);
 struct iface *if_find_by_index(unsigned);
 struct iface *if_find_by_name(char *);
index db6bf9bf94037659c229c51537f1f82815a1c6e1..78fca99c1dbbda6957fd6c3fa2d4d2c40b520eb2 100644 (file)
@@ -740,6 +740,8 @@ proto_notify_state(struct proto *p, unsigned ps)
     }
 }
 
+extern struct protocol proto_unix_iface;
+
 static void
 proto_flush_all(void *unused UNUSED)
 {
@@ -748,6 +750,11 @@ proto_flush_all(void *unused UNUSED)
   rt_prune_all();
   while ((p = HEAD(flush_proto_list))->n.next)
     {
+      /* This will flush interfaces in the same manner
+        like rt_prune_all() flushes routes */
+      if (p->proto == &proto_unix_iface)
+       if_flush_ifaces(p);
+
       DBG("Flushing protocol %s\n", p->name);
       p->core_state = FS_HUNGRY;
       proto_relink(p);
index c71d1da99032fc07596e0ebef335e39261531359..9308c59a1f0e4e81294174f532992a31cfe2475a 100644 (file)
@@ -125,11 +125,12 @@ static_shutdown(struct proto *p)
   struct static_config *c = (void *) p->cf;
   struct static_route *r;
 
-  DBG("Static: prepare for landing!\n");
+  /* Just reset the flag, the routes will be flushed by the nest */
   WALK_LIST(r, c->iface_routes)
-    static_remove(p, r);
+    r->installed = 0;
   WALK_LIST(r, c->other_routes)
-    static_remove(p, r);
+    r->installed = 0;
+
   return PS_DOWN;
 }
 
@@ -294,7 +295,7 @@ static_show_rt(struct static_route *r)
   switch (r->dest)
     {
     case RTD_ROUTER:   bsprintf(via, "via %I", r->via); break;
-    case RTD_DEVICE:   bsprintf(via, "to %s", r->if_name); break;
+    case RTD_DEVICE:   bsprintf(via, "dev %s", r->if_name); break;
     case RTD_BLACKHOLE:        bsprintf(via, "blackhole"); break;
     case RTD_UNREACHABLE:      bsprintf(via, "unreachable"); break;
     case RTD_PROHIBIT: bsprintf(via, "prohibited"); break;
index 47b96217d00df7354a83ffae267e49194395c602..c8887b726aff93639f7c3923b27d1b8f9e8980e1 100644 (file)
@@ -139,15 +139,6 @@ kif_shutdown(struct proto *P)
   krt_if_shutdown(p);
   kif_proto = NULL;
 
-  if_start_update();   /* Remove all interfaces */
-  if_end_update();
-  /*
-   *  FIXME: Is it really a good idea?  It causes routes to be flushed,
-   *  but at the same time it avoids sending of these deletions to the kernel,
-   *  because krt thinks the kernel itself has already removed the route
-   *  when downing the interface.  Sad.
-   */
-
   return PS_DOWN;
 }