0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 02:01:55 +00:00

Babel: Convert the rte-local attributes to extended attributes

This commit is contained in:
Maria Matejka 2020-02-13 13:22:15 +01:00
parent 083e0dbb36
commit adebcd5e0a
3 changed files with 48 additions and 50 deletions

View File

@ -222,13 +222,6 @@ typedef struct rte {
byte pflags; /* Protocol-specific flags */ byte pflags; /* Protocol-specific flags */
btime lastmod; /* Last modified */ btime lastmod; /* Last modified */
union { /* Protocol-dependent data (metrics etc.) */ union { /* Protocol-dependent data (metrics etc.) */
#ifdef CONFIG_BABEL
struct {
u16 seqno; /* Babel seqno */
u16 metric; /* Babel metric */
u64 router_id; /* Babel router id */
} babel;
#endif
struct { /* Routes generated by krt sync (both temporary and inherited ones) */ struct { /* Routes generated by krt sync (both temporary and inherited ones) */
s8 src; /* Alleged route source (see krt.h) */ s8 src; /* Alleged route source (see krt.h) */
u8 proto; /* Kernel source protocol ID */ u8 proto; /* Kernel source protocol ID */

View File

@ -639,16 +639,33 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
.from = r->neigh->addr, .from = r->neigh->addr,
.nh.gw = r->next_hop, .nh.gw = r->next_hop,
.nh.iface = r->neigh->ifa->iface, .nh.iface = r->neigh->ifa->iface,
.eattrs = alloca(sizeof(ea_list) + 3*sizeof(eattr)),
};
*a0.eattrs = (ea_list) { .count = 3 };
a0.eattrs->attrs[0] = (eattr) {
.id = EA_BABEL_METRIC,
.type = EAF_TYPE_INT,
.u.data = r->metric,
};
struct adata *ad = alloca(sizeof(struct adata) + sizeof(u64));
ad->length = sizeof(u64);
memcpy(ad->data, &(r->router_id), sizeof(u64));
a0.eattrs->attrs[1] = (eattr) {
.id = EA_BABEL_ROUTER_ID,
.type = EAF_TYPE_OPAQUE,
.u.ptr = ad,
};
a0.eattrs->attrs[2] = (eattr) {
.id = EA_BABEL_SEQNO,
.type = EAF_TYPE_INT,
.u.data = r->seqno,
}; };
rte e0 = { rte e0 = {
.attrs = &a0, .attrs = &a0,
.u.babel = {
.seqno = r->seqno,
.metric = r->metric,
.router_id = r->router_id,
},
.pflags = EA_ID_FLAG(EA_BABEL_METRIC) | EA_ID_FLAG(EA_BABEL_ROUTER_ID),
}; };
e->unreachable = 0; e->unreachable = 0;
@ -1851,7 +1868,10 @@ babel_dump(struct proto *P)
static void static void
babel_get_route_info(rte *rte, byte *buf) babel_get_route_info(rte *rte, byte *buf)
{ {
buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->pref, rte->u.babel.metric, rte->u.babel.router_id); u64 rid;
memcpy(&rid, ea_find(rte->attrs->eattrs, EA_BABEL_ROUTER_ID)->u.ptr->data, sizeof(u64));
buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->pref,
ea_find(rte->attrs->eattrs, EA_BABEL_METRIC)->u.data, rid);
} }
static int static int
@ -1859,6 +1879,10 @@ babel_get_attr(const eattr *a, byte *buf, int buflen UNUSED)
{ {
switch (a->id) switch (a->id)
{ {
case EA_BABEL_SEQNO:
bsprintf(buf, "seqno: %d", a->u.data);
return GA_FULL;
case EA_BABEL_METRIC: case EA_BABEL_METRIC:
bsprintf(buf, "metric: %d", a->u.data); bsprintf(buf, "metric: %d", a->u.data);
return GA_FULL; return GA_FULL;
@ -2092,27 +2116,6 @@ babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED)
return 0; return 0;
} }
static void
babel_make_tmp_attrs(struct rte *rt, struct linpool *pool)
{
struct adata *id = lp_alloc_adata(pool, sizeof(u64));
memcpy(id->data, &rt->u.babel.router_id, sizeof(u64));
rte_init_tmp_attrs(rt, pool, 2);
rte_make_tmp_attr(rt, EA_BABEL_METRIC, EAF_TYPE_INT, rt->u.babel.metric);
rte_make_tmp_attr(rt, EA_BABEL_ROUTER_ID, EAF_TYPE_OPAQUE, (uintptr_t) id);
}
static void
babel_store_tmp_attrs(struct rte *rt, struct linpool *pool)
{
rte_init_tmp_attrs(rt, pool, 2);
rt->u.babel.metric = rte_store_tmp_attr(rt, EA_BABEL_METRIC);
/* EA_BABEL_ROUTER_ID is read-only, we do not really save the value */
rte_store_tmp_attr(rt, EA_BABEL_ROUTER_ID);
}
/* /*
* babel_rt_notify - core tells us about new route (possibly our own), * babel_rt_notify - core tells us about new route (possibly our own),
* so store it into our data structures. * so store it into our data structures.
@ -2127,10 +2130,20 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
if (new) if (new)
{ {
/* Update */ /* Update */
uint internal = (new->attrs->src->proto == P); uint rt_seqno;
uint rt_seqno = internal ? new->u.babel.seqno : p->update_seqno;
uint rt_metric = ea_get_int(new->attrs->eattrs, EA_BABEL_METRIC, 0); uint rt_metric = ea_get_int(new->attrs->eattrs, EA_BABEL_METRIC, 0);
u64 rt_router_id = internal ? new->u.babel.router_id : p->router_id; u64 rt_router_id;
if (new->attrs->src->proto == P)
{
rt_seqno = ea_find(new->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
memcpy(&rt_router_id, ea_find(new->attrs->eattrs, EA_BABEL_ROUTER_ID)->u.ptr->data, sizeof(u64));
}
else
{
rt_seqno = p->router_id;
rt_router_id = p->router_id;
}
if (rt_metric > BABEL_INFINITY) if (rt_metric > BABEL_INFINITY)
{ {
@ -2173,18 +2186,12 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
static int static int
babel_rte_better(struct rte *new, struct rte *old) babel_rte_better(struct rte *new, struct rte *old)
{ {
return new->u.babel.metric < old->u.babel.metric; uint new_metric = ea_find(new->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
} uint old_metric = ea_find(old->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
static int return new_metric < old_metric;
babel_rte_same(struct rte *new, struct rte *old)
{
return ((new->u.babel.seqno == old->u.babel.seqno) &&
(new->u.babel.metric == old->u.babel.metric) &&
(new->u.babel.router_id == old->u.babel.router_id));
} }
static void static void
babel_postconfig(struct proto_config *CF) babel_postconfig(struct proto_config *CF)
{ {
@ -2215,10 +2222,7 @@ babel_init(struct proto_config *CF)
P->if_notify = babel_if_notify; P->if_notify = babel_if_notify;
P->rt_notify = babel_rt_notify; P->rt_notify = babel_rt_notify;
P->preexport = babel_preexport; P->preexport = babel_preexport;
P->make_tmp_attrs = babel_make_tmp_attrs;
P->store_tmp_attrs = babel_store_tmp_attrs;
P->rte_better = babel_rte_better; P->rte_better = babel_rte_better;
P->rte_same = babel_rte_same;
return P; return P;
} }

View File

@ -27,6 +27,7 @@
#define EA_BABEL_METRIC EA_CODE(PROTOCOL_BABEL, 0) #define EA_BABEL_METRIC EA_CODE(PROTOCOL_BABEL, 0)
#define EA_BABEL_ROUTER_ID EA_CODE(PROTOCOL_BABEL, 1) #define EA_BABEL_ROUTER_ID EA_CODE(PROTOCOL_BABEL, 1)
#define EA_BABEL_SEQNO EA_CODE(PROTOCOL_BABEL, 2)
#define BABEL_MAGIC 42 #define BABEL_MAGIC 42
#define BABEL_VERSION 2 #define BABEL_VERSION 2