* The current stub-router support in Quagga ospfd took the "[max-metric links] should not be used for transit traffic" part of RFC3137 seriously, as that strict no-transit behavoiur is useful (and what the implementor was after). However, it seems that wording was not intended to change any standards specified behaviour.
Quagga as a result has different behaviour to other implementations in its SPF when it encounters 0xffff metric links. This can lead to routing loops in mixed environments. This commit: - Makes the SPF behaviour configurable with a "compatible max-metric (infinite|follow)" command. The state of this setting is explicitly written out, if the ospfd config is written out. - Allows the administrator to specify a "transit" flag to the max-metric command: "max-metric router-lsa transit" to explicitly specify the RFC2328/RFC3187 "discourage, but transit is still fine" behaviour the administator desires, and for the stub-router to try signal to other routers. If this "transit" flag is set, then the router-LSA links are advertised with 0xfffe cost when stub-router is enabled, which should work universally. Note, this is separate from the 'max-metric router-lsa ...' command to enable stub-router advertisement. - Additionally, sets the "Host" option bit in the Router-LSA if the "transit" flag is not specified to the stub-router command. This should allow a Quagga stub-router, at least, to signal its intent clearly: - To RFC2328 routers and older Quagga routers, when it /may/ still be used for transit. - To all routers recognising the H-bit and to older Quagga routers, when it /should not/ be used for transit. If and when the H-bit is widely recognised, and has been deployed in Quagga for long enough, we may be able to change the SPF behaviour default to the standards behaviour of "follow". * libospf.h: Add OSPF_OUTPUT_COST_DISCOURAGE for the 0xfffe cost. * ospf_dump.c: Add the H bit. * ospf_lsa.c: (ospf_link_cost) The Host-bit configuration controls whether we use infinite/0xffff or discourage/0xfffe cost for links for stub-routers. (ospf_router_lsa_new) Set H-bit when configured and stub-routed. * ospf_spf.c: (ospf_spf_next) Recognise the H-bit. Make the 0xffff link behaviour admin configurable. * ospf_vty.c: (show_ip_ospf) display info on the new flags. (ospf_compatible_max_metric_cmd) Set the SPF compatibility behaviour for maximum metric links. (ospf_max_metric_router_lsa_transit_cmd) Configure whether to advertise transit capability or not, as/when stub-router support is in effect. (config_write_stub_router) write the 2 new flags out. (ospf_vty_init) install commands for new flags. * ospfd.c: H-bit advertisement is configured by default as the existing behaviour. * ospfd.h: Add H-bit option define. Add ospf instance config flags for the SPF max-metric link behaviour, and h-bit/no-transit. * ospfd.texi: Update the docs with the new commands. --- doc/ospfd.texi | 137 ++++++++++++++++++++++++++++++++++++++++++------ lib/libospf.h | 2 + ospfd/ospf_dump.c | 3 +- ospfd/ospf_lsa.c | 12 ++++- ospfd/ospf_spf.c | 73 ++++++++++++++++++++++++-- ospfd/ospf_vty.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++------ ospfd/ospfd.c | 2 + ospfd/ospfd.h | 3 ++ 8 files changed, 348 insertions(+), 37 deletions(-) diff --git a/doc/ospfd.texi b/doc/ospfd.texi index 86cabe4..b87cbce 100644 --- a/doc/ospfd.texi +++ b/doc/ospfd.texi @@ -129,6 +129,7 @@ advertise non-OSPF links into stub areas. @deffn {OSPF Command} {timers throttle spf @var{delay} @var{initial-holdtime} @var{max-holdtime}} {} @deffnx {OSPF Command} {no timers throttle spf} {} +@anchor{OSPF timers throttle spf} This command sets the initial @var{delay}, the @var{initial-holdtime} and the @var{maximum-holdtime} between when SPF is calculated and the event which triggered the calculation. The times are specified in @@ -172,23 +173,25 @@ releases. @deffn {OSPF Command} {max-metric router-lsa [on-startup|on-shutdown] <5-86400>} {} @deffnx {OSPF Command} {max-metric router-lsa administrative} {} @deffnx {OSPF Command} {no max-metric router-lsa [on-startup|on-shutdown|administrative]} {} -This enables @cite{RFC3137, OSPF Stub Router Advertisement} support, -where the OSPF process describes its transit links in its router-LSA as -having infinite distance so that other routers will avoid calculating -transit paths through the router while still being able to reach -networks through the router. +@anchor{OSPF stub-router} +@anchor{max-metric router-lsa} -This support may be enabled administratively (and indefinitely) or -conditionally. Conditional enabling of max-metric router-lsas can be -for a period of seconds after startup and/or for a period of seconds -prior to shutdown. +This enables @cite{RFC6987, OSPF Stub Router Advertisement} support, where +the OSPF process describes its transit links in its router-LSA as having +maximum distance so that other routers are discouraged from calculating +transit paths through the router, while still being able to reach stub +addresses of the router, and any attached stub networks. + +This support may be enabled administratively (and indefinitely) with the +@var{administrative} flag. It may alternatively be enabled only for a +specified number of seconds after startup and/or before shutdown, with +@var{on-startup} and @var{on-shutdown}. Enabling this for a period after startup allows OSPF to converge fully -first without affecting any existing routes used by other routers, -while still allowing any connected stub links and/or redistributed -routes to be reachable. Enabling this for a period of time in advance -of shutdown allows the router to gracefully excuse itself from the OSPF -domain. +first, minimising the impact on existing routes used by other routers, +while still allowing any connected stub links and/or redistributed routes to +be reachable. Enabling this for a period of time in advance of shutdown +allows the router to gracefully excuse itself from the OSPF domain. Enabling this feature administratively allows for administrative intervention for whatever reason, for an indefinite period of time. @@ -199,7 +202,111 @@ until manually deconfigured. Configured state of this feature as well as current status, such as the number of second remaining till on-startup or on-shutdown ends, can be -viewed with the @ref{show ip ospf} command. +viewed with the @command{show ip ospf} command, @xref{show ip ospf}. +@end deffn + +@deffn {OSPF Command} {compatible max-metric (infinite|follow)} {} +@deffnx {OSPF Command} {no compatible max-metric} {} + +This flag controls the behaviour of SPF, and how it treats links in +Router-LSAs with the maximum possible metric value. It toggles between the +@cite{RFC2328} specified behaviour, and a Quagga variation. + +When this flag is set to @var{follow}, then the standard RFC2328 behaviour +applies. The SPF calculation will take links with the maximum value metric +of 0xffff into consideration when calculating transit paths out of remote +routers. + +When this flag is set to @var{infinite}, then Quagga deviates from RFC2328. +The SPF transit tree calculation will treat link the 0xffff maximum metric +as an infinite cost. Such links will not be considered for the transit +tree. This only affects whether links @emph{out} of a remote router will be +used for transit - it does not affect the reachability to the router itself, +or to its stub addresses and networks. The @var{infinite} behaviour allows +routers to advertise links as @emph{strictly} non-transit or merely as +discouraged, but available for transit. + +Newer Quagga implementations use and recognise the "Host" option in the +router-LSA. @xref{max-metric router-lsa} and the @var{transit} flag for to +have control whether the H-bit is advertised. + +In networks with routers with mixed behaviour, if links are advertised with +the 0xffff maximum metric (e.g., through the @ref{OSPF stub-router} +functionality) then routing loops may potentially occur. + +In networks where all routers recognise the "Host" option, then it is +recommended to configure the RFC @var{follow} behaviour. + +In other networks, the appropriate behaviour to configure depends on whether +the administrator prefers stub-routers to be strictly not available for +transit or not, on whether the network is mixed, and the consequences of +routing loops. + +The default behaviour is @var{infinite}, for compatibility with previous +Quagga releases. In older Quagga releases this behaviour is not +configurable. The default may change from @var{infinite} to @var{follow} in +a future release, particularly if the "Host" router-LSA option gains +widespread support. + +@end deffn + +@deffn {OSPF Command} {max-metric router-lsa transit} {} +@deffnx {OSPF Command} {no max-metric router-lsa transit} {} + +This flag affects what is advertised when the router is in stub-router mode +(see @ref{OSPF stub-router}). I.e., during the time when stub-router is +enabled administratively, or during the period after startup and/or before +shutdown where enabled to be active. This flag affects whether the router +advertises that it is strictly not available for transit traffic going +through it; or whether such through going, transit traffic is discouraged +but still acceptable. + +The local stub addresses of the router (i.e. loopback, PtP and PtMP +addresses) as well as stub broadcast networks (i.e. without any OSPF +adjacencies) attached to the router should remain reachable regardless of +the setting of this flag, whether the router is advertising itself as a +stub-router or not. + +When this flag is set, then when the stub-router mode is active, the router +will try advertise to other routers that transit traffic through this router +is discouraged, but still allowed. With this flag, the stub-router will: + +@itemize @bullet +@item +Advertise its transit links with high-cost (0xfffe) but not maximum cost, to +ensure other routers can include these links in their SPF calculations. + +@item +Leave the "Host" option in the advertised router-LSA @emph{unset} to +indicate the stub-router's links are still available for transit. +@end itemize + +When this flag is not set, the stub-router will try advertise to other +routers that links are strictly not available for transit. With this flag +unset, the stub-router will: + +@itemize @bullet + +@item +Advertise its transit links with the maximum possible metric, 0xffff, +which some implementations (i.e., older Quagga and Quagga with +@command{compatible max-metric infinite} set) will then not use to calculate +transit paths through. + +@item +Set the "Host" option in its Router-LSA, which will cause all +implementations that support this option to not calculate transit paths +through the local router. +@end itemize + +See @cite{draft-ietf-ospf-ospfv2-hbit} for details on the OSPFv2 "Host" +option. + +Note that this command does not make the router go into stub-router mode. +To enable stub-router mode, see the @command{max-metric router-lsa +(administrative|on-shutdown|on-startup)} command, @ref{max-metric +router-lsa}. + @end deffn @deffn {OSPF Command} {auto-cost reference-bandwidth <1-4294967>} {} diff --git a/lib/libospf.h b/lib/libospf.h index 9265ca5..5890e03 100644 --- a/lib/libospf.h +++ b/lib/libospf.h @@ -63,6 +63,8 @@ /* OSPF interface default values. */ #define OSPF_OUTPUT_COST_DEFAULT 10 #define OSPF_OUTPUT_COST_INFINITE UINT16_MAX +#define OSPF_OUTPUT_COST_MAX OSPF_OUTPUT_COST_INFINITE +#define OSPF_OUTPUT_COST_DISCOURAGE 0xfffe #define OSPF_ROUTER_DEAD_INTERVAL_DEFAULT 40 #define OSPF_ROUTER_DEAD_INTERVAL_MINIMAL 1 #define OSPF_HELLO_INTERVAL_DEFAULT 10 diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index fb43210..03e208c 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -328,7 +328,8 @@ ospf_options_dump (u_char options) { static char buf[OSPF_OPTION_STR_MAXLEN]; - snprintf (buf, OSPF_OPTION_STR_MAXLEN, "*|%s|%s|%s|%s|%s|%s|*", + snprintf (buf, OSPF_OPTION_STR_MAXLEN, "%s|%s|%s|%s|%s|%s|%s|*", + (options & OSPF_OPTION_H) ? "H" : "-", (options & OSPF_OPTION_O) ? "O" : "-", (options & OSPF_OPTION_DC) ? "DC" : "-", (options & OSPF_OPTION_EA) ? "EA" : "-", diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 634bc43..79ad446 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -488,7 +488,8 @@ ospf_link_cost (struct ospf_interface *oi) if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) return oi->output_cost; else - return OSPF_OUTPUT_COST_INFINITE; + return CHECK_FLAG(oi->area->ospf->config, OSPF_STUB_ROUTER_NO_TRANSIT) + ? OSPF_OUTPUT_COST_INFINITE : OSPF_OUTPUT_COST_DISCOURAGE; } /* Set a link information. */ @@ -836,7 +837,14 @@ ospf_router_lsa_new (struct ospf_area *area) /* Create a stream for LSA. */ s = stream_new (OSPF_MAX_LSA_SIZE); /* Set LSA common header fields. */ - lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area), + lsa_header_set (s, + LSA_OPTIONS_GET (area) + | LSA_OPTIONS_NSSA_GET (area) + /* H-bit, specific to router-LSA. */ + | ((CHECK_FLAG (area->stub_router_state, + OSPF_AREA_IS_STUB_ROUTED) + && CHECK_FLAG (ospf->config, OSPF_STUB_ROUTER_NO_TRANSIT)) + ? OSPF_OPTION_H : 0), OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id); /* Set router-LSA body fields. */ diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 58a3992..6ae562c 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -812,6 +812,26 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area, v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", inet_ntoa(v->lsa->id)); + /* draft-ietf-ospf-ospfv2-hbit-00: + * + * "If this is a router-LSA, and the H-bit of the router-LSA is set, and + * vertex V is not the root, then the router should not be used for + * transit and step (3) should be executed immediately. + */ + if ((v != area->spf) + && CHECK_FLAG(v->lsa->options, OSPF_OPTION_H)) + { + if (v->type != OSPF_VERTEX_ROUTER) + zlog_warn ("%s: %s has H-bit set, but is not a Router-LSA!", + __func__, inet_ntoa(v->lsa->id)); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug ("%s: %s has H-bit set," + " not considering for SPF transit tree", + __func__, inet_ntoa(v->lsa->id)); + return; + } + p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4; lim = ((u_char *) v->lsa) + ntohs (v->lsa->length); @@ -837,11 +857,56 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area, if ((type = l->m[0].type) == LSA_LINK_TYPE_STUB) continue; - /* Infinite distance links shouldn't be followed, except - * for local links (a stub-routed router still wants to - * calculate tree, so must follow its own links). + /* In concept, non-transit links / links out of a stub-routed node + * shouldn't be followed /out/ of a node - except if the node is + * the root (in which case, we're calculating initial paths and + * not transiting the vertex; a stub-routed router still wants to + * calculate a tree, so SPF with such as the root should follow). + * + * Conformant OSPF doesn't have a way to signal transit status of + * distinct links. There is only a router-global bit (R-bit in + * OSPFv3, and the proposed H-bit in v2 - see above). However, + * many prior Quagga implementations by default treat 0xffff cost + * links as OSPF_OUTPUT_COST_INFINITE and so will not follow such + * links out of a non-root vertex, full stop. (As did original + * OSPF, prior to 1583). + * + * Other implementations treat 0xffff costs as just a very high + * cost, OSPF_OUTPUT_COST_MAX, but will still include them in the + * transit tree. + * + * Note that a cost of 0xfffe or lower works universally to signal + * "use of this link is discouraged, but it is still available to + * transit through". + * + * Mixed environments of the two behaviours can lead to routing + * loops. The balance of preference between risking routing loops + * in mixed environments and being able to entirely avoid transit + * through stub-routers will depend on the administrator. + * + * In some use-cases, the administrator may intend "no transit + * stub-router" to really mean that, even at the risk of loops; + * while in other cases they may prefer the relaxed interpretation + * of "no transit". + * + * Therefore, this behaviour is configurable, via the OSPF + * instance OSPF_MAX_METRIC_LINK_FOLLOW config flag, defaulting to + * the long-standing Quagga behaviour to not follow 0xfff links + * out for now. + * + * Note: this has no effect on stub networks attached to the + * router, such as local loopback and PtP addresses, and broadcast + * networks without any established OSPF adjacencies. These should + * always be reachable, regardless. + * + * RFC3137/6987 apparently was actually meant to be a no-op with + * regard to how OSPF is supposed to behave. Where it said that + * 0xffff links "should not be used for transit traffic", that + * apparently should not have been taken to heart. */ - if ((v != area->spf) && l->m[0].metric >= OSPF_OUTPUT_COST_INFINITE) + if ((v != area->spf) + && !CHECK_FLAG(area->ospf->config, OSPF_MAX_METRIC_LINK_FOLLOW) + && l->m[0].metric >= OSPF_OUTPUT_COST_INFINITE) continue; /* (b) Otherwise, W is a transit vertex (router or transit diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 14ae9a2..4c4f54e 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2836,6 +2836,17 @@ DEFUN (show_ip_ospf, CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE) ? "enabled" : "disabled", VTY_NEWLINE); + vty_out (vty, " SPF treats max-metric links as:%s %s%s", + VTY_NEWLINE, + CHECK_FLAG(ospf->config, OSPF_MAX_METRIC_LINK_FOLLOW) + ? "low preference but transit capable" + : "infinite cost and not transit capable (RFC deviation)", + VTY_NEWLINE); + vty_out (vty, + " Transit status when stub-router is enabled:" + " %savailable for transit%s", + CHECK_FLAG (ospf->config, OSPF_STUB_ROUTER_NO_TRANSIT) ? "not " : "", + VTY_NEWLINE); /* Show stub-router configuration */ if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED @@ -6385,12 +6396,108 @@ ALIAS (no_ip_ospf_mtu_ignore, "OSPF interface commands\n" "Disable mtu mismatch detection\n") +#define OSPF_CMD_MAX_METRIC_STR \ + "OSPF maximum / infinite-distance metric links\n" +#define OSPF_CMD_MAX_METRIC_RLSA_STR \ + "Advertise this router as a stub router in its router LSA\n" + +DEFUN (ospf_compatible_max_metric, + ospf_compatible_max_metric_cmd, + "compatible max-metric (infinite|follow)", + "OSPF compatibility list\n" + "Behaviour for " OSPF_CMD_MAX_METRIC_STR + "SPF treats max-cost links as infinite and not considered when" + " examining LSAs for transit out of a router (RFC deviation)\n" + "SPF treats max-cost links as lowest-preference links, " + "but still available for transit\n") +{ + struct ospf *ospf = vty->index; + switch (argv[0][0]) + { + case 'i': + UNSET_FLAG (ospf->config, OSPF_MAX_METRIC_LINK_FOLLOW); + break; + case 'f': + SET_FLAG (ospf->config, OSPF_MAX_METRIC_LINK_FOLLOW); + break; + default: + vty_out (vty, "%% Unknown argument %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; +} + +DEFUN (no_ospf_compatible_max_metric, + no_ospf_compatible_max_metric_cmd, + "no compatible max-metric", + NO_STR + "OSPF compatibility list\n" + "Behaviour for " OSPF_CMD_MAX_METRIC_STR) +{ + struct ospf *ospf = vty->index; + UNSET_FLAG (ospf->config, OSPF_MAX_METRIC_LINK_FOLLOW); + return CMD_SUCCESS; +} + +DEFUN (ospf_max_metric_router_lsa_transit, + ospf_max_metric_router_lsa_transit_cmd, + "max-metric router-lsa transit", + OSPF_CMD_MAX_METRIC_STR + OSPF_CMD_MAX_METRIC_RLSA_STR + "Advertise this router may still be transited through," + " when stub-router advertisement is in effect\n") +{ + struct ospf *ospf = vty->index; + struct listnode *ln; + struct ospf_area *area; + + if (!CHECK_FLAG (ospf->config, OSPF_STUB_ROUTER_NO_TRANSIT)) + return CMD_SUCCESS; + UNSET_FLAG (ospf->config, OSPF_STUB_ROUTER_NO_TRANSIT); + + for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) + { + if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) + ospf_router_lsa_update_area (area); + } + + return CMD_SUCCESS; +} + +DEFUN (no_ospf_max_metric_router_lsa_transit, + no_ospf_max_metric_router_lsa_transit_cmd, + "no max-metric router-lsa transit", + NO_STR + OSPF_CMD_MAX_METRIC_STR + OSPF_CMD_MAX_METRIC_RLSA_STR + "Advertise this router may still be transited through," + " when stub-router advertisement is in effect\n") +{ + struct ospf *ospf = vty->index; + struct listnode *ln; + struct ospf_area *area; + + if (CHECK_FLAG (ospf->config, OSPF_STUB_ROUTER_NO_TRANSIT)) + return CMD_SUCCESS; + + SET_FLAG (ospf->config, OSPF_STUB_ROUTER_NO_TRANSIT); + + for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) + { + if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) + ospf_router_lsa_update_area (area); + } + + return CMD_SUCCESS; +} + DEFUN (ospf_max_metric_router_lsa_admin, ospf_max_metric_router_lsa_admin_cmd, "max-metric router-lsa administrative", - "OSPF maximum / infinite-distance metric\n" - "Advertise own Router-LSA with infinite distance (stub router)\n" - "Administratively applied, for an indefinite period\n") + OSPF_CMD_MAX_METRIC_STR + OSPF_CMD_MAX_METRIC_RLSA_STR + "Administratively enable stub-router advertisement," + " for an indefinite period\n") { struct listnode *ln; struct ospf_area *area; @@ -6403,7 +6510,7 @@ DEFUN (ospf_max_metric_router_lsa_admin, if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) ospf_router_lsa_update_area (area); } - + /* Allows for areas configured later to get the property */ ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_SET; @@ -6414,9 +6521,11 @@ DEFUN (no_ospf_max_metric_router_lsa_admin, no_ospf_max_metric_router_lsa_admin_cmd, "no max-metric router-lsa administrative", NO_STR - "OSPF maximum / infinite-distance metric\n" - "Advertise own Router-LSA with infinite distance (stub router)\n" - "Administratively applied, for an indefinite period\n") + OSPF_CMD_MAX_METRIC_STR + OSPF_CMD_MAX_METRIC_RLSA_STR + "Administratively enable stub-router advertisement," + " for an indefinite period\n") + { struct listnode *ln; struct ospf_area *area; @@ -6435,14 +6544,15 @@ DEFUN (no_ospf_max_metric_router_lsa_admin, } } ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET; + return CMD_SUCCESS; } DEFUN (ospf_max_metric_router_lsa_startup, ospf_max_metric_router_lsa_startup_cmd, "max-metric router-lsa on-startup <5-86400>", - "OSPF maximum / infinite-distance metric\n" - "Advertise own Router-LSA with infinite distance (stub router)\n" + OSPF_CMD_MAX_METRIC_STR + OSPF_CMD_MAX_METRIC_RLSA_STR "Automatically advertise stub Router-LSA on startup of OSPF\n" "Time (seconds) to advertise self as stub-router\n") { @@ -6466,8 +6576,8 @@ DEFUN (no_ospf_max_metric_router_lsa_startup, no_ospf_max_metric_router_lsa_startup_cmd, "no max-metric router-lsa on-startup", NO_STR - "OSPF maximum / infinite-distance metric\n" - "Advertise own Router-LSA with infinite distance (stub router)\n" + OSPF_CMD_MAX_METRIC_STR + OSPF_CMD_MAX_METRIC_RLSA_STR "Automatically advertise stub Router-LSA on startup of OSPF\n") { struct listnode *ln; @@ -6494,8 +6604,8 @@ DEFUN (no_ospf_max_metric_router_lsa_startup, DEFUN (ospf_max_metric_router_lsa_shutdown, ospf_max_metric_router_lsa_shutdown_cmd, "max-metric router-lsa on-shutdown <5-86400>", - "OSPF maximum / infinite-distance metric\n" - "Advertise own Router-LSA with infinite distance (stub router)\n" + OSPF_CMD_MAX_METRIC_STR + OSPF_CMD_MAX_METRIC_RLSA_STR "Advertise stub-router prior to full shutdown of OSPF\n" "Time (seconds) to wait till full shutdown\n") { @@ -6519,8 +6629,8 @@ DEFUN (no_ospf_max_metric_router_lsa_shutdown, no_ospf_max_metric_router_lsa_shutdown_cmd, "no max-metric router-lsa on-shutdown", NO_STR - "OSPF maximum / infinite-distance metric\n" - "Advertise own Router-LSA with infinite distance (stub router)\n" + OSPF_CMD_MAX_METRIC_STR + OSPF_CMD_MAX_METRIC_RLSA_STR "Advertise stub-router prior to full shutdown of OSPF\n") { struct ospf *ospf = vty->index; @@ -6536,6 +6646,15 @@ config_write_stub_router (struct vty *vty, struct ospf *ospf) struct listnode *ln; struct ospf_area *area; + vty_out (vty, " compatible max-metric %s%s", + CHECK_FLAG (ospf->config, OSPF_MAX_METRIC_LINK_FOLLOW) + ? "follow" : "infinite", + VTY_NEWLINE); + if (CHECK_FLAG (ospf->config, OSPF_STUB_ROUTER_NO_TRANSIT)) + vty_out (vty, " no max-metric router-lsa transit%s", VTY_NEWLINE); + else + vty_out (vty, " max-metric router-lsa transit%s", VTY_NEWLINE); + if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED) vty_out (vty, " max-metric router-lsa on-startup %u%s", ospf->stub_router_startup_time, VTY_NEWLINE); @@ -7845,6 +7964,10 @@ ospf_vty_init (void) install_element (OSPF_NODE, &no_ospf_refresh_timer_cmd); /* max-metric commands */ + install_element (OSPF_NODE, &ospf_compatible_max_metric_cmd); + install_element (OSPF_NODE, &no_ospf_compatible_max_metric_cmd); + install_element (OSPF_NODE, &ospf_max_metric_router_lsa_transit_cmd); + install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_transit_cmd); install_element (OSPF_NODE, &ospf_max_metric_router_lsa_admin_cmd); install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_admin_cmd); install_element (OSPF_NODE, &ospf_max_metric_router_lsa_startup_cmd); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index c9fcdc3..e8d1117 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -191,6 +191,8 @@ ospf_new (void) new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED; new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED; new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET; + + SET_FLAG (new->config, OSPF_STUB_ROUTER_NO_TRANSIT); /* Distribute parameter init. */ for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 098fc5f..541539d 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -66,6 +66,7 @@ #define OSPF_OPTION_EA 0x10 #define OSPF_OPTION_DC 0x20 #define OSPF_OPTION_O 0x40 +#define OSPF_OPTION_H 0x80 /* OSPF Database Description flags. */ #define OSPF_DD_FLAG_MS 0x01 @@ -130,6 +131,8 @@ struct ospf #define OSPF_OPAQUE_CAPABLE (1 << 2) #define OSPF_LOG_ADJACENCY_CHANGES (1 << 3) #define OSPF_LOG_ADJACENCY_DETAIL (1 << 4) +#define OSPF_MAX_METRIC_LINK_FOLLOW (1 << 5) +#define OSPF_STUB_ROUTER_NO_TRANSIT (1 << 6) /* Opaque-LSA administrative flags. */ u_char opaque; -- 2.5.5 _______________________________________________ Quagga-dev mailing list Quagga-dev@lists.quagga.net https://lists.quagga.net/mailman/listinfo/quagga-dev