summaryrefslogtreecommitdiff
path: root/proto/ospf
diff options
context:
space:
mode:
Diffstat (limited to 'proto/ospf')
-rw-r--r--proto/ospf/config.Y32
-rw-r--r--proto/ospf/hello.c3
-rw-r--r--proto/ospf/iface.c27
-rw-r--r--proto/ospf/ospf.h2
4 files changed, 42 insertions, 22 deletions
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y
index 3f09afba..2cc0b963 100644
--- a/proto/ospf/config.Y
+++ b/proto/ospf/config.Y
@@ -131,10 +131,11 @@ CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL)
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY)
-CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL)
+CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL, NETMASK)
%type <t> opttext
%type <ld> lsadb_args
+%type <i> nbma_eligible
CF_GRAMMAR
@@ -289,13 +290,14 @@ ospf_iface_item:
| TYPE POINTOMULTIPOINT { OSPF_PATT->type = OSPF_IT_PTMP ; }
| TYPE PTMP { OSPF_PATT->type = OSPF_IT_PTMP ; }
| REAL BROADCAST bool { OSPF_PATT->real_bcast = $3; if (OSPF_VERSION != 2) cf_error("Real broadcast option requires OSPFv2"); }
+ | PTP NETMASK bool { OSPF_PATT->ptp_netmask = $3; if (OSPF_VERSION != 2) cf_error("Real netmask option requires OSPFv2"); }
| TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
| PRIORITY expr { OSPF_PATT->priority = $2 ; if (($2<0) || ($2>255)) cf_error("Priority must be in range 0-255"); }
| STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
| 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 +329,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:
{
@@ -372,6 +365,7 @@ ospf_iface_start:
OSPF_PATT->type = OSPF_IT_UNDEF;
init_list(&OSPF_PATT->nbma_list);
OSPF_PATT->autype = OSPF_AUTH_NONE;
+ OSPF_PATT->ptp_netmask = 2; /* not specified */
reset_passwords();
}
;
diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c
index 6ec5c511..d5aa1b95 100644
--- a/proto/ospf/hello.c
+++ b/proto/ospf/hello.c
@@ -253,7 +253,8 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn)
#ifdef OSPFv2
pkt->netmask = ipa_mkmask(ifa->addr->pxlen);
ipa_hton(pkt->netmask);
- if ((ifa->type == OSPF_IT_VLINK) || (ifa->type == OSPF_IT_PTP))
+ if ((ifa->type == OSPF_IT_VLINK) ||
+ ((ifa->type == OSPF_IT_PTP) && !ifa->ptp_netmask))
pkt->netmask = IPA_NONE;
#endif
diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c
index 290a8634..9050f7b1 100644
--- a/proto/ospf/iface.c
+++ b/proto/ospf/iface.c
@@ -537,6 +537,9 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
#ifdef OSPFv2
ifa->autype = ip->autype;
ifa->passwords = ip->passwords;
+ ifa->ptp_netmask = !(addr->flags & IA_PEER);
+ if (ip->ptp_netmask < 2)
+ ifa->ptp_netmask = ip->ptp_netmask;
#endif
#ifdef OSPFv3
@@ -574,8 +577,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 +788,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))
{
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index 7111a13d..d924e657 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -273,6 +273,7 @@ struct ospf_iface
u16 rxbuf; /* Buffer size */
u8 check_link; /* Whether iface link change is used */
u8 ecmp_weight; /* Weight used for ECMP */
+ u8 ptp_netmask; /* Send real netmask for P2P */
};
struct ospf_md5
@@ -810,6 +811,7 @@ struct ospf_iface_patt
u8 check_link;
u8 ecmp_weight;
u8 real_bcast; /* Not really used in OSPFv3 */
+ u8 ptp_netmask; /* bool but 2 for unspecified */
#ifdef OSPFv2
list *passwords;