summaryrefslogtreecommitdiff
path: root/nest/rt-dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'nest/rt-dev.c')
-rw-r--r--nest/rt-dev.c77
1 files changed, 53 insertions, 24 deletions
diff --git a/nest/rt-dev.c b/nest/rt-dev.c
index f6bc1432..a996f4fc 100644
--- a/nest/rt-dev.c
+++ b/nest/rt-dev.c
@@ -24,14 +24,17 @@
#include "lib/resource.h"
#include "lib/string.h"
+
static void
-dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
+dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
{
- struct rt_dev_config *P = (void *) p->cf;
+ struct rt_dev_proto *p = (void *) P;
+ struct rt_dev_config *cf = (void *) P->cf;
+ struct channel *c;
- if (!EMPTY_LIST(P->iface_list) &&
- !iface_patt_find(&P->iface_list, ad->iface, ad->iface->addr))
- /* Empty list is automagically treated as "*" */
+ if (!EMPTY_LIST(cf->iface_list) &&
+ !iface_patt_find(&cf->iface_list, ad->iface, ad->iface->addr))
+ /* Empty list is automatically treated as "*" */
return;
if (ad->flags & IA_SECONDARY)
@@ -40,12 +43,22 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
if (ad->scope <= SCOPE_LINK)
return;
- if (c & IF_CHANGE_DOWN)
+ if (ad->prefix.type == NET_IP4)
+ c = p->ip4_channel;
+ else if (ad->prefix.type == NET_IP6)
+ c = p->ip6_channel;
+ else
+ return;
+
+ if (!c)
+ return;
+
+ if (flags & IF_CHANGE_DOWN)
{
net *n;
DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip);
- n = net_find(p->table, ad->prefix, ad->pxlen);
+ n = net_find(c->table, &ad->prefix);
if (!n)
{
DBG("dev_if_notify: device shutdown: prefix not found\n");
@@ -53,10 +66,10 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
}
/* Use iface ID as local source ID */
- struct rte_src *src = rt_get_source(p, ad->iface->index);
- rte_update2(p->main_ahook, n, NULL, src);
+ struct rte_src *src = rt_get_source(P, ad->iface->index);
+ rte_update2(c, n, NULL, src);
}
- else if (c & IF_CHANGE_UP)
+ else if (flags & IF_CHANGE_UP)
{
rta *a;
net *n;
@@ -65,7 +78,7 @@ 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);
/* Use iface ID as local source ID */
- struct rte_src *src = rt_get_source(p, ad->iface->index);
+ struct rte_src *src = rt_get_source(P, ad->iface->index);
rta a0 = {
.src = src,
@@ -77,37 +90,51 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
};
a = rta_lookup(&a0);
- n = net_get(p->table, ad->prefix, ad->pxlen);
+ n = net_get(c->table, &ad->prefix);
e = rte_get_temp(a);
e->net = n;
e->pflags = 0;
- rte_update2(p->main_ahook, n, e, src);
+ rte_update2(c, n, e, src);
}
}
static struct proto *
-dev_init(struct proto_config *c)
+dev_init(struct proto_config *CF)
{
- struct proto *p = proto_new(c, sizeof(struct proto));
+ struct proto *P = proto_new(CF);
+ struct rt_dev_proto *p = (void *) P;
+ // struct rt_dev_config *cf = (void *) CF;
- p->ifa_notify = dev_ifa_notify;
- return p;
+ 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->ifa_notify = dev_ifa_notify;
+
+ return P;
}
static int
-dev_reconfigure(struct proto *p, struct proto_config *new)
+dev_reconfigure(struct proto *P, struct proto_config *CF)
{
- struct rt_dev_config *o = (struct rt_dev_config *) p->cf;
- struct rt_dev_config *n = (struct rt_dev_config *) new;
+ struct rt_dev_proto *p = (void *) P;
+ 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))
+ return 0;
+
+ return
+ 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));
- return iface_patts_equal(&o->iface_list, &n->iface_list, NULL);
+ return 1;
}
static void
dev_copy_config(struct proto_config *dest, struct proto_config *src)
{
- struct rt_dev_config *d = (struct rt_dev_config *) dest;
- struct rt_dev_config *s = (struct rt_dev_config *) src;
+ struct rt_dev_config *d = (void *) dest;
+ struct rt_dev_config *s = (void *) src;
/*
* We copy iface_list as ifaces can be shared by more direct protocols.
@@ -120,7 +147,9 @@ dev_copy_config(struct proto_config *dest, struct proto_config *src)
struct protocol proto_device = {
.name = "Direct",
.template = "direct%d",
- .preference = DEF_PREF_DIRECT,
+ .preference = DEF_PREF_DIRECT,
+ .channel_mask = NB_IP,
+ .proto_size = sizeof(struct rt_dev_proto),
.config_size = sizeof(struct rt_dev_config),
.init = dev_init,
.reconfigure = dev_reconfigure,