* 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

Reply via email to