From 178a197afb77770d8a90765e39065679936a45d1 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Mon, 21 Jul 2014 21:50:56 +0200 Subject: [PATCH] OSPF instance id option and documentation update. --- doc/bird.sgml | 43 +++++++++++++++++++++++++++++-------------- proto/ospf/config.Y | 36 ++++++++++++++++++------------------ proto/ospf/ospf.c | 7 +++++++ proto/ospf/ospf.h | 13 +++++++------ 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. protocol ospf <name> { rfc1583compat <switch>; + instance id <num>; stub router <switch>; tick <num>; ecmp <switch> [limit <num>]; @@ -2375,14 +2376,24 @@ protocol ospf <name> { RFC 1583 . Default value is no. + instance id + 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. + stub router switch 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 . - 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 + for + details. Default value is no. tick num The routing table calculation and clean-up of areas' databases is not @@ -2484,22 +2495,26 @@ protocol ospf <name> { prefix. When option interface pattern [instance Defines that the specified interfaces belong to the area being defined. See 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 + ) and is + supposed to be set per-protocol. For OSPFv3, it is an integral feature. virtual link id [instance 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 + cost num Specifies output cost (metric) of an interface. Default value is 10. @@ -2530,8 +2545,8 @@ protocol ospf <name> { wait num 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*dead count num When the router does not receive any messages from a neighbor in 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 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) */