diff --git a/doc/bird.sgml b/doc/bird.sgml index 300a71f3..fab49105 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1940,6 +1940,7 @@ protocol ospf <name> { nonbroadcast|nbma|pointomultipoint|ptmp]; strict nonbroadcast <switch>; real broadcast <switch>; + ptp netmask <switch>; check link <switch>; ecmp weight <num>; authentication [none|simple|cryptographic]; @@ -2183,6 +2184,18 @@ protocol ospf <name> { probably is not interoperable with other OSPF implementations. Default value is no. + ptp netmask + In check link switch If set, a hardware link state (reported by OS) is taken into consideration. When a link disappears (e.g. an ethernet cable is diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 3325a5de..2f1ee624 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -116,7 +116,7 @@ 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 opttext %type lsadb_args @@ -280,6 +280,7 @@ 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_cfg_is_v2()) cf_error("Real broadcast option requires OSPFv2"); } + | PTP NETMASK bool { OSPF_PATT->ptp_netmask = $3; if (!ospf_cfg_is_v2()) 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 ; } @@ -354,6 +355,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 c2518708..8f2e497f 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -267,7 +267,8 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn) ps->netmask = htonl(u32_mkmask(ifa->addr->pxlen)); - 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)) ps->netmask = 0; ps->helloint = ntohs(ifa->helloint); diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index 8613ec85..19f4c585 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -538,6 +538,10 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i ifa->passwords = ip->passwords; ifa->instance_id = ip->instance_id; + ifa->ptp_netmask = !(addr->flags & IA_PEER); + if (ip->ptp_netmask < 2) + ifa->ptp_netmask = ip->ptp_netmask; + ifa->type = ospf_iface_classify(ip->type, addr); /* Check validity of interface type */ diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 146d07f6..1c411a71 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -246,6 +246,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 @@ -749,8 +750,9 @@ struct ospf_iface_patt u8 check_link; u8 ecmp_weight; u8 real_bcast; /* Not really used in OSPFv3 */ - list *passwords; + u8 ptp_netmask; /* bool but 2 for unspecified */ u8 instance_id; + list *passwords; }; int ospf_import_control(struct proto *p, rte **new, ea_list **attrs,