diff --git a/nest/route.h b/nest/route.h index ef7cf6f0..d20fc41f 100644 --- a/nest/route.h +++ b/nest/route.h @@ -237,13 +237,6 @@ typedef struct rte { byte pflags; /* Protocol-specific flags */ btime lastmod; /* Last modified */ 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) */ s8 src; /* Alleged route source (see krt.h) */ u8 proto; /* Kernel source protocol ID */ diff --git a/nest/rt-table.c b/nest/rt-table.c index 4177e80a..c222f522 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -57,6 +57,10 @@ #include "proto/bgp/bgp.h" #endif +#ifdef CONFIG_BABEL +#include "proto/babel/babel.h" +#endif + pool *rt_table_pool; static slab *rte_slab; @@ -2949,7 +2953,9 @@ rt_get_igp_metric(rte *rt) #ifdef CONFIG_BABEL case RTS_BABEL: - return rt->u.babel.metric; + if (ea = ea_find(rt->attrs->eattrs, EA_BABEL_METRIC)) + return ea->u.data; + break; #endif case RTS_DEVICE: diff --git a/proto/babel/babel.c b/proto/babel/babel.c index e51700ae..e62fcb2d 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -638,6 +638,29 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) .from = r->neigh->addr, .nh.gw = r->next_hop, .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, }; /* @@ -650,12 +673,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) rte e0 = { .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; @@ -1858,7 +1875,10 @@ babel_dump(struct proto *P) static void 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 @@ -1866,6 +1886,10 @@ babel_get_attr(const eattr *a, byte *buf, int buflen UNUSED) { switch (a->id) { + case EA_BABEL_SEQNO: + bsprintf(buf, "seqno: %d", a->u.data); + return GA_FULL; + case EA_BABEL_METRIC: bsprintf(buf, "metric: %d", a->u.data); return GA_FULL; @@ -2087,27 +2111,6 @@ babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED) 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), * so store it into our data structures. @@ -2122,10 +2125,20 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, if (new) { /* Update */ - uint internal = (new->attrs->src->proto == P); - uint rt_seqno = internal ? new->u.babel.seqno : p->update_seqno; + uint rt_seqno; 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) { @@ -2168,18 +2181,12 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, static int 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 -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)); + return new_metric < old_metric; } - static void babel_postconfig(struct proto_config *CF) { @@ -2210,10 +2217,7 @@ babel_init(struct proto_config *CF) P->if_notify = babel_if_notify; P->rt_notify = babel_rt_notify; 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_same = babel_rte_same; return P; } diff --git a/proto/babel/babel.h b/proto/babel/babel.h index e075024c..f4cab422 100644 --- a/proto/babel/babel.h +++ b/proto/babel/babel.h @@ -27,6 +27,7 @@ #define EA_BABEL_METRIC EA_CODE(PROTOCOL_BABEL, 0) #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_VERSION 2