From 36d5d2dd5cee5ddc7293a817656fa4a8d39834d0 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Wed, 10 Jul 2019 18:48:50 +0200 Subject: [PATCH] OSPF: Fix handling of NSSA option flags Per RFC 3101, N-bit signalling NSSA support should be used only in Hello packets, not in DBDES packets. BIRD since 2.0.4 verifies N-bit in neighbor structure, which is learned from DBDES packets, therefore NSSA-LSAs are not propagated to proper implementations of RFC 3101. This patch fixes that. Both removing the check and removing N-bit from DBDES packet. This will fix compatibility issues with proper implementations, but causes compatibility issues with BIRD 2.0.4. --- proto/ospf/dbdes.c | 4 ++-- proto/ospf/hello.c | 4 ++-- proto/ospf/lsalib.c | 3 +-- proto/ospf/ospf.c | 2 +- proto/ospf/ospf.h | 8 +++++++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c index 463ad6de..7564c572 100644 --- a/proto/ospf/dbdes.c +++ b/proto/ospf/dbdes.c @@ -121,7 +121,7 @@ ospf_prepare_dbdes(struct ospf_proto *p, struct ospf_neighbor *n) { struct ospf_dbdes2_packet *ps = (void *) pkt; ps->iface_mtu = htons(iface_mtu); - ps->options = ifa->oa->options | OPT_O; + ps->options = ifa->oa->options & DBDES2_OPT_MASK; ps->imms = 0; /* Will be set later */ ps->ddseq = htonl(n->dds); length = sizeof(struct ospf_dbdes2_packet); @@ -129,7 +129,7 @@ ospf_prepare_dbdes(struct ospf_proto *p, struct ospf_neighbor *n) else /* OSPFv3 */ { struct ospf_dbdes3_packet *ps = (void *) pkt; - ps->options = htonl(ifa->oa->options); + ps->options = htonl(ifa->oa->options & DBDES3_OPT_MASK); ps->iface_mtu = htons(iface_mtu); ps->padding = 0; ps->imms = 0; /* Will be set later */ diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index 90905cde..3e782989 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -74,7 +74,7 @@ ospf_send_hello(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn) ps->netmask = htonl(u32_mkmask(ifa->addr->prefix.pxlen)); ps->helloint = ntohs(ifa->helloint); - ps->options = ifa->oa->options; + ps->options = ifa->oa->options & HELLO2_OPT_MASK; ps->priority = ifa->priority; ps->deadint = htonl(ifa->deadint); ps->dr = htonl(ipa_to_u32(ifa->drip)); @@ -88,7 +88,7 @@ ospf_send_hello(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn) struct ospf_hello3_packet *ps = (void *) pkt; ps->iface_id = htonl(ifa->iface_id); - ps->options = ntohl(ifa->oa->options | (ifa->priority << 24)); + ps->options = ntohl((ifa->oa->options & HELLO3_OPT_MASK) | (ifa->priority << 24)); ps->helloint = ntohs(ifa->helloint); ps->deadint = htons(ifa->deadint); ps->dr = htonl(ifa->drid); diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c index 7767700f..7aae96ba 100644 --- a/proto/ospf/lsalib.c +++ b/proto/ospf/lsalib.c @@ -98,8 +98,7 @@ lsa_is_acceptable(u32 type, struct ospf_neighbor *n, struct ospf_proto *p) { if (ospf_is_v2(p)) { - if (type == LSA_T_NSSA) - return !!(n->options & OPT_N); + /* Do not check NSSA-LSA here, as OPT_N is only in HELLO packets */ if (lsa_is_opaque(type)) return !!(n->options & OPT_O); diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index f1c1b00b..643b5054 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -145,7 +145,7 @@ static inline uint ospf_opts(struct ospf_proto *p) { if (ospf_is_v2(p)) - return 0; + return OPT_O; return ((ospf_is_ip6(p) && !p->af_mc) ? OPT_V6 : 0) | (!p->stub_router ? OPT_R : 0) | (p->af_ext ? OPT_AF : 0); diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 27f3097e..94a90710 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -494,9 +494,15 @@ struct ospf_neighbor #define OPT_R 0x0010 /* OSPFv3, originator is active router */ #define OPT_DC 0x0020 /* Related to demand circuits, not used */ #define OPT_O 0x0040 /* OSPFv2 Opaque LSA (RFC 5250) */ -#define OPT_DN 0x0080 /* OSPFv2 VPN loop prevention (RFC 4576)*/ +#define OPT_DN 0x0080 /* OSPFv2 VPN loop prevention (RFC 4576) */ #define OPT_AF 0x0100 /* OSPFv3 Address Families (RFC 5838) */ +#define HELLO2_OPT_MASK (OPT_E | OPT_N) +#define DBDES2_OPT_MASK (OPT_E | OPT_O) + +#define HELLO3_OPT_MASK (OPT_V6 | OPT_E | OPT_N | OPT_R | OPT_AF ) +#define DBDES3_OPT_MASK (OPT_V6 | OPT_E | OPT_R | OPT_AF ) + /* Router-LSA VEB flags are are stored together with links (OSPFv2) or options (OSPFv3) */ #define OPT_RT_B (0x01 << 24) #define OPT_RT_E (0x02 << 24)