Fixes OSPFv3 route generation for local stub networks.
This commit is contained in:
parent
e7b09e4ab9
commit
e60d55becd
1 changed files with 61 additions and 45 deletions
106
proto/ospf/rt.c
106
proto/ospf/rt.c
|
@ -146,6 +146,46 @@ ri_install(struct proto_ospf *po, ip_addr prefix, int pxlen, int dest,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OSPFv2
|
||||||
|
|
||||||
|
static struct ospf_iface *
|
||||||
|
find_stub_src(struct ospf_area *oa, ip_addr px, int pxlen)
|
||||||
|
{
|
||||||
|
struct ospf_iface *iff;
|
||||||
|
struct ifa *addr;
|
||||||
|
|
||||||
|
WALK_LIST(iff, oa->po->iface_list)
|
||||||
|
if ((iff->type != OSPF_IT_VLINK) &&
|
||||||
|
(iff->oa == oa) &&
|
||||||
|
ipa_equal(iff->addr->px, px) &&
|
||||||
|
(iff->addr->pxlen == pxlen))
|
||||||
|
return iff;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* OSPFv3 */
|
||||||
|
|
||||||
|
static struct ospf_iface *
|
||||||
|
find_stub_src(struct ospf_area *oa, ip_addr px, int pxlen)
|
||||||
|
{
|
||||||
|
struct ospf_iface *iff;
|
||||||
|
struct ifa *a;
|
||||||
|
|
||||||
|
WALK_LIST(iff, oa->po->iface_list)
|
||||||
|
if ((iff->type != OSPF_IT_VLINK) &&
|
||||||
|
(iff->oa == oa))
|
||||||
|
WALK_LIST(a, iff->iface->addrs)
|
||||||
|
if (ipa_equal(a->prefix, px) &&
|
||||||
|
(a->pxlen == pxlen) &&
|
||||||
|
!(a->flags & IA_SECONDARY))
|
||||||
|
return iff;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_network(struct ospf_area *oa, ip_addr px, int pxlen, int metric, struct top_hash_entry *en)
|
add_network(struct ospf_area *oa, ip_addr px, int pxlen, int metric, struct top_hash_entry *en)
|
||||||
{
|
{
|
||||||
|
@ -161,7 +201,21 @@ add_network(struct ospf_area *oa, ip_addr px, int pxlen, int metric, struct top_
|
||||||
nf.ifa = en->nhi;
|
nf.ifa = en->nhi;
|
||||||
nf.rid = en->lsa.rt;
|
nf.rid = en->lsa.rt;
|
||||||
|
|
||||||
/* FIXME check nf.ifa on stubs */
|
if (en == oa->rt)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nf.ifa = find_stub_src(oa, px, pxlen);
|
||||||
|
|
||||||
|
if (!nf.ifa)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ri_install(oa->po, px, pxlen, ORT_NET, &nf, NULL);
|
ri_install(oa->po, px, pxlen, ORT_NET, &nf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,45 +297,10 @@ ospf_rt_spfa_rtlinks(struct ospf_area *oa, struct top_hash_entry *act, struct to
|
||||||
{
|
{
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
case LSART_STUB:
|
case LSART_STUB:
|
||||||
/*
|
/* This violates RFC 2328! But it is mostly harmless. */
|
||||||
* This violates rfc2328! But it is mostly harmless.
|
add_network(oa, ipa_from_u32(rtl->id),
|
||||||
*/
|
ipa_mklen(ipa_from_u32(rtl->data)),
|
||||||
DBG("\n");
|
act->dist + rtl->metric, act);
|
||||||
|
|
||||||
orta nf;
|
|
||||||
nf.type = RTS_OSPF;
|
|
||||||
nf.options = 0;
|
|
||||||
nf.metric1 = act->dist + rtl->metric;
|
|
||||||
nf.metric2 = LSINFINITY;
|
|
||||||
nf.tag = 0;
|
|
||||||
nf.oa = oa;
|
|
||||||
nf.ar = act;
|
|
||||||
nf.nh = act->nh;
|
|
||||||
nf.ifa = act->nhi;
|
|
||||||
nf.rid = act->lsa.rt;
|
|
||||||
|
|
||||||
if (act == oa->rt)
|
|
||||||
{
|
|
||||||
struct ospf_iface *iff;
|
|
||||||
|
|
||||||
WALK_LIST(iff, po->iface_list) /* Try to find corresponding interface */
|
|
||||||
{
|
|
||||||
// FIXME this is broken
|
|
||||||
if (iff->iface && (iff->type != OSPF_IT_VLINK) &&
|
|
||||||
(rtl->id == (ipa_to_u32(ipa_mkmask(iff->addr->pxlen))
|
|
||||||
& ipa_to_u32(iff->addr->prefix)))) /* No VLINK and IP must match */
|
|
||||||
{
|
|
||||||
nf.ifa = iff;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nf.ifa)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ri_install(po, ipa_from_u32(rtl->id),
|
|
||||||
ipa_mklen(ipa_from_u32(rtl->data)), ORT_NET, &nf, NULL);
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -292,21 +311,18 @@ ospf_rt_spfa_rtlinks(struct ospf_area *oa, struct top_hash_entry *act, struct to
|
||||||
#else /* OSPFv3 */
|
#else /* OSPFv3 */
|
||||||
tmp = ospf_hash_find(po->gr, oa->areaid, rtl->nif, rtl->id, LSA_T_NET);
|
tmp = ospf_hash_find(po->gr, oa->areaid, rtl->nif, rtl->id, LSA_T_NET);
|
||||||
#endif
|
#endif
|
||||||
if (tmp == NULL)
|
|
||||||
DBG("Not found!\n");
|
|
||||||
else
|
|
||||||
DBG("Found. :-)\n");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LSART_VLNK:
|
case LSART_VLNK:
|
||||||
case LSART_PTP:
|
case LSART_PTP:
|
||||||
tmp = ospf_hash_find_rt(po->gr, oa->areaid, rtl->id);
|
tmp = ospf_hash_find_rt(po->gr, oa->areaid, rtl->id);
|
||||||
DBG("PTP found.\n");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log("Unknown link type in router lsa. (rid = %R)", act->lsa.id);
|
log("Unknown link type in router lsa. (rid = %R)", act->lsa.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp)
|
if (tmp)
|
||||||
DBG("Going to add cand, Mydist: %u, Req: %u\n",
|
DBG("Going to add cand, Mydist: %u, Req: %u\n",
|
||||||
tmp->dist, act->dist + rtl->metric);
|
tmp->dist, act->dist + rtl->metric);
|
||||||
|
|
Loading…
Reference in a new issue