mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-09 12:48:43 +00:00
OSPF: Convert the rte-local attributes to extended attributes
This commit is contained in:
parent
0bb56d9b1b
commit
083e0dbb36
@ -222,13 +222,6 @@ typedef struct rte {
|
||||
byte pflags; /* Protocol-specific flags */
|
||||
btime lastmod; /* Last modified */
|
||||
union { /* Protocol-dependent data (metrics etc.) */
|
||||
#ifdef CONFIG_OSPF
|
||||
struct {
|
||||
u32 metric1, metric2; /* OSPF Type 1 and Type 2 metrics */
|
||||
u32 tag; /* External route tag */
|
||||
u32 router_id; /* Router that originated this route */
|
||||
} ospf;
|
||||
#endif
|
||||
#ifdef CONFIG_BABEL
|
||||
struct {
|
||||
u16 seqno; /* Babel seqno */
|
||||
|
@ -48,6 +48,10 @@
|
||||
#include "proto/rip/rip.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OSPF
|
||||
#include "proto/ospf/ospf.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BGP
|
||||
#include "proto/bgp/bgp.h"
|
||||
#endif
|
||||
@ -2826,7 +2830,7 @@ rt_get_igp_metric(rte *rt)
|
||||
if ((a->source == RTS_OSPF) ||
|
||||
(a->source == RTS_OSPF_IA) ||
|
||||
(a->source == RTS_OSPF_EXT1))
|
||||
return rt->u.ospf.metric1;
|
||||
return ea_find(rt->attrs->eattrs, EA_OSPF_METRIC1)->u.data;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RIP
|
||||
|
@ -108,11 +108,8 @@
|
||||
#include "ospf.h"
|
||||
|
||||
static int ospf_preexport(struct proto *P, rte **new, struct linpool *pool);
|
||||
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 void ospf_disp(timer *timer);
|
||||
|
||||
|
||||
@ -378,10 +375,7 @@ 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;
|
||||
|
||||
return P;
|
||||
}
|
||||
@ -390,7 +384,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,28 +394,19 @@ 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)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ospf_schedule_rtcalc(struct ospf_proto *p)
|
||||
{
|
||||
@ -501,26 +488,6 @@ ospf_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
|
||||
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
|
||||
@ -607,16 +574,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_find(rte->attrs->eattrs, EA_OSPF_METRIC1)->u.data);
|
||||
if (rte->attrs->source == RTS_OSPF_EXT2)
|
||||
buf += bsprintf(buf, "/%d", rte->u.ospf.metric2);
|
||||
buf += bsprintf(buf, "/%d", ea_find(rte->attrs->eattrs, EA_OSPF_METRIC2)->u.data);
|
||||
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)
|
||||
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
|
||||
|
@ -2053,25 +2053,50 @@ again1:
|
||||
|
||||
if (reload || ort_changed(nf, &a0))
|
||||
{
|
||||
rte e0 = {
|
||||
.attrs = rta_lookup(&a0),
|
||||
.u.ospf.metric1 = nf->old_metric1 = nf->n.metric1,
|
||||
.u.ospf.metric2 = nf->old_metric2 = nf->n.metric2,
|
||||
.u.ospf.tag = nf->old_tag = nf->n.tag,
|
||||
.u.ospf.router_id = nf->old_rid = nf->n.rid,
|
||||
.pflags = EA_ID_FLAG(EA_OSPF_METRIC1) | EA_ID_FLAG(EA_OSPF_ROUTER_ID),
|
||||
_Bool have_metric2 = (nf->n.type == RTS_OSPF_EXT2);
|
||||
_Bool have_tag = (((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2)) && nf->n.tag);
|
||||
_Bool have_router_id = !!nf->n.rid;
|
||||
|
||||
a0.eattrs = alloca(sizeof(ea_list) + (1 + have_metric2 + have_tag + have_router_id) * sizeof(eattr));
|
||||
memset(a0.eattrs, 0, sizeof(ea_list));
|
||||
|
||||
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 (have_metric2)
|
||||
a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
|
||||
.id = EA_OSPF_METRIC2,
|
||||
.type = EAF_TYPE_INT,
|
||||
.u.data = nf->n.metric2,
|
||||
};
|
||||
|
||||
if (have_tag)
|
||||
a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
|
||||
.id = EA_OSPF_TAG,
|
||||
.type = EAF_TYPE_INT,
|
||||
.u.data = nf->n.tag,
|
||||
};
|
||||
|
||||
if (have_router_id)
|
||||
a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
|
||||
.id = EA_OSPF_ROUTER_ID,
|
||||
.type = EAF_TYPE_ROUTER_ID,
|
||||
.u.data = nf->n.rid,
|
||||
};
|
||||
|
||||
rte e0 = { .attrs = rta_lookup(&a0), };
|
||||
|
||||
rta_free(nf->old_rta);
|
||||
nf->old_rta = rta_clone(e0.attrs);
|
||||
|
||||
if (nf->n.type == RTS_OSPF_EXT2)
|
||||
e0.pflags |= EA_ID_FLAG(EA_OSPF_METRIC2);
|
||||
|
||||
/* Perhaps onfly if tag is non-zero? */
|
||||
if ((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2))
|
||||
e0.pflags |= EA_ID_FLAG(EA_OSPF_TAG);
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user