diff options
-rw-r--r-- | proto/ospf/hello.c | 34 | ||||
-rw-r--r-- | proto/ospf/packet.c | 3 |
2 files changed, 30 insertions, 7 deletions
diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index c7d20273..4a35acde 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; } diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index 23785fe8..783d28ed 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)) |