diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2016-04-08 15:10:57 +0200 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2016-04-08 15:11:21 +0200 |
commit | e90dd656cc9126e1fbcc45fb77a10bf1baa2a1b5 (patch) | |
tree | 5383de73050fdc1d3c87b3c28b218126bb4d2244 /nest | |
parent | f2ae2badff37c008ba8217a12f8ee6dc6a3c5a39 (diff) |
Direct: Implement check link for direct protocol
When enabled, direct protocol generates routes only if the underlying
link state is up.
Diffstat (limited to 'nest')
-rw-r--r-- | nest/config.Y | 1 | ||||
-rw-r--r-- | nest/rt-dev.c | 28 | ||||
-rw-r--r-- | nest/rt-dev.h | 1 |
3 files changed, 29 insertions, 1 deletions
diff --git a/nest/config.Y b/nest/config.Y index 87827c10..4566971f 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -335,6 +335,7 @@ dev_proto: dev_proto_start proto_name '{' | dev_proto proto_item ';' | dev_proto dev_iface_patt ';' + | dev_proto CHECK LINK bool ';' { DIRECT_CFG->check_link = $4; } ; dev_iface_init: diff --git a/nest/rt-dev.c b/nest/rt-dev.c index f6bc1432..ed6c06af 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -64,6 +64,9 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad) DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip); + if (P->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); @@ -85,11 +88,31 @@ dev_ifa_notify(struct proto *p, unsigned c, 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 *c) { struct proto *p = proto_new(c, sizeof(struct proto)); + p->if_notify = dev_if_notify; p->ifa_notify = dev_ifa_notify; return p; } @@ -100,7 +123,8 @@ dev_reconfigure(struct proto *p, struct proto_config *new) struct rt_dev_config *o = (struct rt_dev_config *) p->cf; struct rt_dev_config *n = (struct rt_dev_config *) new; - return iface_patts_equal(&o->iface_list, &n->iface_list, NULL); + return iface_patts_equal(&o->iface_list, &n->iface_list, NULL) && + (o->check_link == n->check_link); } static void @@ -115,6 +139,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 = { diff --git a/nest/rt-dev.h b/nest/rt-dev.h index c36d0742..191b9a02 100644 --- a/nest/rt-dev.h +++ b/nest/rt-dev.h @@ -12,6 +12,7 @@ struct rt_dev_config { struct proto_config c; list iface_list; /* list of struct iface_patt */ + int check_link; }; #endif |