From 875cc073b067f295cccc668008e10218f8e98dd3 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 14 Mar 2019 17:22:22 +0100 Subject: Nest: Update handling of temporary attributes The temporary atttributes are no longer removed by ea_do_prune(), but they are undefined by store_tmp_attrs() protocol hooks. This fixes several bugs where temporary attributes were removed when they should not or not removed when they should be. The flag EAF_TEMP is no longer needed and was removed. Update all protocol make_tmp_attrs() / store_tmp_attrs() hooks to use helper functions and to handle unset attributes properly. Also fix some related bugs like improper handling of empty eattr list. --- proto/babel/babel.c | 45 ++++++++++++++------------------------------- proto/mrt/mrt.c | 2 +- proto/ospf/ospf.c | 26 ++++++++++---------------- proto/rip/rip.c | 38 +++++++++----------------------------- 4 files changed, 34 insertions(+), 77 deletions(-) (limited to 'proto') diff --git a/proto/babel/babel.c b/proto/babel/babel.c index d321f1d8..177ff3a3 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -645,7 +645,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) rte->u.babel.seqno = r->seqno; rte->u.babel.metric = r->metric; rte->u.babel.router_id = r->router_id; - rte->pflags = 0; + rte->pflags = EA_ID_FLAG(EA_BABEL_METRIC) | EA_ID_FLAG(EA_BABEL_ROUTER_ID); e->unreachable = 0; rte_update2(c, e->n.addr, rte, p->p.main_source); @@ -2077,32 +2077,6 @@ babel_kick_timer(struct babel_proto *p) } -static struct ea_list * -babel_prepare_attrs(struct linpool *pool, ea_list *next, uint metric, u64 router_id) -{ - struct ea_list *l = lp_alloc(pool, sizeof(struct ea_list) + 2*sizeof(eattr)); - struct adata *rid = lp_alloc(pool, sizeof(struct adata) + sizeof(u64)); - rid->length = sizeof(u64); - memcpy(&rid->data, &router_id, sizeof(u64)); - - l->next = next; - l->flags = EALF_SORTED; - l->count = 2; - - l->attrs[0].id = EA_BABEL_METRIC; - l->attrs[0].flags = 0; - l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP; - l->attrs[0].u.data = metric; - - l->attrs[1].id = EA_BABEL_ROUTER_ID; - l->attrs[1].flags = 0; - l->attrs[1].type = EAF_TYPE_OPAQUE | EAF_TEMP; - l->attrs[1].u.ptr = rid; - - return l; -} - - static int babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED) { @@ -2115,16 +2089,25 @@ babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED) return 0; } -static struct ea_list * +static void babel_make_tmp_attrs(struct rte *rt, struct linpool *pool) { - return babel_prepare_attrs(pool, NULL, rt->u.babel.metric, rt->u.babel.router_id); + 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) +babel_store_tmp_attrs(struct rte *rt, struct linpool *pool) { - rt->u.babel.metric = ea_get_int(rt->attrs->eattrs, EA_BABEL_METRIC, 0); + 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); } /* diff --git a/proto/mrt/mrt.c b/proto/mrt/mrt.c index 95014958..e4f1acea 100644 --- a/proto/mrt/mrt.c +++ b/proto/mrt/mrt.c @@ -496,7 +496,7 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, net *n, int add_path) continue; } - rte_make_tmp_attrs(&rt, s->linpool); + rte_make_tmp_attrs(&rt, s->linpool, NULL); if (f_run(s->filter, &rt, s->linpool, 0) <= F_ACCEPT) mrt_rib_table_entry(s, rt); diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index def73cb6..f3eabb47 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -106,8 +106,8 @@ #include "ospf.h" static int ospf_preexport(struct proto *P, rte **new, struct linpool *pool); -static struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool); -static void ospf_store_tmp_attrs(struct rte *rt); +static void ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool); +static void ospf_store_tmp_attrs(struct rte *rt, struct linpool *pool); static void ospf_reload_routes(struct channel *C); static int ospf_rte_better(struct rte *new, struct rte *old); static int ospf_rte_same(struct rte *new, struct rte *old); @@ -438,26 +438,20 @@ ospf_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED) return 0; } -static struct ea_list * +static void ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool) { - struct ea_list *e = lp_alloc(pool, sizeof(struct ea_list) + 4 * sizeof(eattr)); - - e->next = NULL; - e->flags = EALF_SORTED; - e->count = 0; - - rte_make_tmp_attr(rt, e, EA_OSPF_METRIC1, EAF_TYPE_INT, rt->u.ospf.metric1); - rte_make_tmp_attr(rt, e, EA_OSPF_METRIC2, EAF_TYPE_INT, rt->u.ospf.metric2); - rte_make_tmp_attr(rt, e, EA_OSPF_TAG, EAF_TYPE_INT, rt->u.ospf.tag); - rte_make_tmp_attr(rt, e, EA_OSPF_ROUTER_ID, EAF_TYPE_ROUTER_ID, rt->u.ospf.router_id); - - return e; + rte_init_tmp_attrs(rt, pool, 4); + rte_make_tmp_attr(rt, EA_OSPF_METRIC1, EAF_TYPE_INT, rt->u.ospf.metric1); + rte_make_tmp_attr(rt, EA_OSPF_METRIC2, EAF_TYPE_INT, rt->u.ospf.metric2); + rte_make_tmp_attr(rt, EA_OSPF_TAG, EAF_TYPE_INT, rt->u.ospf.tag); + rte_make_tmp_attr(rt, EA_OSPF_ROUTER_ID, EAF_TYPE_ROUTER_ID, rt->u.ospf.router_id); } static void -ospf_store_tmp_attrs(struct rte *rt) +ospf_store_tmp_attrs(struct rte *rt, struct linpool *pool) { + rte_init_tmp_attrs(rt, pool, 4); rt->u.ospf.metric1 = rte_store_tmp_attr(rt, EA_OSPF_METRIC1); rt->u.ospf.metric2 = rte_store_tmp_attr(rt, EA_OSPF_METRIC2); rt->u.ospf.tag = rte_store_tmp_attr(rt, EA_OSPF_TAG); diff --git a/proto/rip/rip.c b/proto/rip/rip.c index 612b6f92..91c00588 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -193,8 +193,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) e->u.rip.from = a0.nh.iface; e->u.rip.metric = rt_metric; e->u.rip.tag = rt_tag; - - e->pflags = 0; + e->pflags = EA_ID_FLAG(EA_RIP_METRIC) | EA_ID_FLAG(EA_RIP_TAG); rte_update(&p->p, en->n.addr, e); } @@ -997,28 +996,6 @@ rip_trigger_update(struct rip_proto *p) * RIP protocol glue */ -static struct ea_list * -rip_prepare_attrs(struct linpool *pool, ea_list *next, u8 metric, u16 tag) -{ - struct ea_list *l = lp_alloc(pool, sizeof(struct ea_list) + 2 * sizeof(eattr)); - - l->next = next; - l->flags = EALF_SORTED; - l->count = 2; - - l->attrs[0].id = EA_RIP_METRIC; - l->attrs[0].flags = 0; - l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP; - l->attrs[0].u.data = metric; - - l->attrs[1].id = EA_RIP_TAG; - l->attrs[1].flags = 0; - l->attrs[1].type = EAF_TYPE_INT | EAF_TEMP; - l->attrs[1].u.data = tag; - - return l; -} - static void rip_reload_routes(struct channel *C) { @@ -1032,17 +1009,20 @@ rip_reload_routes(struct channel *C) rip_kick_timer(p); } -static struct ea_list * +static void rip_make_tmp_attrs(struct rte *rt, struct linpool *pool) { - return rip_prepare_attrs(pool, NULL, rt->u.rip.metric, rt->u.rip.tag); + rte_init_tmp_attrs(rt, pool, 2); + rte_make_tmp_attr(rt, EA_RIP_METRIC, EAF_TYPE_INT, rt->u.rip.metric); + rte_make_tmp_attr(rt, EA_RIP_TAG, EAF_TYPE_INT, rt->u.rip.tag); } static void -rip_store_tmp_attrs(struct rte *rt) +rip_store_tmp_attrs(struct rte *rt, struct linpool *pool) { - rt->u.rip.metric = ea_get_int(rt->attrs->eattrs, EA_RIP_METRIC, 1); - rt->u.rip.tag = ea_get_int(rt->attrs->eattrs, EA_RIP_TAG, 0); + rte_init_tmp_attrs(rt, pool, 2); + rt->u.rip.metric = rte_store_tmp_attr(rt, EA_RIP_METRIC); + rt->u.rip.tag = rte_store_tmp_attr(rt, EA_RIP_TAG); } static int -- cgit v1.2.3