]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Bugfix for routing table breaking bug.
authorOndrej Zajicek <santiago@crfreenet.org>
Sun, 26 Oct 2008 22:09:46 +0000 (23:09 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Sun, 26 Oct 2008 22:09:46 +0000 (23:09 +0100)
Here is a patch fixing a bug that causes breakage of a local routing
table during shutdown of Bird. The problem was caused by shutdown
of 'device' protocol before shutdown of 'kernel' protocol.  When
'device' protocol went down, the route (with local network prefix)
From different protocol (BGP or OSPF) became preferred and installed
to the kernel routing table. Such routes were broken (like
192.168.1.0/24 via 192.168.1.2). I think it is also the cause
of problem reported by Martin Kraus.

The patch disables updating of kernel routing table during shutdown of
Bird. I am not sure whether this is the best way to fix it, I would
prefer to forbid 'kernel' protocol to overwrite routes with
'proto kernel'.

The patch also fixes a problem that during shutdown sometimes routes
created by Bird remained in the kernel routing table.

conf/conf.c
sysdep/linux/netlink/netlink.c
sysdep/unix/krt-set.c
sysdep/unix/krt.c

index a744dcaaac0480156a6ffbc3cb325c11cb61cb17..fefcac5133b763c668e39b3d3e41e35ed3c9f347 100644 (file)
@@ -266,7 +266,7 @@ config_commit(struct config *c)
     }
   if (old_config)                      /* Reconfiguration already in progress */
     {
-      if (shutting_down)
+      if (shutting_down == 2)
        {
          log(L_INFO "New configuration discarded due to shutdown");
          config_free(c);
@@ -314,8 +314,9 @@ order_shutdown(void)
   init_list(&c->protos);
   init_list(&c->tables);
   c->shutdown = 1;
-  config_commit(c);
   shutting_down = 1;
+  config_commit(c);
+  shutting_down = 2;
 }
 
 /**
index a70428efe33d513c1fc84661a176655362d5c41d..98c63f02e8280f1987436bb9f33c57c3c50df29b 100644 (file)
@@ -498,6 +498,8 @@ nl_send_route(struct krt_proto *p, rte *e, int new)
       nl_add_attr_ipa(&r.h, sizeof(r), RTA_GATEWAY, a->gw);
       break;
     case RTD_DEVICE:
+      if (!a->iface)
+       return;
       r.r.rtm_type = RTN_UNICAST;
       nl_add_attr_u32(&r.h, sizeof(r), RTA_OIF, a->iface->index);
       break;
@@ -531,11 +533,8 @@ krt_set_notify(struct krt_proto *p, net *n UNUSED, rte *new, rte *old)
   else
     {
       if (old)
-       {
-         if (!old->attrs->iface || (old->attrs->iface->flags & IF_UP))
-           nl_send_route(p, old, 0);
-         /* else the kernel has already flushed it */
-       }
+       nl_send_route(p, old, 0);
+
       if (new)
        nl_send_route(p, new, 1);
     }
index bd5644864468b645bb0250169ce0213645b850e1..23cbe5c56007dcd1cdd15b2dd8ab520d2a523aad 100644 (file)
@@ -61,6 +61,8 @@ krt_ioctl(int ioc, rte *e, char *name)
       re.rt_flags |= RTF_GATEWAY;
       break;
     case RTD_DEVICE:
+      if (!a->iface)
+       return;
       re.rt_dev = a->iface->name;
       break;
 #ifdef RTF_REJECT
index a6d172799975ccb7dda0d575d2a167c56797b32e..5269eb71ee1b59912120147b49228edd2716b788 100644 (file)
@@ -684,7 +684,7 @@ krt_notify(struct proto *P, net *net, rte *new, rte *old, struct ea_list *attrs
 {
   struct krt_proto *p = (struct krt_proto *) P;
 
-  if (shutting_down && KRT_CF->persist)
+  if (shutting_down)
     return;
   if (new && (!krt_capable(new) || new->attrs->source == RTS_INHERIT))
     new = NULL;