Bugfix in LSA origination for PTP OSPF links.

The code generating LSAs for PTP OSPF links is buggy. The old behavior
is that it generates PTP link if there is a full/ptp neighbor and stub
link if there isn't. According to RFC 2328, the correct behavior is to
generate stub link in both cases (in the first case together with PTP
link).

And because of buggy detection of unnumbered networks, for numbered
networks the code creates stub links with 0.0.0.0/32.
This commit is contained in:
Ondrej Zajicek 2008-10-26 23:43:13 +01:00
parent 4c94a6c7e7
commit a97122a3ca

View file

@ -20,6 +20,8 @@
#define HASH_LO_STEP 2 #define HASH_LO_STEP 2
#define HASH_LO_MIN 8 #define HASH_LO_MIN 8
int ptp_unnumbered_stub_lsa = 0;
static void * static void *
originate_rt_lsa_body(struct ospf_area *oa, u16 * length) originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
{ {
@ -28,7 +30,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
int j = 0, k = 0; int j = 0, k = 0;
u16 i = 0; u16 i = 0;
struct ospf_lsa_rt *rt; struct ospf_lsa_rt *rt;
struct ospf_lsa_rt_link *ln; struct ospf_lsa_rt_link *ln, *ln_after;
struct ospf_neighbor *neigh; struct ospf_neighbor *neigh;
DBG("%s: Originating RT_lsa body for area \"%I\".\n", po->proto.name, DBG("%s: Originating RT_lsa body for area \"%I\".\n", po->proto.name,
@ -39,6 +41,9 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
if ((ifa->oa == oa) && (ifa->state != OSPF_IS_DOWN)) if ((ifa->oa == oa) && (ifa->state != OSPF_IS_DOWN))
{ {
i++; i++;
if ((ifa->type == OSPF_IT_PTP) && (ifa->state == OSPF_IS_PTP) &&
(ptp_unnumbered_stub_lsa || !(ifa->iface->addr->flags & IA_UNNUMBERED)))
i++;
} }
} }
rt = mb_allocz(po->proto.pool, sizeof(struct ospf_lsa_rt) + rt = mb_allocz(po->proto.pool, sizeof(struct ospf_lsa_rt) +
@ -48,6 +53,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
if ((po->ebit) && (!oa->stub)) if ((po->ebit) && (!oa->stub))
rt->veb.bit.e = 1; rt->veb.bit.e = 1;
ln = (struct ospf_lsa_rt_link *) (rt + 1); ln = (struct ospf_lsa_rt_link *) (rt + 1);
ln_after = ln + i;
WALK_LIST(ifa, po->iface_list) WALK_LIST(ifa, po->iface_list)
{ {
@ -61,6 +67,9 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN)) if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
continue; continue;
if (ln == ln_after)
die("LSA space overflow");
if (ifa->state == OSPF_IS_LOOP) if (ifa->state == OSPF_IS_LOOP)
{ {
ln->type = 3; ln->type = 3;
@ -81,7 +90,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
ln->id = neigh->rid; ln->id = neigh->rid;
ln->metric = ifa->cost; ln->metric = ifa->cost;
ln->notos = 0; ln->notos = 0;
if (ifa->iface->flags && IA_UNNUMBERED) if (ifa->iface->addr->flags & IA_UNNUMBERED)
{ {
ln->data = ifa->iface->index; ln->data = ifa->iface->index;
} }
@ -92,18 +101,29 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
} }
else else
{ {
if (ifa->state == OSPF_IS_PTP) ln--;
i--; /* No link added */
}
if ((ifa->state == OSPF_IS_PTP) &&
(ptp_unnumbered_stub_lsa || !(ifa->iface->addr->flags & IA_UNNUMBERED)))
{ {
ln++;
if (ln == ln_after)
die("LSA space overflow");
ln->type = LSART_STUB; ln->type = LSART_STUB;
ln->id = ln->id = ipa_to_u32(ifa->iface->addr->opposite);
ln->metric = ifa->cost; ln->metric = ifa->cost;
ln->notos = 0; ln->notos = 0;
if (ifa->iface->addr->flags & IA_UNNUMBERED)
{
ln->id = ipa_to_u32(ifa->iface->addr->opposite);
ln->data = 0xffffffff; ln->data = 0xffffffff;
} }
else else
{ {
ln--; ln->data = ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
i--; /* No link added */ ln->id = ipa_to_u32(ifa->iface->addr->prefix) & ln->data;
} }
} }
break; break;