]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
OSPF: Fix handling of NSSA option flags
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 10 Jul 2019 16:25:36 +0000 (18:25 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 10 Jul 2019 16:25:36 +0000 (18:25 +0200)
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
proto/ospf/hello.c
proto/ospf/lsalib.c
proto/ospf/ospf.c
proto/ospf/ospf.h

index b39595d98bb21e2054bd2d1c40a5c7c0ff21f6cb..5a5f76f8858615045c3304d0b2b83ba185d7f4b4 100644 (file)
@@ -127,7 +127,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);
@@ -135,7 +135,8 @@ 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 | (ifa->autype == OSPF_AUTH_CRYPT ? OPT_AT : 0));
+    u32 options = ifa->oa->options | (ifa->autype == OSPF_AUTH_CRYPT ? OPT_AT : 0);
+    ps->options = htonl(options & DBDES3_OPT_MASK);
     ps->iface_mtu = htons(iface_mtu);
     ps->padding = 0;
     ps->imms = 0;      /* Will be set later */
index 9e427c4f72dd6942def2d7ea0e0ee74521cbce7b..d094f9346309e3102ef1453384cd8935a381cabe 100644 (file)
@@ -81,7 +81,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));
@@ -96,7 +96,7 @@ ospf_send_hello(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn)
     u32 options = ifa->oa->options | (ifa->autype == OSPF_AUTH_CRYPT ? OPT_AT : 0);
 
     ps->iface_id = htonl(ifa->iface_id);
-    ps->options = ntohl(options | (ifa->priority << 24));
+    ps->options = ntohl((options & HELLO3_OPT_MASK) | (ifa->priority << 24));
     ps->helloint = ntohs(ifa->helloint);
     ps->deadint = htons(ifa->deadint);
     ps->dr = htonl(ifa->drid);
index 7767700f8a7ddffdbfd62f79a5853d40776eac20..7aae96ba5a5487618249678592a512cb39444226 100644 (file)
@@ -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);
index abd4cd8415240aa7f289a5ffc9ba14ab167a4c1b..57e578da65fac5a77b886ef726b987931ca1c28b 100644 (file)
@@ -146,7 +146,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);
index 3fd1c363f8b0f2a6e5aced94f417a1f62edc0da7..823b5e539e0ea4deab33a22deba069c5864de457 100644 (file)
@@ -484,11 +484,17 @@ 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 OPT_L_V3       0x0200  /* OSPFv3, link-local signaling */
 #define OPT_AT          0x0400 /* OSPFv3, authentication trailer */
 
+#define HELLO2_OPT_MASK        (OPT_E | OPT_N | OPT_L_V2)
+#define DBDES2_OPT_MASK        (OPT_E         | OPT_L_V2 | OPT_O)
+
+#define HELLO3_OPT_MASK        (OPT_V6 | OPT_E | OPT_N | OPT_R | OPT_AF | OPT_L_V3 | OPT_AT )
+#define DBDES3_OPT_MASK        (OPT_V6 | OPT_E |         OPT_R | OPT_AF | OPT_L_V3 | OPT_AT )
+
 /* 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)