summaryrefslogtreecommitdiffstats
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/ospf/hello.c37
-rw-r--r--proto/ospf/packet.c3
2 files changed, 32 insertions, 8 deletions
diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c
index c7d2027..45b6b61 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;
diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c
index 23785fe..783d28e 100644
--- a/proto/ospf/packet.c
+++ b/proto/ospf/packet.c
@@ -323,6 +323,9 @@ ospf_rx_hook(sock * sk, int size)
return 1;
}
+ /* This is deviation from RFC 2328 - neighbours should be identified by
+ * IP address on broadcast and NBMA networks.
+ */
n = find_neigh(ifa, ntohl(((struct ospf_packet *) ps)->routerid));
if(!n && (ps->type != HELLO_P))