summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/bird.sgml43
-rw-r--r--proto/ospf/config.Y36
-rw-r--r--proto/ospf/ospf.c7
-rw-r--r--proto/ospf/ospf.h13
4 files changed, 61 insertions, 38 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 04b6a845..46900227 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -2288,6 +2288,7 @@ networks.
<code>
protocol ospf &lt;name&gt; {
rfc1583compat &lt;switch&gt;;
+ instance id &lt;num&gt;;
stub router &lt;switch&gt;;
tick &lt;num&gt;;
ecmp &lt;switch&gt; [limit &lt;num&gt;];
@@ -2375,14 +2376,24 @@ protocol ospf &lt;name&gt; {
RFC 1583 <htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc1583.txt">.
Default value is no.
+ <tag>instance id <m/num/</tag>
+ When multiple OSPF protocol instances are active on the same links, they
+ should use different instance IDs to distinguish their packets. Although
+ it could be done on per-interface basis, it is often preferred to set
+ one instance ID to whole OSPF domain/topology (e.g., when multiple
+ instances are used to represent separate logical topologies on the same
+ physical network). This option specifies the default instance ID for all
+ interfaces of the OSPF instance. Note that this option, if used, must
+ precede interface definitions. Default value is 0.
+
<tag>stub router <M>switch</M></tag>
This option configures the router to be a stub router, i.e., a router
that participates in the OSPF topology but does not allow transit
traffic. In OSPFv2, this is implemented by advertising maximum metric
- for outgoing links, as suggested by
- RFC 3137 <htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc3137.txt">.
- In OSPFv3, the stub router behavior is announced by clearing the R-bit
- in the router LSA. Default value is no.
+ for outgoing links. In OSPFv3, the stub router behavior is announced by
+ clearing the R-bit in the router LSA. See RFC 6987
+ <htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc6987.txt"> for
+ details. Default value is no.
<tag>tick <M>num</M></tag>
The routing table calculation and clean-up of areas' databases is not
@@ -2484,22 +2495,26 @@ protocol ospf &lt;name&gt; {
prefix. When option <cf/summary/ is used, also default stub networks
that are subnetworks of given stub network are suppressed. This might be
used, for example, to aggregate generated stub networks.
-
+
<tag>interface <M>pattern</M> [instance <m/num/]</tag>
Defines that the specified interfaces belong to the area being defined.
See <ref id="dsc-iface" name="interface"> common option for detailed
description. In OSPFv2, extended interface clauses are used, because
- OSPFv2 handles each network prefix as a separate virtual interface. In
- OSPFv3, you can specify instance ID for that interface description, so
- it is possible to have several instances of that interface with
- different options or even in different areas.
+ each network prefix is handled as a separate virtual interface.
+
+ You can specify alternative instance ID for the interface definition,
+ therefore it is possible to have several instances of that interface
+ with different options or even in different areas. For OSPFv2,
+ instance ID support is an extension (RFC 6549
+ <htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc6549.txt">) and is
+ supposed to be set per-protocol. For OSPFv3, it is an integral feature.
<tag>virtual link <M>id</M> [instance <m/num/]</tag>
Virtual link to router with the router id. Virtual link acts as a
point-to-point interface belonging to backbone. The actual area is used
- as transport area. This item cannot be in the backbone. In OSPFv3, you
- could also use several virtual links to one destination with different
- instance IDs.
+ as a transport area. This item cannot be in the backbone. Like with
+ <cf/interface/ option, you could also use several virtual links to one
+ destination with different instance IDs.
<tag>cost <M>num</M></tag>
Specifies output cost (metric) of an interface. Default value is 10.
@@ -2530,8 +2545,8 @@ protocol ospf &lt;name&gt; {
<tag>wait <M>num</M></tag>
After start, router waits for the specified number of seconds between
- starting election and building adjacency. Default value is 40.
-
+ starting election and building adjacency. Default value is 4*<m/hello/.
+
<tag>dead count <M>num</M></tag>
When the router does not receive any messages from a neighbor in
<m/dead count/*<m/hello/ seconds, it will consider the neighbor down.
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y
index 9cbfa9a3..268b9539 100644
--- a/proto/ospf/config.Y
+++ b/proto/ospf/config.Y
@@ -19,7 +19,7 @@ static struct ospf_area_config *this_area;
static struct nbma_node *this_nbma;
static list *this_nets;
static struct area_net_config *this_pref;
-static struct ospf_stubnet_config *this_stubnet;
+static struct ospf_stubnet_config *this_stubnet;
static inline int ospf_cfg_is_v2(void) { return OSPF_CFG->ospf2; }
static inline int ospf_cfg_is_v3(void) { return ! OSPF_CFG->ospf2; }
@@ -32,6 +32,9 @@ ospf_iface_finish(void)
if (ip->deadint == 0)
ip->deadint = ip->deadc * ip->helloint;
+ if (ip->waitint == 0)
+ ip->waitint = ip->deadc * ip->helloint;
+
ip->passwords = get_passwords();
if ((ip->autype == OSPF_AUTH_CRYPT) && (ip->helloint < 5))
@@ -159,6 +162,7 @@ ospf_proto_item:
| ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); }
| MERGE EXTERNAL bool { OSPF_CFG->merge_external = $3; }
| TICK expr { OSPF_CFG->tick = $2; if($2<=0) cf_error("Tick must be greater than zero"); }
+ | INSTANCE ID expr { OSPF_CFG->instance_id = $3; if (($3<0) || ($3>255)) cf_error("Instance ID must be in range 0-255"); }
| ospf_area
;
@@ -213,7 +217,7 @@ ospf_stubnet_start:
add_tail(&this_area->stubnet_list, NODE this_stubnet);
this_stubnet->px = $1;
this_stubnet->cost = COST_D;
- }
+ }
;
ospf_stubnet_opts:
@@ -239,9 +243,9 @@ ospf_vlink_opts:
ospf_vlink_item:
| HELLO expr { OSPF_PATT->helloint = $2 ; if (($2<=0) || ($2>65535)) cf_error("Hello interval must be in range 1-65535"); }
- | RETRANSMIT expr { OSPF_PATT->rxmtint = $2 ; if ($2<=0) cf_error("Retransmit int must be greater than zero"); }
+ | RETRANSMIT expr { OSPF_PATT->rxmtint = $2 ; if ($2<=1) cf_error("Retransmit int must be greater than one"); }
| TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
- | WAIT expr { OSPF_PATT->waitint = $2 ; }
+ | WAIT expr { OSPF_PATT->waitint = $2 ; if ($2<=1) cf_error("Wait interval must be greater than one"); }
| DEAD expr { OSPF_PATT->deadint = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
| DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
| AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE; }
@@ -261,12 +265,10 @@ ospf_vlink_start: VIRTUAL LINK idval
OSPF_PATT->helloint = HELLOINT_D;
OSPF_PATT->rxmtint = RXMTINT_D;
OSPF_PATT->inftransdelay = INFTRANSDELAY_D;
- OSPF_PATT->waitint = WAIT_DMH*HELLOINT_D;
OSPF_PATT->deadc = DEADC_D;
- OSPF_PATT->deadint = 0;
OSPF_PATT->type = OSPF_IT_VLINK;
+ OSPF_PATT->instance_id = OSPF_CFG->instance_id;
init_list(&OSPF_PATT->nbma_list);
- OSPF_PATT->autype = OSPF_AUTH_NONE;
reset_passwords();
}
;
@@ -275,8 +277,8 @@ ospf_iface_item:
COST expr { OSPF_PATT->cost = $2 ; if (($2<=0) || ($2>65535)) cf_error("Cost must be in range 1-65535"); }
| HELLO expr { OSPF_PATT->helloint = $2 ; if (($2<=0) || ($2>65535)) cf_error("Hello interval must be in range 1-65535"); }
| POLL expr { OSPF_PATT->pollint = $2 ; if ($2<=0) cf_error("Poll int must be greater than zero"); }
- | RETRANSMIT expr { OSPF_PATT->rxmtint = $2 ; if ($2<=0) cf_error("Retransmit int must be greater than zero"); }
- | WAIT expr { OSPF_PATT->waitint = $2 ; }
+ | RETRANSMIT expr { OSPF_PATT->rxmtint = $2 ; if ($2<=1) cf_error("Retransmit int must be greater than one"); }
+ | WAIT expr { OSPF_PATT->waitint = $2 ; if ($2<=1) cf_error("Wait interval must be greater than one"); }
| DEAD expr { OSPF_PATT->deadint = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
| DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
| TYPE BROADCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
@@ -300,8 +302,8 @@ ospf_iface_item:
| 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(); }
- | RX BUFFER NORMAL { OSPF_PATT->rx_buffer = 0; }
- | RX BUFFER LARGE { OSPF_PATT->rx_buffer = OSPF_MAX_PKT_SIZE; }
+ | RX BUFFER NORMAL { OSPF_PATT->rx_buffer = 0; }
+ | RX BUFFER LARGE { OSPF_PATT->rx_buffer = OSPF_MAX_PKT_SIZE; }
| RX BUFFER expr { OSPF_PATT->rx_buffer = $3; if (($3 < OSPF_MIN_PKT_SIZE) || ($3 > OSPF_MAX_PKT_SIZE)) cf_error("Buffer size must be in range 256-65535"); }
| TX tos { OSPF_PATT->tx_tos = $2; }
| TX PRIORITY expr { OSPF_PATT->tx_priority = $3; }
@@ -344,7 +346,7 @@ nbma_eligible:
/* empty */ { $$ = 0; }
| ELIGIBLE { $$ = 1; }
;
-
+
nbma_item: ipa nbma_eligible ';'
{
this_nbma = cfg_allocz(sizeof(struct nbma_node));
@@ -353,7 +355,7 @@ nbma_item: ipa nbma_eligible ';'
this_nbma->eligible=$2;
}
;
-
+
ospf_iface_start:
{
this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
@@ -365,12 +367,10 @@ ospf_iface_start:
OSPF_PATT->rxmtint = RXMTINT_D;
OSPF_PATT->inftransdelay = INFTRANSDELAY_D;
OSPF_PATT->priority = PRIORITY_D;
- OSPF_PATT->waitint = WAIT_DMH*HELLOINT_D;
OSPF_PATT->deadc = DEADC_D;
- OSPF_PATT->deadint = 0;
OSPF_PATT->type = OSPF_IT_UNDEF;
+ OSPF_PATT->instance_id = OSPF_CFG->instance_id;
init_list(&OSPF_PATT->nbma_list);
- OSPF_PATT->autype = OSPF_AUTH_NONE;
OSPF_PATT->ptp_netmask = 2; /* not specified */
OSPF_PATT->tx_tos = IP_PREC_INTERNET_CONTROL;
OSPF_PATT->tx_priority = sk_priority_control;
@@ -380,12 +380,12 @@ ospf_iface_start:
ospf_instance_id:
/* empty */
- | INSTANCE expr { OSPF_PATT->instance_id = $2; }
+ | INSTANCE expr { OSPF_PATT->instance_id = $2; if (($2<0) || ($2>255)) cf_error("Instance ID must be in range 0-255"); }
;
ospf_iface_patt_list:
iface_patt_list { if (ospf_cfg_is_v3()) iface_patt_check(); } ospf_instance_id
- ;
+ ;
ospf_iface_opts:
/* empty */
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index d65dba3b..470a8633 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -87,6 +87,13 @@
* we have recalculated and also those we have deleted to the core's routing
* table and the core will take care of the rest. This simplifies the process
* and conserves memory.
+ *
+ * Supported standards:
+ * - RFC 2328 - main OSPFv2 standard
+ * - RFC 5340 - main OSPFv3 standard
+ * - RFC 3101 - OSPFv2 NSSA areas
+ * - RFC 6549 - OSPFv2 multi-instance extensions
+ * - RFC 6987 - OSPF stub router advertisement
*/
#include <stdlib.h>
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index 7e5996f6..f464a3ed 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -103,12 +103,13 @@ struct ospf_config
{
struct proto_config c;
uint tick;
- byte ospf2;
- byte rfc1583;
- byte stub_router;
- byte merge_external;
- byte abr;
- byte asbr;
+ u8 ospf2;
+ u8 rfc1583;
+ u8 stub_router;
+ u8 merge_external;
+ u8 instance_id;
+ u8 abr;
+ u8 asbr;
int ecmp;
list area_list; /* list of area configs (struct ospf_area_config) */
list vlink_list; /* list of configured vlinks (struct ospf_iface_patt) */