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 3f09afba..b16d46a9 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -135,6 +135,7 @@ CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL) %type opttext %type lsadb_args +%type nbma_eligible CF_GRAMMAR @@ -295,7 +296,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 ; } | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT ; } @@ -327,33 +328,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 290a8634..39084cef 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -574,8 +574,22 @@ 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 */ + +#ifdef OSPFv2 + if (!ipa_in_net(nb->ip, addr->prefix, addr->pxlen)) + continue; +#else + if (!ipa_has_link_scope(nb->ip)) + log(L_WARN "In OSPFv3, configured neighbor address (%I) should be link-local", nb->ip); +#endif + + add_nbma_node(ifa, nb, 0); + } ifa->state = OSPF_IS_DOWN; add_tail(&oa->po->iface_list, NODE ifa); @@ -771,8 +785,14 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new) /* NBMA LIST - add new */ WALK_LIST(nb, new->nbma_list) { + /* See related note in ospf_iface_new() */ +#ifdef OSPFv2 if (!ipa_in_net(nb->ip, ifa->addr->prefix, ifa->addr->pxlen)) continue; +#else + if (!ipa_has_link_scope(nb->ip)) + log(L_WARN "In OSPFv3, configured neighbor address (%I) should be link-local", nb->ip); +#endif if (! find_nbma_node(ifa, nb->ip)) {