* 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
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev