summaryrefslogtreecommitdiff
path: root/nest/rt-dev.c
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2016-01-26 11:48:58 +0100
committerJan Moskyto Matejka <mq@ucw.cz>2016-02-01 10:28:50 +0100
commitf4a60a9bc429c28cb397402331dc01a789197450 (patch)
treee8cead76aa1c2aedfb76d7e3ceade2fc4a7214cf /nest/rt-dev.c
parent9f5782d9691f23296c4b1a68ef66630d9cc3a6cd (diff)
Channels - explicit links between protocols and tables
The patch adds support for channels, structures connecting protocols and tables and handling most interactions between them. The documentation is missing yet.
Diffstat (limited to 'nest/rt-dev.c')
-rw-r--r--nest/rt-dev.c75
1 files changed, 52 insertions, 23 deletions
diff --git a/nest/rt-dev.c b/nest/rt-dev.c
index f94933d5..17737853 100644
--- a/nest/rt-dev.c
+++ b/nest/rt-dev.c
@@ -24,13 +24,16 @@
#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))
+ if (!EMPTY_LIST(cf->iface_list) &&
+ !iface_patt_find(&cf->iface_list, ad->iface, ad->iface->addr))
/* Empty list is automagically treated as "*" */
return;
@@ -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);
+ 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);
+ 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,