Bugfix for routing table breaking bug.

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.
This commit is contained in:
Ondrej Zajicek 2008-10-26 23:09:46 +01:00
parent b6bf284a90
commit 1567edea8d
4 changed files with 10 additions and 8 deletions

View file

@ -266,7 +266,7 @@ config_commit(struct config *c)
} }
if (old_config) /* Reconfiguration already in progress */ if (old_config) /* Reconfiguration already in progress */
{ {
if (shutting_down) if (shutting_down == 2)
{ {
log(L_INFO "New configuration discarded due to shutdown"); log(L_INFO "New configuration discarded due to shutdown");
config_free(c); config_free(c);
@ -314,8 +314,9 @@ order_shutdown(void)
init_list(&c->protos); init_list(&c->protos);
init_list(&c->tables); init_list(&c->tables);
c->shutdown = 1; c->shutdown = 1;
config_commit(c);
shutting_down = 1; shutting_down = 1;
config_commit(c);
shutting_down = 2;
} }
/** /**

View 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); nl_add_attr_ipa(&r.h, sizeof(r), RTA_GATEWAY, a->gw);
break; break;
case RTD_DEVICE: case RTD_DEVICE:
if (!a->iface)
return;
r.r.rtm_type = RTN_UNICAST; r.r.rtm_type = RTN_UNICAST;
nl_add_attr_u32(&r.h, sizeof(r), RTA_OIF, a->iface->index); nl_add_attr_u32(&r.h, sizeof(r), RTA_OIF, a->iface->index);
break; break;
@ -531,11 +533,8 @@ krt_set_notify(struct krt_proto *p, net *n UNUSED, rte *new, rte *old)
else else
{ {
if (old) if (old)
{
if (!old->attrs->iface || (old->attrs->iface->flags & IF_UP))
nl_send_route(p, old, 0); nl_send_route(p, old, 0);
/* else the kernel has already flushed it */
}
if (new) if (new)
nl_send_route(p, new, 1); nl_send_route(p, new, 1);
} }

View file

@ -61,6 +61,8 @@ krt_ioctl(int ioc, rte *e, char *name)
re.rt_flags |= RTF_GATEWAY; re.rt_flags |= RTF_GATEWAY;
break; break;
case RTD_DEVICE: case RTD_DEVICE:
if (!a->iface)
return;
re.rt_dev = a->iface->name; re.rt_dev = a->iface->name;
break; break;
#ifdef RTF_REJECT #ifdef RTF_REJECT

View 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; struct krt_proto *p = (struct krt_proto *) P;
if (shutting_down && KRT_CF->persist) if (shutting_down)
return; return;
if (new && (!krt_capable(new) || new->attrs->source == RTS_INHERIT)) if (new && (!krt_capable(new) || new->attrs->source == RTS_INHERIT))
new = NULL; new = NULL;