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.
This commit is contained in:
Ondrej Zajicek (work) 2019-07-10 18:25:36 +02:00
parent 422a933429
commit 1aec7112f7
5 changed files with 14 additions and 8 deletions

View file

@ -127,7 +127,7 @@ ospf_prepare_dbdes(struct ospf_proto *p, struct ospf_neighbor *n)
{ {
struct ospf_dbdes2_packet *ps = (void *) pkt; struct ospf_dbdes2_packet *ps = (void *) pkt;
ps->iface_mtu = htons(iface_mtu); 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->imms = 0; /* Will be set later */
ps->ddseq = htonl(n->dds); ps->ddseq = htonl(n->dds);
length = sizeof(struct ospf_dbdes2_packet); length = sizeof(struct ospf_dbdes2_packet);
@ -135,7 +135,8 @@ ospf_prepare_dbdes(struct ospf_proto *p, struct ospf_neighbor *n)
else /* OSPFv3 */ else /* OSPFv3 */
{ {
struct ospf_dbdes3_packet *ps = (void *) pkt; 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->iface_mtu = htons(iface_mtu);
ps->padding = 0; ps->padding = 0;
ps->imms = 0; /* Will be set later */ ps->imms = 0; /* Will be set later */

View 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->netmask = htonl(u32_mkmask(ifa->addr->prefix.pxlen));
ps->helloint = ntohs(ifa->helloint); ps->helloint = ntohs(ifa->helloint);
ps->options = ifa->oa->options; ps->options = ifa->oa->options & HELLO2_OPT_MASK;
ps->priority = ifa->priority; ps->priority = ifa->priority;
ps->deadint = htonl(ifa->deadint); ps->deadint = htonl(ifa->deadint);
ps->dr = htonl(ipa_to_u32(ifa->drip)); 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); u32 options = ifa->oa->options | (ifa->autype == OSPF_AUTH_CRYPT ? OPT_AT : 0);
ps->iface_id = htonl(ifa->iface_id); 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->helloint = ntohs(ifa->helloint);
ps->deadint = htons(ifa->deadint); ps->deadint = htons(ifa->deadint);
ps->dr = htonl(ifa->drid); ps->dr = htonl(ifa->drid);

View file

@ -98,8 +98,7 @@ lsa_is_acceptable(u32 type, struct ospf_neighbor *n, struct ospf_proto *p)
{ {
if (ospf_is_v2(p)) if (ospf_is_v2(p))
{ {
if (type == LSA_T_NSSA) /* Do not check NSSA-LSA here, as OPT_N is only in HELLO packets */
return !!(n->options & OPT_N);
if (lsa_is_opaque(type)) if (lsa_is_opaque(type))
return !!(n->options & OPT_O); return !!(n->options & OPT_O);

View file

@ -146,7 +146,7 @@ static inline uint
ospf_opts(struct ospf_proto *p) ospf_opts(struct ospf_proto *p)
{ {
if (ospf_is_v2(p)) if (ospf_is_v2(p))
return 0; return OPT_O;
return ((ospf_is_ip6(p) && !p->af_mc) ? OPT_V6 : 0) | return ((ospf_is_ip6(p) && !p->af_mc) ? OPT_V6 : 0) |
(!p->stub_router ? OPT_R : 0) | (p->af_ext ? OPT_AF : 0); (!p->stub_router ? OPT_R : 0) | (p->af_ext ? OPT_AF : 0);

View file

@ -489,6 +489,12 @@ struct ospf_neighbor
#define OPT_L_V3 0x0200 /* OSPFv3, link-local signaling */ #define OPT_L_V3 0x0200 /* OSPFv3, link-local signaling */
#define OPT_AT 0x0400 /* OSPFv3, authentication trailer */ #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) */ /* Router-LSA VEB flags are are stored together with links (OSPFv2) or options (OSPFv3) */
#define OPT_RT_B (0x01 << 24) #define OPT_RT_B (0x01 << 24)
#define OPT_RT_E (0x02 << 24) #define OPT_RT_E (0x02 << 24)