.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,
};
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;
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
{
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;
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.
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)
{
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)
{
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;
}