]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospf6d: add overload support
authorDinesh Dutt <ddutt@cumulusnetworks.com>
Sat, 24 Aug 2013 08:00:37 +0000 (08:00 +0000)
committerDavid Lamparter <equinox@opensourcerouting.org>
Fri, 8 Nov 2013 02:15:43 +0000 (18:15 -0800)
OSPFv3: Support setting/clearing overload bit on router

It is sometimes necessary for a router to gracefully remove itself from
the SPF tree i.e. it cannot act as a transit router. It does this by
setting the overload bit in the router LSA. This patch adds support for
enabling/disabling the overload bit.

Signed-off-by: Dinesh G Dutt <ddutt at cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat at cumulusnetworks.com>
[DL: patch applied with fuzz]
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
ospf6d/ospf6_area.c
ospf6d/ospf6_intra.c
ospf6d/ospf6_intra.h
ospf6d/ospf6_spf.c
ospf6d/ospf6_top.c
ospf6d/ospf6_top.h

index 1e07d8579482cd06bee5498675ff1ab41b103f46..37e5c0045ce4eaa13092063e2c22fc465e8a995b 100644 (file)
@@ -164,9 +164,18 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
   oa->summary_router->scope = oa;
 
   /* set default options */
-  OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
+  if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
+    {
+      OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
+      OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
+    }
+  else
+    {
+      OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
+      OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
+    }
+
   OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
-  OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
 
   oa->ospf6 = o;
   listnode_add_sort (o->area_list, oa);
index c08a6ae640d9e96e869d93e8f60391aee27d5061..025a77104b289675880c78ea727a0a5284a563ef 100644 (file)
@@ -104,6 +104,29 @@ ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
   return 0;
 }
 
