diff --git a/nest/route.h b/nest/route.h index 1809f7cc..a7a2782f 100644 --- a/nest/route.h +++ b/nest/route.h @@ -222,13 +222,6 @@ typedef struct rte { byte pflags; /* Protocol-specific flags */ btime lastmod; /* Last modified */ union { /* Protocol-dependent data (metrics etc.) */ -#ifdef CONFIG_RIP - struct { - struct iface *from; /* Incoming iface */ - u8 metric; /* RIP metric */ - u16 tag; /* External route tag */ - } rip; -#endif #ifdef CONFIG_OSPF struct { u32 metric1, metric2; /* OSPF Type 1 and Type 2 metrics */ diff --git a/nest/rt-table.c b/nest/rt-table.c index 94e3af30..a35ff93f 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -44,6 +44,10 @@ #include "lib/string.h" #include "lib/alloca.h" +#ifdef CONFIG_RIP +#include "proto/rip/rip.h" +#endif + #ifdef CONFIG_BGP #include "proto/bgp/bgp.h" #endif @@ -2826,8 +2830,8 @@ rt_get_igp_metric(rte *rt) #endif #ifdef CONFIG_RIP - if (a->source == RTS_RIP) - return rt->u.rip.metric; + if (ea = ea_find(rt->attrs->eattrs, EA_RIP_METRIC)) + return ea->u.data; #endif #ifdef CONFIG_BGP diff --git a/proto/rip/rip.c b/proto/rip/rip.c index 9befbbd1..f56fb6c4 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -188,14 +188,27 @@ 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, + }; + rte e0 = { .attrs = &a0, - .u.rip = { - .from = a0.nh.iface, - .metric = rt_metric, - .tag = rt_tag, - }, - .pflags = EA_ID_FLAG(EA_RIP_METRIC) | EA_ID_FLAG(EA_RIP_TAG) }; rte_update(p->p.main_channel, en->n.addr, &e0); @@ -306,8 +319,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) { @@ -338,7 +352,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 = rt_from; en->iface = new->attrs->nh.iface; en->next_hop = new->attrs->nh.gw; } @@ -1053,37 +1067,15 @@ 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; -} + u32 new_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1); + u32 old_metric = ea_get_int(old->attrs->eattrs, EA_RIP_METRIC, 1); -static int -rip_rte_same(struct rte *new, struct rte *old) -{ - 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 new_metric < old_metric; } - static void rip_postconfig(struct proto_config *CF) { @@ -1105,10 +1097,7 @@ 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; return P; } @@ -1183,10 +1172,13 @@ 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); + u32 rt_metric = ea_get_int(rte->attrs->eattrs, EA_RIP_METRIC, 1); + u32 rt_tag = ea_get_int(rte->attrs->eattrs, EA_RIP_TAG, 0); - if (rte->u.rip.tag) - bsprintf(buf, " [%04x]", rte->u.rip.tag); + buf += bsprintf(buf, " (%d/%d)", rte->attrs->pref, rt_metric); + + if (rt_tag) + bsprintf(buf, " [%04x]", rt_tag); } static int @@ -1202,6 +1194,10 @@ rip_get_attr(const eattr *a, byte *buf, int buflen UNUSED) bsprintf(buf, "tag: %04x", a->u.data); return GA_FULL; + case EA_RIP_FROM: + bsprintf(buf, "from: %s", ((struct iface *) a->u.data)->name); + return GA_FULL; + default: return GA_UNKNOWN; } 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; }