summaryrefslogtreecommitdiffstats
path: root/proto/ospf
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2008-10-26 23:43:13 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2008-10-26 23:43:13 +0100
commita97122a3caff40bf35e6019a9b60d5e5ef35a84f (patch)
treeccc09a8b829559f6e3ade60799030a5917f7c7b0 /proto/ospf
parent4c94a6c7e78fb75a9952d891db9d47605f8a26e1 (diff)
downloadbird-a97122a3caff40bf35e6019a9b60d5e5ef35a84f.tar
bird-a97122a3caff40bf35e6019a9b60d5e5ef35a84f.zip
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.
Diffstat (limited to 'proto/ospf')
-rw-r--r--proto/ospf/topology.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index 419a395..1d6b06e 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -20,6 +20,8 @@
#define HASH_LO_STEP 2
#define HASH_LO_MIN 8
+int ptp_unnumbered_stub_lsa = 0;
+
static void *
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;
u16 i = 0;
struct ospf_lsa_rt *rt;
- struct ospf_lsa_rt_link *ln;
+ struct ospf_lsa_rt_link *ln, *ln_after;
struct ospf_neighbor *neigh;
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))
{
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) +
@@ -48,6 +53,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
if ((po->ebit) && (!oa->stub))
rt->veb.bit.e = 1;
ln = (struct ospf_lsa_rt_link *) (rt + 1);
+ ln_after = ln + i;
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))
continue;
+ if (ln == ln_after)
+ die("LSA space overflow");
+
if (ifa->state == OSPF_IS_LOOP)
{
ln->type = 3;
@@ -81,7 +90,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
ln->id = neigh->rid;
ln->metric = ifa->cost;
ln->notos = 0;
- if (ifa->iface->flags && IA_UNNUMBERED)
+ if (ifa->iface->addr->flags & IA_UNNUMBERED)
{
ln->data = ifa->iface->index;
}
@@ -92,19 +101,30 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
}
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->metric = ifa->cost;
+ ln->notos = 0;
+ if (ifa->iface->addr->flags & IA_UNNUMBERED)
{
- ln->type = LSART_STUB;
- ln->id = ln->id = ipa_to_u32(ifa->iface->addr->opposite);
- ln->metric = ifa->cost;
- ln->notos = 0;
+ ln->id = ipa_to_u32(ifa->iface->addr->opposite);
ln->data = 0xffffffff;
}
else
- {
- ln--;
- i--; /* No link added */
- }
+ {
+ ln->data = ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
+ ln->id = ipa_to_u32(ifa->iface->addr->prefix) & ln->data;
+ }
}
break;
case OSPF_IT_BCAST: