summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2010-05-26 12:32:30 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2010-05-26 12:32:30 +0200
commite0a62ad0f8be198bf8afb1f6900f138dfe12d4fb (patch)
tree0cdff2e810d0414cef0e8af3b8f19356c809ece8
parent52572e94ec75728c114f47db37aaf220c1af29d6 (diff)
downloadbird-e0a62ad0f8be198bf8afb1f6900f138dfe12d4fb.tar
bird-e0a62ad0f8be198bf8afb1f6900f138dfe12d4fb.zip
Fixes a bug in duplicit configured stubnets.
If there was the same configured stubnet on local and remote router, the remote route always won regardless of its cost.
-rw-r--r--proto/ospf/rt.c18
-rw-r--r--proto/ospf/rt.h4
2 files changed, 15 insertions, 7 deletions
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index 944d0e5..892aa41 100644
--- a/proto/ospf/rt.c
+++ b/proto/ospf/rt.c
@@ -244,14 +244,12 @@ add_network(struct ospf_area *oa, ip_addr px, int pxlen, int metric, struct top_
* Local stub networks does not have proper iface in en->nhi
* (because they all have common top_hash_entry en).
* We have to find iface responsible for that stub network.
- * Some stubnets does not have any iface. Ignore them.
+ * Configured stubnets does not have any iface. They will
+ * be removed in rt_sync().
*/
nf.ifa = find_stub_src(oa, px, pxlen);
nf.nh = IPA_NONE;
-
- if (!nf.ifa)
- return;
}
ri_install_net(oa->po, px, pxlen, &nf);
@@ -813,7 +811,7 @@ decide_sum_lsa(struct ospf_area *oa, ort *nf, int dest)
return 0;
/* 12.4.3 p4 */
- if (nf->n.ifa->oa->areaid == oa->areaid)
+ if (nf->n.ifa && (nf->n.ifa->oa->areaid == oa->areaid))
return 0;
/* 12.4.3 p5 */
@@ -961,7 +959,7 @@ ospf_rt_abr(struct proto_ospf *po)
/* RFC 2328 G.3 - incomplete resolution of virtual next hops */
- if (nf->n.type && (nf->n.ifa->type == OSPF_IT_VLINK))
+ if (nf->n.type && nf->n.ifa && (nf->n.ifa->type == OSPF_IT_VLINK))
reset_ri(&nf->n);
@@ -1153,6 +1151,10 @@ ospf_ext_spf(struct proto_ospf *po)
if ((nf2->n.type != RTS_OSPF) && (nf2->n.type != RTS_OSPF_IA))
continue;
+ /* Next-hop is a part of a configured stubnet */
+ if (!nf2->n.ifa)
+ continue;
+
/* If nh is zero, it is a device route */
nh = ipa_nonzero(nf2->n.nh) ? nf2->n.nh : rt_fwaddr;
nhi = nf2->n.ifa;
@@ -1539,6 +1541,10 @@ again1:
if (po->areano > 1)
check_sum_net_lsa(po, nf);
+ /* Remove configured stubnets */
+ if (!nf->n.ifa)
+ reset_ri(&nf->n);
+
if (reload || memcmp(&nf->n, &nf->o, sizeof(orta)))
{
net *ne = net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
diff --git a/proto/ospf/rt.h b/proto/ospf/rt.h
index 4fc76f4..78156c7 100644
--- a/proto/ospf/rt.h
+++ b/proto/ospf/rt.h
@@ -72,7 +72,9 @@ ort;
* - nodes may be invalid (fn.type == 0), in that case other invariants don't hold
* - n.metric1 may be at most a small multiple of LSINFINITY,
* therefore sums do not overflow
- * - n.oa and n.ifa are always non-NULL
+ * - n.oa is always non-NULL
+ * - n.ifa is always non-NULL with one exception - configured stubnet
+ nodes (in po->rtf). In that case, n.nh is IFA_NONE.
* - oa->rtr does not contain calculating router itself
*/