summaryrefslogtreecommitdiff
path: root/proto/ospf
diff options
context:
space:
mode:
Diffstat (limited to 'proto/ospf')
-rw-r--r--proto/ospf/iface.c15
-rw-r--r--proto/ospf/neighbor.c6
-rw-r--r--proto/ospf/ospf.c93
-rw-r--r--proto/ospf/ospf.h2
-rw-r--r--proto/ospf/rt.c62
-rw-r--r--proto/ospf/topology.c12
-rw-r--r--proto/ospf/topology.h2
7 files changed, 106 insertions, 86 deletions
diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c
index f38b8210..049030ac 100644
--- a/proto/ospf/iface.c
+++ b/proto/ospf/iface.c
@@ -311,7 +311,7 @@ ospf_iface_remove(struct ospf_iface *ifa)
ospf_iface_sm(ifa, ISM_DOWN);
rem_node(NODE ifa);
- rfree(ifa->pool);
+ rp_free(ifa->pool, p->p.pool);
}
void
@@ -522,7 +522,10 @@ static inline void
add_nbma_node(struct ospf_iface *ifa, struct nbma_node *src, int found)
{
struct nbma_node *n = mb_alloc(ifa->pool, sizeof(struct nbma_node));
+
+ n->n = (node) {};
add_tail(&ifa->nbma_list, NODE n);
+
n->ip = src->ip;
n->eligible = src->eligible;
n->found = found;
@@ -564,7 +567,7 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
OSPF_TRACE(D_EVENTS, "Adding interface %s (%N) to area %R",
iface->name, &addr->prefix, oa->areaid);
- pool = rp_new(p->p.pool, "OSPF Interface");
+ pool = rp_new(p->p.pool, p->p.loop, "OSPF Interface");
ifa = mb_allocz(pool, sizeof(struct ospf_iface));
ifa->iface = iface;
ifa->addr = addr;
@@ -684,7 +687,7 @@ ospf_iface_new_vlink(struct ospf_proto *p, struct ospf_iface_patt *ip)
/* Vlink ifname is stored just after the ospf_iface structure */
- pool = rp_new(p->p.pool, "OSPF Vlink");
+ pool = rp_new(p->p.pool, p->p.loop, "OSPF Vlink");
ifa = mb_allocz(pool, sizeof(struct ospf_iface) + 16);
ifa->oa = p->backbone;
ifa->cf = ip;
@@ -1222,7 +1225,8 @@ ospf_reconfigure_ifaces2(struct ospf_proto *p)
struct iface *iface;
struct ifa *a;
- WALK_LIST(iface, iface_list)
+ IFACE_LEGACY_ACCESS;
+ WALK_LIST(iface, global_iface_list)
{
if (! (iface->flags & IF_UP))
continue;
@@ -1268,7 +1272,8 @@ ospf_reconfigure_ifaces3(struct ospf_proto *p)
struct iface *iface;
struct ifa *a;
- WALK_LIST(iface, iface_list)
+ IFACE_LEGACY_ACCESS;
+ WALK_LIST(iface, global_iface_list)
{
if (! (iface->flags & IF_UP))
continue;
diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c
index ca369819..4ae0d3fa 100644
--- a/proto/ospf/neighbor.c
+++ b/proto/ospf/neighbor.c
@@ -80,7 +80,7 @@ struct ospf_neighbor *
ospf_neighbor_new(struct ospf_iface *ifa)
{
struct ospf_proto *p = ifa->oa->po;
- struct pool *pool = rp_new(p->p.pool, "OSPF Neighbor");
+ struct pool *pool = rp_new(p->p.pool, p->p.loop, "OSPF Neighbor");
struct ospf_neighbor *n = mb_allocz(pool, sizeof(struct ospf_neighbor));
n->pool = pool;
@@ -120,7 +120,7 @@ ospf_neigh_down(struct ospf_neighbor *n)
s_get(&(n->dbsi));
release_lsrtl(p, n);
rem_node(NODE n);
- rfree(n->pool);
+ rp_free(n->pool, p->p.pool);
OSPF_TRACE(D_EVENTS, "Neighbor %R on %s removed", rid, ifa->ifname);
}
@@ -777,7 +777,7 @@ ospf_neigh_update_bfd(struct ospf_neighbor *n, int use_bfd)
if (use_bfd && !n->bfd_req)
n->bfd_req = bfd_request_session(n->pool, n->ip, n->ifa->addr->ip,
n->ifa->iface, p->p.vrf,
- ospf_neigh_bfd_hook, n, NULL);
+ ospf_neigh_bfd_hook, n, birdloop_event_list(p->p.loop), NULL);
if (!use_bfd && n->bfd_req)
{
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index ba8c2e2b..16774df6 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -107,12 +107,10 @@
#include <stdlib.h>
#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 int ospf_preexport(struct channel *C, rte *new);
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->sources.class = &ospf_rte_owner_class;
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)
@@ -484,14 +482,13 @@ ospf_disp(timer * timer)
* import to the filters.
*/
static int
-ospf_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
+ospf_preexport(struct channel *c, rte *e)
{
- struct ospf_proto *p = (struct ospf_proto *) P;
+ struct ospf_proto *p = (struct ospf_proto *) c->proto;
struct ospf_area *oa = ospf_main_area(p);
- rte *e = *new;
/* Reject our own routes */
- if (e->attrs->src->proto == P)
+ if (e->sender == c->in_req.hook)
return -1;
/* Do not export routes to stub areas */
@@ -501,26 +498,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
@@ -558,6 +535,9 @@ ospf_shutdown(struct proto *P)
}
FIB_WALK_END;
+ if (tm_active(p->disp_timer))
+ tm_stop(p->disp_timer);
+
return PS_DOWN;
}
@@ -607,16 +587,20 @@ ospf_get_route_info(rte * rte, byte * buf)
}
buf += bsprintf(buf, " %s", type);
- buf += bsprintf(buf, " (%d/%d", rte->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
@@ -1533,6 +1517,12 @@ ospf_sh_lsadb(struct lsadb_show_data *ld)
}
+struct rte_owner_class ospf_rte_owner_class = {
+ .get_route_info = ospf_get_route_info,
+ .rte_better = ospf_rte_better,
+ .rte_igp_metric = ospf_rte_igp_metric,
+};
+
struct protocol proto_ospf = {
.name = "OSPF",
.template = "ospf%d",
@@ -1548,5 +1538,4 @@ struct protocol proto_ospf = {
.reconfigure = ospf_reconfigure,
.get_status = ospf_get_status,
.get_attr = ospf_get_attr,
- .get_route_info = ospf_get_route_info
};
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index 3e704ae8..a5f83e79 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -1007,6 +1007,8 @@ void ospf_sh_state(struct proto *P, int verbose, int reachable);
void ospf_sh_lsadb(struct lsadb_show_data *ld);
+extern struct rte_owner_class ospf_rte_owner_class;
+
/* iface.c */
void ospf_iface_chstate(struct ospf_iface *ifa, u8 state);
void ospf_iface_sm(struct ospf_iface *ifa, int event);
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index faee49dc..3e208023 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 */
@@ -2053,36 +2053,61 @@ again1:
if (nf->n.type) /* Add the route */
{
rta a0 = {
- .src = p->p.main_source,
.source = nf->n.type,
.scope = SCOPE_UNIVERSE,
.dest = RTD_UNICAST,
.nh = *(nf->n.nhs),
+ .pref = p->p.main_channel->preference,
};
if (reload || ort_changed(nf, &a0))
{
- rta *a = rta_lookup(&a0);
- rte *e = rte_get_temp(a);
+ 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_free(nf->old_rta);
+ nf->old_rta = rta_lookup(&a0);
+
+ rte e0 = {
+ .attrs = nf->old_rta,
+ .src = p->p.main_source,
+ };
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);
- rte_update(&p->p, nf->fn.addr, e);
+
+ rte_update(p->p.main_channel, nf->fn.addr, &e0, p->p.main_source);
}
}
else if (nf->old_rta)
@@ -2091,7 +2116,7 @@ again1:
rta_free(nf->old_rta);
nf->old_rta = NULL;
- rte_update(&p->p, nf->fn.addr, NULL);
+ rte_update(p->p.main_channel, nf->fn.addr, NULL, p->p.main_source);
}
/* Remove unused rt entry, some special entries are persistent */
@@ -2107,7 +2132,6 @@ again1:
}
FIB_ITERATE_END;
-
WALK_LIST(oa, p->area_list)
{
/* Cleanup ASBR hash tables */
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index 52c2a0ce..bb88d20a 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -1300,7 +1300,7 @@ find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa)
}
void
-ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED)
+ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, const net_addr *n, rte *new, const rte *old UNUSED)
{
struct ospf_proto *p = (struct ospf_proto *) P;
struct ospf_area *oa = NULL; /* non-NULL for NSSA-LSA */
@@ -1319,7 +1319,7 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
if (!new)
{
- nf = fib_find(&p->rtf, n->n.addr);
+ nf = fib_find(&p->rtf, n);
if (!nf || !nf->external_rte)
return;
@@ -1346,14 +1346,14 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
if (m1 > LSINFINITY)
{
log(L_WARN "%s: Invalid ospf_metric1 value %u for route %N",
- p->p.name, m1, n->n.addr);
+ p->p.name, m1, n);
m1 = LSINFINITY;
}
if (m2 > LSINFINITY)
{
log(L_WARN "%s: Invalid ospf_metric2 value %u for route %N",
- p->p.name, m2, n->n.addr);
+ p->p.name, m2, n);
m2 = LSINFINITY;
}
@@ -1377,12 +1377,12 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
if (ipa_zero(fwd))
{
log(L_ERR "%s: Cannot find forwarding address for NSSA-LSA %N",
- p->p.name, n->n.addr);
+ p->p.name, n);
return;
}
}
- nf = fib_get(&p->rtf, n->n.addr);
+ nf = fib_get(&p->rtf, n);
ospf_originate_ext_lsa(p, oa, nf, LSA_M_EXPORT, metric, ebit, fwd, tag, 1, p->vpn_pe);
nf->external_rte = 1;
}
diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h
index 535d1f1b..c36d0b50 100644
--- a/proto/ospf/topology.h
+++ b/proto/ospf/topology.h
@@ -200,7 +200,7 @@ void ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, u32 d
void ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode, u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit, int dn);
void ospf_originate_gr_lsa(struct ospf_proto *p, struct ospf_iface *ifa);
-void ospf_rt_notify(struct proto *P, struct channel *ch, net *n, rte *new, rte *old);
+void ospf_rt_notify(struct proto *P, struct channel *ch, const net_addr *n, rte *new, const rte *old);
void ospf_update_topology(struct ospf_proto *p);
struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 domain, u32 lsa, u32 rtr, u32 type);