summaryrefslogtreecommitdiff
path: root/nest/rt-dev.c
diff options
context:
space:
mode:
authorJan Moskyto Matejka <mq@ucw.cz>2016-05-13 13:48:04 +0200
committerJan Moskyto Matejka <mq@ucw.cz>2016-05-13 13:48:04 +0200
commit5af7b59660be615fbbd7c20b92b71321c003c43a (patch)
tree59bc962b18ae5a4ac6bf088863cfe210c9123b57 /nest/rt-dev.c
parentd39d41fbda2ec86ea2bac27308eb4fb16ecc4702 (diff)
parentb66a9e2f3376b4cb07ef4cc318f70a9c794f407a (diff)
Merge branch 'int-new' of gitlab.labs.nic.cz:labs/bird into int-new
Diffstat (limited to 'nest/rt-dev.c')
-rw-r--r--nest/rt-dev.c28
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 = {