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.c105
1 files changed, 61 insertions, 44 deletions
diff --git a/nest/rt-dev.c b/nest/rt-dev.c
index ed6c06af..718c4578 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))
+ /* Empty list is automatically treated as "*" */
return;
if (ad->flags & IA_SECONDARY)
@@ -40,51 +43,49 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
if (ad->scope <= SCOPE_LINK)
return;
- if (c & IF_CHANGE_DOWN)
- {
- net *n;
+ 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)
+ {
DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip);
- n = net_find(p->table, ad->prefix, ad->pxlen);
- if (!n)
- {
- DBG("dev_if_notify: device shutdown: prefix not found\n");
- return;
- }
/* 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, &ad->prefix, NULL, src);
}
- else if (c & IF_CHANGE_UP)
+ else if (flags & IF_CHANGE_UP)
{
rta *a;
- net *n;
rte *e;
DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
- if (P->check_link && !(ad->iface->flags & IF_LINK_UP))
+ 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);
+ struct rte_src *src = rt_get_source(P, ad->iface->index);
rta a0 = {
.src = src,
.source = RTS_DEVICE,
.scope = SCOPE_UNIVERSE,
- .cast = RTC_UNICAST,
- .dest = RTD_DEVICE,
- .iface = ad->iface
+ .dest = RTD_UNICAST,
+ .nh.iface = ad->iface,
};
a = rta_lookup(&a0);
- n = net_get(p->table, ad->prefix, ad->pxlen);
e = rte_get_temp(a);
- e->net = n;
e->pflags = 0;
- rte_update2(p->main_ahook, n, e, src);
+ rte_update2(c, &ad->prefix, e, src);
}
}
@@ -108,30 +109,44 @@ dev_if_notify(struct proto *p, uint c, struct iface *iface)
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;
+
+ 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;
- p->if_notify = dev_if_notify;
- p->ifa_notify = dev_ifa_notify;
- return p;
+ 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) ||
+ (o->check_link != n->check_link))
+ 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) &&
- (o->check_link == n->check_link);
+ 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.
@@ -144,11 +159,13 @@ dev_copy_config(struct proto_config *dest, struct proto_config *src)
}
struct protocol proto_device = {
- .name = "Direct",
- .template = "direct%d",
- .preference = DEF_PREF_DIRECT,
+ .name = "Direct",
+ .template = "direct%d",
+ .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,
- .copy_config = dev_copy_config
+ .init = dev_init,
+ .reconfigure = dev_reconfigure,
+ .copy_config = dev_copy_config
};