diff options
Diffstat (limited to 'proto/ospf')
-rw-r--r-- | proto/ospf/iface.c | 15 | ||||
-rw-r--r-- | proto/ospf/neighbor.c | 6 | ||||
-rw-r--r-- | proto/ospf/ospf.c | 93 | ||||
-rw-r--r-- | proto/ospf/ospf.h | 2 | ||||
-rw-r--r-- | proto/ospf/rt.c | 62 | ||||
-rw-r--r-- | proto/ospf/topology.c | 12 | ||||
-rw-r--r-- | proto/ospf/topology.h | 2 |
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); |