summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/babel/babel.c95
-rw-r--r--proto/babel/babel.h1
-rw-r--r--proto/bgp/attrs.c7
-rw-r--r--proto/bgp/bgp.c1
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/ospf/ospf.c72
-rw-r--r--proto/ospf/rt.c52
-rw-r--r--proto/rip/rip.c74
-rw-r--r--proto/rip/rip.h1
9 files changed, 171 insertions, 133 deletions
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 09d8ad7e..30809000 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -648,6 +648,29 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
.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,
};
/*
@@ -660,10 +683,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
rta *a = rta_lookup(&a0);
rte *rte = rte_get_temp(a, p->p.main_source);
- 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);
e->unreachable = 0;
rte_update2(c, e->n.addr, rte, p->p.main_source);
@@ -680,7 +699,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
rta *a = rta_lookup(&a0);
rte *rte = rte_get_temp(a, p->p.main_source);
- memset(&rte->u.babel, 0, sizeof(rte->u.babel));
rte->pflags = 0;
e->unreachable = 1;
@@ -2009,7 +2027,13 @@ babel_dump(struct proto *P)
static void
babel_get_route_info(rte *rte, byte *buf)
{
- buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->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 +2041,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;
@@ -2240,27 +2267,6 @@ babel_preexport(struct proto *P, struct rte *new)
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.
@@ -2275,10 +2281,22 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
if (new)
{
/* Update */
- uint internal = (new->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)
{
@@ -2321,15 +2339,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);
}
@@ -2363,10 +2382,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;
}
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/bgp/attrs.c b/proto/bgp/attrs.c
index 09c0bc57..6963833a 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -374,6 +374,13 @@ bgp_init_aigp_metric(rte *e, u64 *metric, const struct adata **ad)
return *metric < IGP_METRIC_UNKNOWN;
}
+u32
+bgp_rte_igp_metric(struct rte *rt)
+{
+ u64 metric = bgp_total_aigp_metric(rt);
+ return (u32) MIN(metric, (u64) IGP_METRIC_UNKNOWN);
+}
+
/*
* Attribute hooks
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index b5a31ab7..52400762 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -1679,6 +1679,7 @@ bgp_init(struct proto_config *CF)
P->rte_mergable = bgp_rte_mergable;
P->rte_recalculate = cf->deterministic_med ? bgp_rte_recalculate : NULL;
P->rte_modify = bgp_rte_modify_stale;
+ P->rte_igp_metric = bgp_rte_igp_metric;
p->cf = cf;
p->is_internal = (cf->local_as == cf->remote_as);
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 9d25da21..26e04966 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -584,6 +584,7 @@ int bgp_rte_better(struct rte *, struct rte *);
int bgp_rte_mergable(rte *pri, rte *sec);
int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best);
struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool);
+u32 bgp_rte_igp_metric(struct rte *);
void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old);
int bgp_preexport(struct proto *, struct rte *);
int bgp_get_attr(const struct eattr *e, byte *buf, int buflen);
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index 03b16350..f9aa6cd1 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -108,11 +108,9 @@
#include "ospf.h"
static int ospf_preexport(struct proto *P, rte *new);
-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);
+static u32 ospf_rte_igp_metric(struct rte *rt);
static void ospf_disp(timer *timer);
@@ -378,10 +376,8 @@ ospf_init(struct proto_config *CF)
P->reload_routes = ospf_reload_routes;
P->feed_begin = ospf_feed_begin;
P->feed_end = ospf_feed_end;
- P->make_tmp_attrs = ospf_make_tmp_attrs;
- P->store_tmp_attrs = ospf_store_tmp_attrs;
P->rte_better = ospf_rte_better;
- P->rte_same = ospf_rte_same;
+ P->rte_igp_metric = ospf_rte_igp_metric;
return P;
}
@@ -390,7 +386,9 @@ ospf_init(struct proto_config *CF)
static int
ospf_rte_better(struct rte *new, struct rte *old)
{
- if (new->u.ospf.metric1 == LSINFINITY)
+ u32 new_metric1 = ea_get_int(new->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY);
+
+ if (new_metric1 == LSINFINITY)
return 0;
if(new->attrs->source < old->attrs->source) return 1;
@@ -398,27 +396,27 @@ ospf_rte_better(struct rte *new, struct rte *old)
if(new->attrs->source == RTS_OSPF_EXT2)
{
- if(new->u.ospf.metric2 < old->u.ospf.metric2) return 1;
- if(new->u.ospf.metric2 > old->u.ospf.metric2) return 0;
+ u32 old_metric2 = ea_get_int(old->attrs->eattrs, EA_OSPF_METRIC2, LSINFINITY);
+ u32 new_metric2 = ea_get_int(new->attrs->eattrs, EA_OSPF_METRIC2, LSINFINITY);
+ if(new_metric2 < old_metric2) return 1;
+ if(new_metric2 > old_metric2) return 0;
}
- if (new->u.ospf.metric1 < old->u.ospf.metric1)
+ u32 old_metric1 = ea_get_int(old->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY);
+ if (new_metric1 < old_metric1)
return 1;
return 0; /* Old is shorter or same */
}
-static int
-ospf_rte_same(struct rte *new, struct rte *old)
+static u32
+ospf_rte_igp_metric(struct rte *rt)
{
- /* new->attrs == old->attrs always */
- return
- new->u.ospf.metric1 == old->u.ospf.metric1 &&
- new->u.ospf.metric2 == old->u.ospf.metric2 &&
- new->u.ospf.tag == old->u.ospf.tag &&
- new->u.ospf.router_id == old->u.ospf.router_id;
-}
+ if (rt->attrs->source == RTS_OSPF_EXT2)
+ return IGP_METRIC_UNKNOWN;
+ return ea_get_int(rt->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY);
+}
void
ospf_schedule_rtcalc(struct ospf_proto *p)
@@ -500,26 +498,6 @@ ospf_preexport(struct proto *P, rte *e)
return 0;
}
-static void
-ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool)
-{
- 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, 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);
- rt->u.ospf.router_id = rte_store_tmp_attr(rt, EA_OSPF_ROUTER_ID);
-}
-
/**
* ospf_shutdown - Finish of OSPF instance
* @P: OSPF protocol instance
@@ -609,16 +587,20 @@ ospf_get_route_info(rte * rte, byte * buf)
}
buf += bsprintf(buf, " %s", type);
- buf += bsprintf(buf, " (%d/%d", rte->attrs->pref, rte->u.ospf.metric1);
+ buf += bsprintf(buf, " (%d/%d", rte->attrs->pref, ea_get_int(rte->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY));
if (rte->attrs->source == RTS_OSPF_EXT2)
- buf += bsprintf(buf, "/%d", rte->u.ospf.metric2);
+ buf += bsprintf(buf, "/%d", ea_get_int(rte->attrs->eattrs, EA_OSPF_METRIC2, LSINFINITY));
buf += bsprintf(buf, ")");
- if ((rte->attrs->source == RTS_OSPF_EXT1 || rte->attrs->source == RTS_OSPF_EXT2) && rte->u.ospf.tag)
+ if (rte->attrs->source == RTS_OSPF_EXT1 || rte->attrs->source == RTS_OSPF_EXT2)
{
- buf += bsprintf(buf, " [%x]", rte->u.ospf.tag);
+ eattr *ea = ea_find(rte->attrs->eattrs, EA_OSPF_TAG);
+ if (ea && (ea->u.data > 0))
+ buf += bsprintf(buf, " [%x]", ea->u.data);
}
- if (rte->u.ospf.router_id)
- buf += bsprintf(buf, " [%R]", rte->u.ospf.router_id);
+
+ eattr *ea = ea_find(rte->attrs->eattrs, EA_OSPF_ROUTER_ID);
+ if (ea)
+ buf += bsprintf(buf, " [%R]", ea->u.data);
}
static int
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index cda464e0..471bb586 100644
--- a/proto/ospf/rt.c
+++ b/proto/ospf/rt.c
@@ -144,7 +144,7 @@ orta_compare(const struct ospf_proto *p, const orta *new, const orta *old)
{
int r;
- if (old->type == RTS_DUMMY)
+ if (!old->type)
return 1;
/* Prefer intra-area to inter-area to externals */
@@ -195,7 +195,7 @@ orta_compare_asbr(const struct ospf_proto *p, const orta *new, const orta *old)
{
int r;
- if (old->type == RTS_DUMMY)
+ if (!old->type)
return 1;
if (!p->rfc1583)
@@ -225,7 +225,7 @@ orta_compare_ext(const struct ospf_proto *p, const orta *new, const orta *old)
{
int r;
- if (old->type == RTS_DUMMY)
+ if (!old->type)
return 1;
/* 16.4 (6a) - prefer routes with lower type */
@@ -2062,23 +2062,45 @@ again1:
if (reload || ort_changed(nf, &a0))
{
- rta *a = rta_lookup(&a0);
- rte *e = rte_get_temp(a, p->p.main_source);
+ a0.eattrs = alloca(sizeof(ea_list) + 4 * sizeof(eattr));
+ memset(a0.eattrs, 0, sizeof(ea_list));
- rta_free(nf->old_rta);
- nf->old_rta = rta_clone(a);
- e->u.ospf.metric1 = nf->old_metric1 = nf->n.metric1;
- e->u.ospf.metric2 = nf->old_metric2 = nf->n.metric2;
- e->u.ospf.tag = nf->old_tag = nf->n.tag;
- e->u.ospf.router_id = nf->old_rid = nf->n.rid;
- e->pflags = EA_ID_FLAG(EA_OSPF_METRIC1) | EA_ID_FLAG(EA_OSPF_ROUTER_ID);
+ nf->old_metric1 = nf->n.metric1;
+ nf->old_metric2 = nf->n.metric2;
+ nf->old_tag = nf->n.tag;
+ nf->old_rid = nf->n.rid;
+
+ a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
+ .id = EA_OSPF_METRIC1,
+ .type = EAF_TYPE_INT,
+ .u.data = nf->n.metric1,
+ };
if (nf->n.type == RTS_OSPF_EXT2)
- e->pflags |= EA_ID_FLAG(EA_OSPF_METRIC2);
+ a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
+ .id = EA_OSPF_METRIC2,
+ .type = EAF_TYPE_INT,
+ .u.data = nf->n.metric2,
+ };
- /* Perhaps onfly if tag is non-zero? */
if ((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2))
- e->pflags |= EA_ID_FLAG(EA_OSPF_TAG);
+ a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
+ .id = EA_OSPF_TAG,
+ .type = EAF_TYPE_INT,
+ .u.data = nf->n.tag,
+ };
+
+ a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
+ .id = EA_OSPF_ROUTER_ID,
+ .type = EAF_TYPE_ROUTER_ID,
+ .u.data = nf->n.rid,
+ };
+
+ rta *a = rta_lookup(&a0);
+ rte *e = rte_get_temp(a, p->p.main_source);
+
+ rta_free(nf->old_rta);
+ nf->old_rta = rta_clone(a);
DBG("Mod rte type %d - %N via %I on iface %s, met %d\n",
a0.source, nf->fn.addr, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1);
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; }