+int
+ospf6_router_is_stub_router (struct ospf6_lsa *lsa)
+{
+  struct ospf6_router_lsa *rtr_lsa;
+
+  if (lsa != NULL && OSPF6_LSA_IS_TYPE (ROUTER, lsa))
+    {
+      rtr_lsa = (struct ospf6_router_lsa *)
+       ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
+
+      if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_R))
+       {
+         return (OSPF6_IS_STUB_ROUTER);
+       }
+      else if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_V6))
+       {
+         return (OSPF6_IS_STUB_ROUTER_V6);
+       }
+    }
+
+  return (OSPF6_NOT_STUB_ROUTER);
+}
+
 int
 ospf6_router_lsa_originate (struct thread *thread)
 {
index 3810174ea64c2308c173d8bcba97bb4b73ec7a3f..a25efa12c958c80f15ab068919561555d26ecfcc 100644 (file)
@@ -94,6 +94,13 @@ struct ospf6_router_lsdesc
 #define OSPF6_ROUTER_LSDESC_STUB_NETWORK       3
 #define OSPF6_ROUTER_LSDESC_VIRTUAL_LINK       4
 
+enum stub_router_mode
+  {
+    OSPF6_NOT_STUB_ROUTER,
+    OSPF6_IS_STUB_ROUTER,
+    OSPF6_IS_STUB_ROUTER_V6,
+  };
+
 #define ROUTER_LSDESC_IS_TYPE(t,x)                         \
   ((((struct ospf6_router_lsdesc *)(x))->type ==           \
    OSPF6_ROUTER_LSDESC_ ## t) ? 1 : 0)
@@ -200,6 +207,7 @@ extern char *ospf6_router_lsdesc_lookup (u_char type, u_int32_t interface_id,
 extern char *ospf6_network_lsdesc_lookup (u_int32_t router_id,
                                           struct ospf6_lsa *lsa);
 
+extern int ospf6_router_is_stub_router (struct ospf6_lsa *lsa);
 extern int ospf6_router_lsa_originate (struct thread *);
 extern int ospf6_network_lsa_originate (struct thread *);
 extern int ospf6_link_lsa_originate (struct thread *);
index e4c424dbbb91c27df0a95183170c9d3532b9a41e..845e206c4a4d0c06fc8994357e71b90d367ab68e 100644 (file)
@@ -424,6 +424,11 @@ ospf6_spf_calculation (u_int32_t router_id,
       if (ospf6_spf_install (v, result_table) < 0)
         continue;
 
+      /* Skip overloaded routers */
+      if ((OSPF6_LSA_IS_TYPE (ROUTER, v->lsa) &&
+          ospf6_router_is_stub_router (v->lsa)))
+       continue;
+
       /* For each LS description in the just-added vertex V's LSA */
       size = (VERTEX_IS_TYPE (ROUTER, v) ?
               sizeof (struct ospf6_router_lsdesc) :
index e9fe7a4e945f42656a11993cf809a567f0d6c418..dec7096cf0006dfbdb65d303bd09979dca5c1ca7 100644 (file)
@@ -464,6 +464,101 @@ DEFUN (no_ospf6_interface_area,
   return CMD_SUCCESS;
 }
 
+DEFUN (ospf6_stub_router_admin,
+       ospf6_stub_router_admin_cmd,
+       "stub-router administrative",
+       "Make router a stub router\n"
+       "Advertise inability to be a transit router\n"
+       "Administratively applied, for an indefinite period\n")
+{
+  struct listnode *node;
+  struct ospf6_area *oa;
+
+  if (!CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER))
+    {
+      for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
+       {
+          OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
+          OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
+          OSPF6_ROUTER_LSA_SCHEDULE (oa);
+       }
+      SET_FLAG (ospf6->flag, OSPF6_STUB_ROUTER);
+    }
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ospf6_stub_router_admin,
+       no_ospf6_stub_router_admin_cmd,
+       "no stub-router administrative",
+       NO_STR
+       "Make router a stub router\n"
+       "Advertise ability to be a transit router\n"
+       "Administratively applied, for an indefinite period\n")
+{
+  struct listnode *node;
+  struct ospf6_area *oa;
+
+  if (CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER))
+    {
+      for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
+       {
+          OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
+          OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
+          OSPF6_ROUTER_LSA_SCHEDULE (oa);
+       }
+      UNSET_FLAG (ospf6->flag, OSPF6_STUB_ROUTER);
+    }
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (ospf6_stub_router_startup,
+       ospf6_stub_router_startup_cmd,
+       "stub-router on-startup <5-86400>",
+       "Make router a stub router\n"
+       "Advertise inability to be a transit router\n"
+       "Automatically advertise as stub-router on startup of OSPF6\n"
+       "Time (seconds) to advertise self as stub-router\n")
+{
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ospf6_stub_router_startup,
+       no_ospf6_stub_router_startup_cmd,
+       "no stub-router on-startup",
+       NO_STR
+       "Make router a stub router\n"
+       "Advertise inability to be a transit router\n"
+       "Automatically advertise as stub-router on startup of OSPF6\n"
+       "Time (seconds) to advertise self as stub-router\n")
+{
+  return CMD_SUCCESS;
+}
+
+DEFUN (ospf6_stub_router_shutdown,
+       ospf6_stub_router_shutdown_cmd,
+       "stub-router on-shutdown <5-86400>",
+       "Make router a stub router\n"
+       "Advertise inability to be a transit router\n"
+       "Automatically advertise as stub-router before shutdown\n"
+       "Time (seconds) to advertise self as stub-router\n")
+{
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ospf6_stub_router_shutdown,
+       no_ospf6_stub_router_shutdown_cmd,
+       "no stub-router on-shutdown",
+       NO_STR
+       "Make router a stub router\n"
+       "Advertise inability to be a transit router\n"
+       "Automatically advertise as stub-router before shutdown\n"
+       "Time (seconds) to advertise self as stub-router\n")
+{
+  return CMD_SUCCESS;
+}
+
 static void
 ospf6_show (struct vty *vty, struct ospf6 *o)
 {
@@ -486,6 +581,9 @@ ospf6_show (struct vty *vty, struct ospf6 *o)
   /* Redistribute configuration */
   /* XXX */
 
+  if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
+    vty_out (vty, " Router Is Stub Router%s", VNL);
+
   /* LSAs */
   vty_out (vty, " Number of AS scoped LSAs is %u%s",
            o->lsdb->count, VNL);
@@ -654,6 +752,16 @@ DEFUN (show_ipv6_ospf6_route_type_detail,
   return CMD_SUCCESS;
 }
 
+static void
+ospf6_stub_router_config_write (struct vty *vty)
+{
+  if (CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER))
+    {
+      vty_out (vty, " stub-router administrative%s", VNL);
+    }
+    return;
+}
+
 /* OSPF configuration write function. */
 static int
 config_write_ospf6 (struct vty *vty)
@@ -674,6 +782,7 @@ config_write_ospf6 (struct vty *vty)
   if (ospf6->router_id_static != 0)
     vty_out (vty, " router-id %s%s", router_id, VNL);
 
+  ospf6_stub_router_config_write (vty);
   ospf6_redistribute_config_write (vty);
   ospf6_area_config_write (vty);
   ospf6_spf_config_write (vty);
@@ -729,6 +838,14 @@ ospf6_top_init (void)
   install_element (OSPF6_NODE, &ospf6_router_id_cmd);
   install_element (OSPF6_NODE, &ospf6_interface_area_cmd);
   install_element (OSPF6_NODE, &no_ospf6_interface_area_cmd);
+  install_element (OSPF6_NODE, &ospf6_stub_router_admin_cmd);
+  install_element (OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
+  /* For a later time
+  install_element (OSPF6_NODE, &ospf6_stub_router_startup_cmd);
+  install_element (OSPF6_NODE, &no_ospf6_stub_router_startup_cmd);
+  install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd);
+  install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd);
+  */
 }
 
 
index 27eb18cddf9f41ca0dfc797a68415f95882ccf47..02eb9154735ceb68aa40fa81bad16cd2fd311b19 100644 (file)
@@ -76,6 +76,7 @@ struct ospf6
 };
 
 #define OSPF6_DISABLED    0x01
+#define OSPF6_STUB_ROUTER 0x02
 
 /* global pointer for OSPF top data structure */
 extern struct ospf6 *ospf6;