diff options
Diffstat (limited to 'proto/rip/rip.c')
-rw-r--r-- | proto/rip/rip.c | 108 |
1 files changed, 68 insertions, 40 deletions
diff --git a/proto/rip/rip.c b/proto/rip/rip.c index e1a235a0..6ca7a6b5 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -108,14 +108,14 @@ rip_add_rte(struct rip_proto *p, struct rip_rte **rp, struct rip_rte *src) } static inline void -rip_remove_rte(struct rip_proto *p, struct rip_rte **rp) +rip_remove_rte(struct rip_proto *p UNUSED, struct rip_rte **rp) { struct rip_rte *rt = *rp; rip_unlock_neighbor(rt->from); *rp = rt->next; - sl_free(p->rte_slab, rt); + sl_free(rt); } static inline int rip_same_rte(struct rip_rte *a, struct rip_rte *b) @@ -124,6 +124,11 @@ static inline int rip_same_rte(struct rip_rte *a, struct rip_rte *b) static inline int rip_valid_rte(struct rip_rte *rt) { return rt->from->ifa != NULL; } +struct rip_iface_adata { + struct adata ad; + struct iface *iface; +}; + /** * rip_announce_rte - announce route from RIP routing table to the core * @p: RIP instance @@ -145,7 +150,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) { /* Update */ rta a0 = { - .src = p->p.main_source, + .pref = p->p.main_channel->preference, .source = RTS_RIP, .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, @@ -188,13 +193,39 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) a0.nh.iface = rt->from->ifa->iface; } - rta *a = rta_lookup(&a0); - rte *e = rte_get_temp(a); + struct { + ea_list l; + eattr e[3]; + struct rip_iface_adata riad; + } ea_block = { + .l = { .count = 3, }, + .e = { + { + .id = EA_RIP_METRIC, + .type = EAF_TYPE_INT, + .u.data = rt_metric, + }, + { + .id = EA_RIP_TAG, + .type = EAF_TYPE_INT, + .u.data = rt_tag, + }, + { + .id = EA_RIP_FROM, + .type = EAF_TYPE_IFACE, + .u.ptr = &ea_block.riad.ad, + } + }, + .riad = { + .ad = { .length = sizeof(struct rip_iface_adata) - sizeof(struct adata) }, + .iface = a0.nh.iface, + }, + }; + + a0.eattrs = &ea_block.l; - 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); + rta *a = rta_lookup(&a0); + rte *e = rte_get_temp(a, p->p.main_source); rte_update(&p->p, en->n.addr, e); } @@ -307,8 +338,10 @@ 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); + const eattr *rie = ea_find(new->attrs->eattrs, EA_RIP_FROM); + struct iface *rt_from = rie ? ((struct rip_iface_adata *) rie->u.ptr)->iface : NULL; if (rt_metric > p->infinity) { @@ -339,7 +372,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->attrs->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 +1101,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 +1140,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 +1216,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->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 @@ -1338,3 +1360,9 @@ struct protocol proto_rip = { .get_route_info = rip_get_route_info, .get_attr = rip_get_attr }; + +void +rip_build(void) +{ + proto_build(&proto_rip); +} |