diff options
author | Maria Matejka <mq@ucw.cz> | 2022-03-09 11:01:44 +0100 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2022-03-09 11:02:55 +0100 |
commit | 24773af9e099530aa6ccf4c730ad31c452284228 (patch) | |
tree | 373d1835e6b16a4946690fa467f89eba8b0a58b7 /proto/rip | |
parent | 83d9920f90738e4df75b3cf57335b43c094051cd (diff) | |
parent | e42eedb912428aa9af450b0426e53b0a7004dfb1 (diff) |
Merge commit 'e42eedb9' into haugesund
Diffstat (limited to 'proto/rip')
-rw-r--r-- | proto/rip/rip.c | 74 | ||||
-rw-r--r-- | proto/rip/rip.h | 1 |
2 files changed, 41 insertions, 34 deletions
diff --git a/proto/rip/rip.c b/proto/rip/rip.c index f2e56e93..0556939a 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -188,12 +188,28 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) a0.nh.iface = rt->from->ifa->iface; } + a0.eattrs = alloca(sizeof(ea_list) + 3*sizeof(eattr)); + memset(a0.eattrs, 0, sizeof(ea_list)); /* Zero-ing only the ea_list header */ + a0.eattrs->count = 3; + a0.eattrs->attrs[0] = (eattr) { + .id = EA_RIP_METRIC, + .type = EAF_TYPE_INT, + .u.data = rt_metric, + }; + a0.eattrs->attrs[1] = (eattr) { + .id = EA_RIP_TAG, + .type = EAF_TYPE_INT, + .u.data = rt_tag, + }; + a0.eattrs->attrs[2] = (eattr) { + .id = EA_RIP_FROM, + .type = EAF_TYPE_PTR, + .u.data = (uintptr_t) a0.nh.iface, + }; + rta *a = rta_lookup(&a0); rte *e = rte_get_temp(a, p->p.main_source); - e->u.rip.from = a0.nh.iface; - e->u.rip.metric = rt_metric; - e->u.rip.tag = rt_tag; e->pflags = EA_ID_FLAG(EA_RIP_METRIC) | EA_ID_FLAG(EA_RIP_TAG); rte_update(&p->p, en->n.addr, e); @@ -307,8 +323,9 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s if (new) { /* Update */ - u32 rt_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1); u32 rt_tag = ea_get_int(new->attrs->eattrs, EA_RIP_TAG, 0); + u32 rt_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1); + struct iface *rt_from = (struct iface *) ea_get_int(new->attrs->eattrs, EA_RIP_FROM, 0); if (rt_metric > p->infinity) { @@ -339,7 +356,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s en->valid = RIP_ENTRY_VALID; en->metric = rt_metric; en->tag = rt_tag; - en->from = (new->src->proto == P) ? new->u.rip.from : NULL; + en->from = (new->src->proto == P) ? rt_from : NULL; en->iface = new->attrs->nh.iface; en->next_hop = new->attrs->nh.gw; } @@ -1068,37 +1085,24 @@ rip_reload_routes(struct channel *C) rip_kick_timer(p); } -static void -rip_make_tmp_attrs(struct rte *rt, struct linpool *pool) -{ - 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, struct linpool *pool) -{ - 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 rip_rte_better(struct rte *new, struct rte *old) { - return new->u.rip.metric < old->u.rip.metric; + ASSERT_DIE(new->src == old->src); + struct rip_proto *p = (struct rip_proto *) new->src->proto; + + u32 new_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, p->infinity); + u32 old_metric = ea_get_int(old->attrs->eattrs, EA_RIP_METRIC, p->infinity); + + return new_metric < old_metric; } -static int -rip_rte_same(struct rte *new, struct rte *old) +static u32 +rip_rte_igp_metric(struct rte *rt) { - return ((new->u.rip.metric == old->u.rip.metric) && - (new->u.rip.tag == old->u.rip.tag) && - (new->u.rip.from == old->u.rip.from)); + return ea_get_int(rt->attrs->eattrs, EA_RIP_METRIC, IGP_METRIC_UNKNOWN); } - static void rip_postconfig(struct proto_config *CF) { @@ -1120,10 +1124,8 @@ rip_init(struct proto_config *CF) P->rt_notify = rip_rt_notify; P->neigh_notify = rip_neigh_notify; P->reload_routes = rip_reload_routes; - P->make_tmp_attrs = rip_make_tmp_attrs; - P->store_tmp_attrs = rip_store_tmp_attrs; P->rte_better = rip_rte_better; - P->rte_same = rip_rte_same; + P->rte_igp_metric = rip_rte_igp_metric; return P; } @@ -1198,10 +1200,14 @@ rip_reconfigure(struct proto *P, struct proto_config *CF) static void rip_get_route_info(rte *rte, byte *buf) { - buf += bsprintf(buf, " (%d/%d)", rte->attrs->pref, rte->u.rip.metric); + struct rip_proto *p = (struct rip_proto *) rte->src->proto; + u32 rt_metric = ea_get_int(rte->attrs->eattrs, EA_RIP_METRIC, p->infinity); + u32 rt_tag = ea_get_int(rte->attrs->eattrs, EA_RIP_TAG, 0); + + buf += bsprintf(buf, " (%d/%d)", rte->attrs->pref, rt_metric); - if (rte->u.rip.tag) - bsprintf(buf, " [%04x]", rte->u.rip.tag); + if (rt_tag) + bsprintf(buf, " [%04x]", rt_tag); } static int diff --git a/proto/rip/rip.h b/proto/rip/rip.h index 8d347000..f8713c4a 100644 --- a/proto/rip/rip.h +++ b/proto/rip/rip.h @@ -197,6 +197,7 @@ struct rip_rte #define EA_RIP_METRIC EA_CODE(PROTOCOL_RIP, 0) #define EA_RIP_TAG EA_CODE(PROTOCOL_RIP, 1) +#define EA_RIP_FROM EA_CODE(PROTOCOL_RIP, 2) static inline int rip_is_v2(struct rip_proto *p) { return p->rip2; } |