Better flushing of interfaces.
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.
This commit is contained in:
parent
3075824dbd
commit
53434e44a9
5 changed files with 23 additions and 14 deletions
|
@ -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
|
* if_feed_baby - advertise interfaces to a new protocol
|
||||||
* @p: protocol to feed
|
* @p: protocol to feed
|
||||||
|
|
|
@ -75,8 +75,9 @@ struct iface *if_update(struct iface *);
|
||||||
struct ifa *ifa_update(struct ifa *);
|
struct ifa *ifa_update(struct ifa *);
|
||||||
void ifa_delete(struct ifa *);
|
void ifa_delete(struct ifa *);
|
||||||
void if_start_update(void);
|
void if_start_update(void);
|
||||||
void if_end_update(void);
|
|
||||||
void if_end_partial_update(struct iface *);
|
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 *);
|
void if_feed_baby(struct proto *);
|
||||||
struct iface *if_find_by_index(unsigned);
|
struct iface *if_find_by_index(unsigned);
|
||||||
struct iface *if_find_by_name(char *);
|
struct iface *if_find_by_name(char *);
|
||||||
|
|
|
@ -740,6 +740,8 @@ proto_notify_state(struct proto *p, unsigned ps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern struct protocol proto_unix_iface;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proto_flush_all(void *unused UNUSED)
|
proto_flush_all(void *unused UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -748,6 +750,11 @@ proto_flush_all(void *unused UNUSED)
|
||||||
rt_prune_all();
|
rt_prune_all();
|
||||||
while ((p = HEAD(flush_proto_list))->n.next)
|
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);
|
DBG("Flushing protocol %s\n", p->name);
|
||||||
p->core_state = FS_HUNGRY;
|
p->core_state = FS_HUNGRY;
|
||||||
proto_relink(p);
|
proto_relink(p);
|
||||||
|
|
|
@ -125,11 +125,12 @@ static_shutdown(struct proto *p)
|
||||||
struct static_config *c = (void *) p->cf;
|
struct static_config *c = (void *) p->cf;
|
||||||
struct static_route *r;
|
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)
|
WALK_LIST(r, c->iface_routes)
|
||||||
static_remove(p, r);
|
r->installed = 0;
|
||||||
WALK_LIST(r, c->other_routes)
|
WALK_LIST(r, c->other_routes)
|
||||||
static_remove(p, r);
|
r->installed = 0;
|
||||||
|
|
||||||
return PS_DOWN;
|
return PS_DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +295,7 @@ static_show_rt(struct static_route *r)
|
||||||
switch (r->dest)
|
switch (r->dest)
|
||||||
{
|
{
|
||||||
case RTD_ROUTER: bsprintf(via, "via %I", r->via); break;
|
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_BLACKHOLE: bsprintf(via, "blackhole"); break;
|
||||||
case RTD_UNREACHABLE: bsprintf(via, "unreachable"); break;
|
case RTD_UNREACHABLE: bsprintf(via, "unreachable"); break;
|
||||||
case RTD_PROHIBIT: bsprintf(via, "prohibited"); break;
|
case RTD_PROHIBIT: bsprintf(via, "prohibited"); break;
|
||||||
|
|
|
@ -139,15 +139,6 @@ kif_shutdown(struct proto *P)
|
||||||
krt_if_shutdown(p);
|
krt_if_shutdown(p);
|
||||||
kif_proto = NULL;
|
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;
|
return PS_DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue