mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
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.
This commit is contained in:
committed by
Jan Moskyto Matejka
parent
9f5782d969
commit
f4a60a9bc4
@@ -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)
|
||||
{
|
||||
struct rt_dev_config *P = (void *) p->cf;
|
||||
|
||||
if (!EMPTY_LIST(P->iface_list) &&
|
||||
!iface_patt_find(&P->iface_list, ad->iface, ad->iface->addr))
|
||||
static void
|
||||
dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
|
||||
{
|
||||
struct rt_dev_proto *p = (void *) P;
|
||||
struct rt_dev_config *cf = (void *) P->cf;
|
||||
struct channel *c;
|
||||
|
||||
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;
|
||||
|
||||
return iface_patts_equal(&o->iface_list, &n->iface_list, NULL);
|
||||
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 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,
|
||||
|
Reference in New Issue
Block a user