diff --git a/doc/bird.sgml b/doc/bird.sgml index e83cf0e1..8e5641e0 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -2212,7 +2212,10 @@ protocol ospf <name> { neighbors { A set of neighbors to which Hello messages on NBMA or PtMP networks are to be sent. For NBMA networks, some of them - could be marked as eligible. + could be marked as eligible. In OSPFv3, link-local addresses + should be used, using global ones is possible, but it is + nonstandard and might be problematic. And definitely, + link-local and global addresses should not be mixed. diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 1ba77252..3325a5de 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -120,7 +120,7 @@ CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL) %type opttext %type lsadb_args -%type ospf_proto_key +%type ospf_proto_key nbma_eligible CF_GRAMMAR @@ -286,7 +286,7 @@ ospf_iface_item: | STUB bool { OSPF_PATT->stub = $2 ; } | CHECK LINK bool { OSPF_PATT->check_link = $3; } | ECMP WEIGHT expr { OSPF_PATT->ecmp_weight = $3 - 1; if (($3<1) || ($3>256)) cf_error("ECMP weight must be in range 1-256"); } - | NEIGHBORS '{' ipa_list '}' + | NEIGHBORS '{' nbma_list '}' | AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE; } | AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE; ospf_check_auth(); } | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT; ospf_check_auth(); } @@ -318,33 +318,24 @@ pref_opt: | TAG expr { this_pref->tag = $2; } ; -ipa_list: +nbma_list: /* empty */ - | ipa_list ipa_item + | nbma_list nbma_item ; -ipa_item: - ipa_el - | ipa_ne; +nbma_eligible: + /* empty */ { $$ = 0; } + | ELIGIBLE { $$ = 1; } + ; -ipa_el: ipa ';' +nbma_item: ipa nbma_eligible ';' { this_nbma = cfg_allocz(sizeof(struct nbma_node)); add_tail(&OSPF_PATT->nbma_list, NODE this_nbma); this_nbma->ip=$1; - this_nbma->eligible=0; + this_nbma->eligible=$2; } ; - -ipa_ne: ipa ELIGIBLE ';' - { - this_nbma = cfg_allocz(sizeof(struct nbma_node)); - add_tail(&OSPF_PATT->nbma_list, NODE this_nbma); - this_nbma->ip=$1; - this_nbma->eligible=1; - } -; - ospf_iface_start: { diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index 6025d2d1..8613ec85 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -567,8 +567,20 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i init_list(&ifa->nbma_list); WALK_LIST(nb, ip->nbma_list) - if (ipa_in_net(nb->ip, addr->prefix, addr->pxlen)) - add_nbma_node(ifa, nb, 0); + { + /* In OSPFv3, addr is link-local while configured neighbors could + have global IP (although RFC 5340 C.5 says link-local addresses + should be used). Because OSPFv3 iface is not subnet-specific, + there is no need for ipa_in_net() check */ + + if (ospf_is_v2(po) && !ipa_in_net(nb->ip, addr->prefix, addr->pxlen)) + continue; + + if (ospf_is_v3(po) && !ipa_has_link_scope(nb->ip)) + log(L_WARN "In OSPFv3, configured neighbor address (%I) should be link-local", nb->ip); + + add_nbma_node(ifa, nb, 0); + } ifa->state = OSPF_IS_DOWN; add_tail(&oa->po->iface_list, NODE ifa); @@ -758,9 +770,13 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new) /* NBMA LIST - add new */ WALK_LIST(nb, new->nbma_list) { - if (!ipa_in_net(nb->ip, ifa->addr->prefix, ifa->addr->pxlen)) + /* See related note in ospf_iface_new() */ + if (ospf_is_v2(po) && !ipa_in_net(nb->ip, ifa->addr->prefix, ifa->addr->pxlen)) continue; + if (ospf_is_v3(po) && !ipa_has_link_scope(nb->ip)) + log(L_WARN "In OSPFv3, configured neighbor address (%I) should be link-local", nb->ip); + if (! find_nbma_node(ifa, nb->ip)) { OSPF_TRACE(D_EVENTS, "Adding NBMA neighbor %I on interface %s",