From: Ondrej Zajicek Date: Tue, 30 Jul 2013 19:59:36 +0000 (+0200) Subject: Merge commit 'f623ab9875cad2d129f708e95021d3a252930000' into integrated X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f24ea8155b90286a78cc734717253b568edd09e8;p=thirdparty%2Fbird.git Merge commit 'f623ab9875cad2d129f708e95021d3a252930000' into integrated Conflicts: proto/ospf/config.Y proto/ospf/ospf.c proto/ospf/rt.c proto/ospf/topology.c --- f24ea8155b90286a78cc734717253b568edd09e8 diff --cc proto/ospf/config.Y index 2f1ee624e,ba050d852..b43ef8a88 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@@ -148,7 -158,8 +148,8 @@@ ospf_proto ospf_proto_item: proto_item | RFC1583COMPAT bool { OSPF_CFG->rfc1583 = $2; } + | STUB ROUTER bool { OSPF_CFG->stub_router = $3; } - | ECMP bool { OSPF_CFG->ecmp = $2 ? DEFAULT_ECMP_LIMIT : 0; } + | ECMP bool { OSPF_CFG->ecmp = $2 ? OSPF_DEFAULT_ECMP_LIMIT : 0; } | ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); } | TICK expr { OSPF_CFG->tick = $2; if($2<=0) cf_error("Tick must be greater than zero"); } | ospf_area diff --cc proto/ospf/ospf.c index bfd7777d7,2fa872017..43e248051 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@@ -164,7 -164,11 +164,10 @@@ ospf_area_add(struct proto_ospf *po, st if (oa->areaid == 0) po->backbone = oa; - oa->options = ospf_is_v2(po) ? ac->type : (OPT_R | ac->type | OPT_V6); -#ifdef OSPFv2 - oa->options = ac->type; -#else /* OSPFv3 */ - oa->options = ac->type | OPT_V6 | (po->stub_router ? 0 : OPT_R); -#endif ++ if (ospf_is_v2(po)) ++ oa->options = ac->type; ++ else ++ oa->options = ac->type | OPT_V6 | (po->stub_router ? 0 : OPT_R); /* * Set E-bit for NSSA ABR routers. No need to explicitly call @@@ -678,8 -688,11 +682,11 @@@ ospf_area_reconfigure(struct ospf_area oa->ac = nac; // FIXME better area type reconfiguration - oa->options = ospf_is_v2(oa->po) ? nac->type : (OPT_R | nac->type | OPT_V6); -#ifdef OSPFv2 - oa->options = nac->type; -#else /* OSPFv3 */ - oa->options = nac->type | OPT_V6 | (oa->po->stub_router ? 0 : OPT_R); -#endif ++ if (ospf_is_v2(po)) ++ oa->options = nac->type; ++ else ++ oa->options = nac->type | OPT_V6 | (oa->po->stub_router ? 0 : OPT_R); + if (oa_is_nssa(oa) && (oa->po->areano > 1)) oa->po->ebit = 1; diff --cc proto/ospf/ospf.h index 90acc5c65,7608225ff..b5ecc4359 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@@ -70,10 -82,10 +70,11 @@@ struct ospf_confi { struct proto_config c; unsigned tick; + byte ospf2; byte rfc1583; + byte stub_router; byte abr; - int ecmp; + byte ecmp; list area_list; /* list of struct ospf_area_config */ list vlink_list; /* list of struct ospf_iface_patt */ }; @@@ -708,8 -771,8 +709,9 @@@ struct proto_osp list area_list; int areano; /* Number of area I belong to */ struct fib rtf; /* Routing table */ + byte ospf2; /* OSPF v2 or v3 */ byte rfc1583; /* RFC1583 compatibility */ + byte stub_router; /* Do not forward transit traffic */ byte ebit; /* Did I originate any ext lsa? */ byte ecmp; /* Maximal number of nexthops in ECMP route, or 0 */ struct ospf_area *backbone; /* If exists */ diff --cc proto/ospf/rt.c index bf9b2adf8,f509b8965..51fbf66c1 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@@ -288,114 -294,21 +288,118 @@@ add_network(struct ospf_area *oa, ip_ad */ struct ospf_iface *ifa; -#ifdef OSPFv2 - ifa = rt_pos_to_ifa(oa, pos); -#else /* OSPFv3 */ - ifa = px_pos_to_ifa(oa, pos); -#endif + ifa = ospf_is_v2(po) ? rt_pos_to_ifa(oa, pos) : px_pos_to_ifa(oa, pos); + nf.nhs = ifa ? new_nexthop(po, IPA_NONE, ifa->iface, ifa->ecmp_weight) : NULL; + } - nf.nhs = ifa ? new_nexthop(oa->po, IPA_NONE, ifa->iface, ifa->ecmp_weight) : NULL; + ri_install_net(po, px, pxlen, &nf); +} + + + +static inline void +spfa_process_rt(struct ospf_area *oa, struct top_hash_entry *act) +{ + struct proto_ospf *po = oa->po; + struct ospf_lsa_rt *rt = act->lsa_body; + struct ospf_lsa_rt_walk rtl; + struct top_hash_entry *tmp; + ip_addr prefix; + int pxlen, i; + + if (rt->options & OPT_RT_V) + oa->trcap = 1; + + /* + * In OSPFv3, all routers are added to per-area routing + * tables. But we use it just for ASBRs and ABRs. For the + * purpose of the last step in SPF - prefix-LSA processing in + * spfa_process_prefixes(), we use information stored in LSA db. + */ + if (((rt->options & OPT_RT_E) || (rt->options & OPT_RT_B)) + && (act->lsa.rt != po->router_id)) + { + orta nf = { + .type = RTS_OSPF, + .options = rt->options, + .metric1 = act->dist, + .metric2 = LSINFINITY, + .tag = 0, + .rid = act->lsa.rt, + .oa = oa, + .nhs = act->nhs + }; + ri_install_rt(oa, act->lsa.rt, &nf); } - ri_install_net(oa->po, px, pxlen, &nf); ++ /* Errata 2078 to RFC 5340 4.8.1 - skip links from non-routing nodes */ ++ if (ospf_is_v3(po) && (act != oa->rt) && !(rt->options & OPT_R)) ++ break; ++ + /* Now process Rt links */ + for (lsa_walk_rt_init(po, act, &rtl), i = 0; lsa_walk_rt(&rtl); i++) + { + tmp = NULL; + + switch (rtl.type) + { + case LSART_STUB: + + /* Should not happen, LSART_STUB is not defined in OSPFv3 */ + if (ospf_is_v3(po)) + break; + + /* + * RFC 2328 in 16.1. (2a) says to handle stub networks in an + * second phase after the SPF for an area is calculated. We get + * the same result by handing them here because add_network() + * will keep the best (not the first) found route. + */ + prefix = ipa_from_u32(rtl.id & rtl.data); + pxlen = u32_masklen(rtl.data); + add_network(oa, prefix, pxlen, act->dist + rtl.metric, act, i); + break; + + case LSART_NET: + tmp = ospf_hash_find_net(po->gr, oa->areaid, rtl.id, rtl.nif); + break; + + case LSART_VLNK: + case LSART_PTP: + tmp = ospf_hash_find_rt(po->gr, oa->areaid, rtl.id); + break; + } + + add_cand(&oa->cand, tmp, act, act->dist + rtl.metric, oa, i); + } } -#ifdef OSPFv3 -static void -process_prefixes(struct ospf_area *oa) +static inline void +spfa_process_net(struct ospf_area *oa, struct top_hash_entry *act) +{ + struct proto_ospf *po = oa->po; + struct ospf_lsa_net *ln = act->lsa_body; + struct top_hash_entry *tmp; + ip_addr prefix; + int pxlen, i, cnt; + + if (ospf_is_v2(po)) + { + prefix = ipa_from_u32(act->lsa.id & ln->optx); + pxlen = u32_masklen(ln->optx); + add_network(oa, prefix, pxlen, act->dist, act, -1); + } + + cnt = lsa_net_count(&act->lsa); + for (i = 0; i < cnt; i++) + { + tmp = ospf_hash_find_rt(po->gr, oa->areaid, ln->routers[i]); + add_cand(&oa->cand, tmp, act, act->dist, oa, -1); + } +} + +static inline void +spfa_process_prefixes(struct ospf_area *oa) { struct proto_ospf *po = oa->po; // struct proto *p = &po->proto; @@@ -1711,13 -1839,14 +1715,13 @@@ add_cand(list * l, struct top_hash_entr if (en->lsa.age == LSA_MAXAGE) return; -#ifdef OSPFv3 - if (en->lsa.type == LSA_T_RT) - { - struct ospf_lsa_rt *rt = en->lsa_body; - if (!(rt->options & OPT_V6)) - return; - } -#endif + if (ospf_is_v3(po) && (en->lsa_type == LSA_T_RT)) - { - /* In OSPFv3, check V6 and R flags */ - struct ospf_lsa_rt *rt = en->lsa_body; - if (!(rt->options & OPT_V6) || !(rt->options & OPT_R)) - return; - } ++ { ++ /* In OSPFv3, check V6 flag */ ++ struct ospf_lsa_rt *rt = en->lsa_body; ++ if (!(rt->options & OPT_V6)) ++ return; ++ } /* 16.1. (2c) */ if (en->color == INSPF) diff --cc proto/ospf/topology.c index f8637fdc5,5d93c0e98..df7b63c6e --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@@ -249,7 -268,9 +250,7 @@@ prepare_rt2_lsa_body(struct proto_ospf * compatibility with some broken implementations that use * this address as a next-hop. */ - add_rt2_lsa_link(po, LSART_PTP, neigh->rid, ipa_to_u32(ifa->addr->ip), ifa->cost); - ln->data = ipa_to_u32(ifa->addr->ip); - ln->metric = link_cost; - ln->padding = 0; ++ add_rt2_lsa_link(po, LSART_PTP, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost); i++; } break; @@@ -258,7 -279,12 +259,7 @@@ case OSPF_IT_NBMA: if (bcast_net_active(ifa)) { - add_rt2_lsa_link(po, LSART_NET, ipa_to_u32(ifa->drip), ipa_to_u32(ifa->addr->ip), ifa->cost); - ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link)); - ln->type = LSART_NET; - ln->id = ipa_to_u32(ifa->drip); - ln->data = ipa_to_u32(ifa->addr->ip); - ln->metric = link_cost; - ln->padding = 0; ++ add_rt2_lsa_link(po, LSART_NET, ipa_to_u32(ifa->drip), ipa_to_u32(ifa->addr->ip), link_cost); i++; net_lsa = 1; } @@@ -267,7 -293,15 +268,7 @@@ case OSPF_IT_VLINK: neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list); if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff)) - add_rt2_lsa_link(po, LSART_VLNK, neigh->rid, ipa_to_u32(ifa->addr->ip), ifa->cost), i++; - { - ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link)); - ln->type = LSART_VLNK; - ln->id = neigh->rid; - ln->data = ipa_to_u32(ifa->addr->ip); - ln->metric = link_cost; - ln->padding = 0; - i++; - } ++ add_rt2_lsa_link(po, LSART_VLNK, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost), i++; break; default: