diff options
Diffstat (limited to 'nest/rt-dev.c')
-rw-r--r-- | nest/rt-dev.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/nest/rt-dev.c b/nest/rt-dev.c index 098885b9..d98cd79f 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -68,6 +68,9 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad) DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip); + if (cf->check_link && !(ad->iface->flags & IF_LINK_UP)) + return; + /* Use iface ID as local source ID */ struct rte_src *src = rt_get_source(P, ad->iface->index); @@ -87,6 +90,25 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad) } } +static void +dev_if_notify(struct proto *p, uint c, struct iface *iface) +{ + struct rt_dev_config *cf = (void *) p->cf; + + if (c & (IF_CHANGE_UP | IF_CHANGE_DOWN)) + return; + + if ((c & IF_CHANGE_LINK) && cf->check_link) + { + uint ac = (iface->flags & IF_LINK_UP) ? IF_CHANGE_UP : IF_CHANGE_DOWN; + + struct ifa *a; + WALK_LIST(a, iface->addrs) + dev_ifa_notify(p, ac, a); + } +} + + static struct proto * dev_init(struct proto_config *CF) { @@ -97,6 +119,7 @@ dev_init(struct proto_config *CF) proto_configure_channel(P, &p->ip4_channel, proto_cf_find_channel(CF, NET_IP4)); proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6)); + P->if_notify = dev_if_notify; P->ifa_notify = dev_ifa_notify; return P; @@ -109,7 +132,8 @@ dev_reconfigure(struct proto *P, struct proto_config *CF) struct rt_dev_config *o = (void *) P->cf; struct rt_dev_config *n = (void *) CF; - if (!iface_patts_equal(&o->iface_list, &n->iface_list, NULL)) + if (!iface_patts_equal(&o->iface_list, &n->iface_list, NULL) || + (o->check_link != n->check_link)) return 0; return @@ -131,6 +155,8 @@ dev_copy_config(struct proto_config *dest, struct proto_config *src) * old nodes cannot be modified (although they contain internal lists). */ cfg_copy_list(&d->iface_list, &s->iface_list, sizeof(struct iface_patt)); + + d->check_link = s->check_link; } struct protocol proto_device = { |