summaryrefslogtreecommitdiff
path: root/proto/ospf/hello.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/ospf/hello.c')
-rw-r--r--proto/ospf/hello.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c
index c7d20273..45b6b613 100644
--- a/proto/ospf/hello.c
+++ b/proto/ospf/hello.c
@@ -24,16 +24,36 @@ ospf_hello_receive(struct ospf_hello_packet *ps,
mask = ps->netmask;
ipa_ntoh(mask);
- if (((ifa->type != OSPF_IT_VLINK) && (ifa->type != OSPF_IT_PTP)) &&
- ((unsigned) ipa_mklen(mask) != ifa->iface->addr->pxlen))
- {
- log(L_ERR "%s%I%sbad netmask %I.", beg, faddr, rec, mask);
- return;
- }
+ if (ifa->type != OSPF_IT_VLINK)
+ {
+ char *msg = L_WARN "Received HELLO packet %s (%I) is inconsistent "
+ "with the primary address of interface %s.";
+
+ if ((ifa->type != OSPF_IT_PTP) &&
+ !ipa_equal(mask, ipa_mkmask(ifa->iface->addr->pxlen)))
+ {
+ if (!n) log(msg, "netmask", mask, ifa->iface->name);
+ return;
+ }
+
+ /* This check is not specified in RFC 2328, but it is needed
+ * to handle the case when there is more IP networks on one
+ * physical network (which is not handled in RFC 2328).
+ * We allow OSPF on primary IP address only and ignore HELLO packets
+ * with secondary addresses (which are sent for example by Quagga.
+ */
+ if ((ifa->iface->addr->flags & IA_UNNUMBERED) ?
+ !ipa_equal(faddr, ifa->iface->addr->opposite) :
+ !ipa_equal(ipa_and(faddr,mask), ifa->iface->addr->prefix))
+ {
+ if (!n) log(msg, "address", faddr, ifa->iface->name);
+ return;
+ }
+ }
if (ntohs(ps->helloint) != ifa->helloint)
{
- log(L_WARN "%s%I%shello interval mismatch (%d).", beg, faddr, rec,
+ log(L_ERR "%s%I%shello interval mismatch (%d).", beg, faddr, rec,
ntohs(ps->helloint));
return;
}
@@ -205,7 +225,8 @@ ospf_hello_send(timer * timer, int poll, struct ospf_neighbor *dirn)
pkt->netmask = ipa_mkmask(ifa->iface->addr->pxlen);
ipa_hton(pkt->netmask);
- if (ifa->type == OSPF_IT_VLINK) pkt->netmask = IPA_NONE;
+ if ((ifa->type == OSPF_IT_VLINK) || (ifa->type == OSPF_IT_PTP))
+ pkt->netmask = IPA_NONE;
pkt->helloint = ntohs(ifa->helloint);
pkt->options = ifa->oa->opt.byte;
pkt->priority = ifa->priority;