I would prefer that we are rfc compliant as per default and then have a
switch to turn it off if needed.

donald

On Tue, Apr 12, 2016 at 7:58 AM, Paul Jakma <paul.ja...@hpe.com> wrote:

> * 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
>
_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to