diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2010-02-27 16:00:07 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2010-02-27 16:00:07 +0100 |
commit | 53434e44a95fe9334f4bdf5e0da987929addffb1 (patch) | |
tree | 75317dd53e6059b7c6fe0941312adc2e317c46eb /nest | |
parent | 3075824dbd4bb654e98614dfd9992ceec0428beb (diff) | |
download | bird-53434e44a95fe9334f4bdf5e0da987929addffb1.tar bird-53434e44a95fe9334f4bdf5e0da987929addffb1.zip |
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.
Diffstat (limited to 'nest')
-rw-r--r-- | nest/iface.c | 9 | ||||
-rw-r--r-- | nest/iface.h | 3 | ||||
-rw-r--r-- | nest/proto.c | 7 |
3 files changed, 18 insertions, 1 deletions
diff --git a/nest/iface.c b/nest/iface.c index 5e88b21..82dead3 100644 --- a/nest/iface.c +++ b/nest/iface.c @@ -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 diff --git a/nest/iface.h b/nest/iface.h index 02129ac..8fc2567 100644 --- a/nest/iface.h +++ b/nest/iface.h @@ -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 *); diff --git a/nest/proto.c b/nest/proto.c index db6bf9b..78fca99 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -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); |