Commit 53434e44 authored by Ondřej Zajíček's avatar Ondřej Zajíček

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.
parent 3075824d
......@@ -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
......
......@@ -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 *);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment