diff options
Diffstat (limited to 'proto/babel')
-rw-r--r-- | proto/babel/Makefile | 1 | ||||
-rw-r--r-- | proto/babel/babel.c | 129 | ||||
-rw-r--r-- | proto/babel/babel.h | 1 | ||||
-rw-r--r-- | proto/babel/packets.c | 9 |
4 files changed, 81 insertions, 59 deletions
diff --git a/proto/babel/Makefile b/proto/babel/Makefile index 06b58e95..ae6aeaf2 100644 --- a/proto/babel/Makefile +++ b/proto/babel/Makefile @@ -2,5 +2,6 @@ src := babel.c packets.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,babel_build) tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/babel/babel.c b/proto/babel/babel.c index 71452a6f..d9ebfbad 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -119,7 +119,7 @@ babel_get_source(struct babel_proto *p, struct babel_entry *e, u64 router_id) } static void -babel_expire_sources(struct babel_proto *p, struct babel_entry *e) +babel_expire_sources(struct babel_proto *p UNUSED, struct babel_entry *e) { struct babel_source *n, *nx; btime now_ = current_time(); @@ -129,7 +129,7 @@ babel_expire_sources(struct babel_proto *p, struct babel_entry *e) if (n->expires && n->expires <= now_) { rem_node(NODE n); - sl_free(p->source_slab, n); + sl_free(n); } } } @@ -174,7 +174,7 @@ babel_retract_route(struct babel_proto *p, struct babel_route *r) } static void -babel_flush_route(struct babel_proto *p, struct babel_route *r) +babel_flush_route(struct babel_proto *p UNUSED, struct babel_route *r) { DBG("Babel: Flush route %N router_id %lR neigh %I\n", r->e->n.addr, r->router_id, r->neigh->addr); @@ -185,7 +185,7 @@ babel_flush_route(struct babel_proto *p, struct babel_route *r) if (r->e->selected == r) r->e->selected = NULL; - sl_free(p->route_slab, r); + sl_free(r); } static void @@ -338,13 +338,13 @@ found: } static void -babel_remove_seqno_request(struct babel_proto *p, struct babel_seqno_request *sr) +babel_remove_seqno_request(struct babel_proto *p UNUSED, struct babel_seqno_request *sr) { if (sr->nbr) rem_node(&sr->nbr_node); rem_node(NODE sr); - sl_free(p->seqno_slab, sr); + sl_free(sr); } static int @@ -640,13 +640,36 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) if (r) { rta a0 = { - .src = p->p.main_source, .source = RTS_BABEL, .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, + .pref = c->preference, .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, }; /* @@ -658,11 +681,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) a0.nh.flags = RNF_ONLINK; rta *a = rta_lookup(&a0); - rte *rte = rte_get_temp(a); - rte->u.babel.seqno = r->seqno; - rte->u.babel.metric = r->metric; - rte->u.babel.router_id = r->router_id; - rte->pflags = EA_ID_FLAG(EA_BABEL_METRIC) | EA_ID_FLAG(EA_BABEL_ROUTER_ID); + rte *rte = rte_get_temp(a, p->p.main_source); e->unreachable = 0; rte_update2(c, e->n.addr, rte, p->p.main_source); @@ -671,17 +690,15 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) { /* Unreachable */ rta a0 = { - .src = p->p.main_source, .source = RTS_BABEL, .scope = SCOPE_UNIVERSE, .dest = RTD_UNREACHABLE, + .pref = 1, }; rta *a = rta_lookup(&a0); - rte *rte = rte_get_temp(a); - memset(&rte->u.babel, 0, sizeof(rte->u.babel)); + rte *rte = rte_get_temp(a, p->p.main_source); rte->pflags = 0; - rte->pref = 1; e->unreachable = 1; rte_update2(c, e->n.addr, rte, p->p.main_source); @@ -2009,7 +2026,13 @@ babel_dump(struct proto *P) static void babel_get_route_info(rte *rte, byte *buf) { - buf += bsprintf(buf, " (%d/%d) [%lR]", rte->pref, rte->u.babel.metric, rte->u.babel.router_id); + u64 rid = 0; + eattr *e = ea_find(rte->attrs->eattrs, EA_BABEL_ROUTER_ID); + if (e) + memcpy(&rid, e->u.ptr->data, sizeof(u64)); + + buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->pref, + ea_get_int(rte->attrs->eattrs, EA_BABEL_METRIC, BABEL_INFINITY), rid); } static int @@ -2017,6 +2040,9 @@ babel_get_attr(const eattr *a, byte *buf, int buflen UNUSED) { switch (a->id) { + case EA_BABEL_SEQNO: + return GA_FULL; + case EA_BABEL_METRIC: bsprintf(buf, "metric: %d", a->u.data); return GA_FULL; @@ -2230,38 +2256,16 @@ babel_kick_timer(struct babel_proto *p) static int -babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED) +babel_preexport(struct proto *P, struct rte *new) { - struct rta *a = (*new)->attrs; - + struct rta *a = new->attrs; /* Reject our own unreachable routes */ - if ((a->dest == RTD_UNREACHABLE) && (a->src->proto == P)) + if ((a->dest == RTD_UNREACHABLE) && (new->src->proto == P)) return -1; 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. @@ -2276,10 +2280,22 @@ 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 = 0; + + if (new->src->proto == P) + { + rt_seqno = ea_find(new->attrs->eattrs, EA_BABEL_SEQNO)->u.data; + eattr *e = ea_find(new->attrs->eattrs, EA_BABEL_ROUTER_ID); + if (e) + memcpy(&rt_router_id, e->u.ptr->data, sizeof(u64)); + } + else + { + rt_seqno = p->update_seqno; + rt_router_id = p->router_id; + } if (rt_metric > BABEL_INFINITY) { @@ -2322,15 +2338,16 @@ 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; + + return new_metric < old_metric; } -static int -babel_rte_same(struct rte *new, struct rte *old) +static u32 +babel_rte_igp_metric(struct rte *rt) { - 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 ea_get_int(rt->attrs->eattrs, EA_BABEL_METRIC, BABEL_INFINITY); } @@ -2364,10 +2381,8 @@ 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; + P->rte_igp_metric = babel_rte_igp_metric; return P; } @@ -2483,3 +2498,9 @@ struct protocol proto_babel = { .get_route_info = babel_get_route_info, .get_attr = babel_get_attr }; + +void +babel_build(void) +{ + proto_build(&proto_babel); +} diff --git a/proto/babel/babel.h b/proto/babel/babel.h index 84feb085..8b6da3c8 100644 --- a/proto/babel/babel.h +++ b/proto/babel/babel.h @@ -28,6 +28,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 diff --git a/proto/babel/packets.c b/proto/babel/packets.c index 2647a79f..d4acc170 100644 --- a/proto/babel/packets.c +++ b/proto/babel/packets.c @@ -1318,7 +1318,6 @@ babel_send_to(struct babel_iface *ifa, ip_addr dest) static uint babel_write_queue(struct babel_iface *ifa, list *queue) { - struct babel_proto *p = ifa->proto; struct babel_write_state state = { .next_hop_ip6 = ifa->addr }; if (EMPTY_LIST(*queue)) @@ -1346,7 +1345,7 @@ babel_write_queue(struct babel_iface *ifa, list *queue) pos += len; rem_node(NODE msg); - sl_free(p->msg_slab, msg); + sl_free(msg); } pos += babel_auth_add_tlvs(ifa, (struct babel_tlv *) pos, end - pos); @@ -1507,13 +1506,13 @@ babel_process_packet(struct babel_iface *ifa, else if (res == PARSE_IGNORE) { DBG("Babel: Ignoring TLV of type %d\n", tlv->type); - sl_free(p->msg_slab, msg); + sl_free(msg); } else /* PARSE_ERROR */ { LOG_PKT("Bad TLV from %I via %s type %d pos %d - parse error", saddr, ifa->iface->name, tlv->type, (int) ((byte *)tlv - (byte *)pkt)); - sl_free(p->msg_slab, msg); + sl_free(msg); break; } } @@ -1525,7 +1524,7 @@ babel_process_packet(struct babel_iface *ifa, if (tlv_data[msg->msg.type].handle_tlv) tlv_data[msg->msg.type].handle_tlv(&msg->msg, ifa); rem_node(NODE msg); - sl_free(p->msg_slab, msg); + sl_free(msg); } } |