Browse Source

ospfd: 'ip ospf network' interface should down iface before changing type

* ospf_vty.c: (ip_ospf_network) This function changes the interface type
  and only then downs/ups the interface if already up.  So the down happens
  with the interface type already altered.  However, the interface type
  can have major ramifications for how underlying state is stored/indexed,
  which may cause problems.

  Further, bit of an encapsulation violation to twiddle state here.
  (no_ip_ospf_network) ditto.
* ospf_interface.c: (ospf_if_reset_type) New function to reset the OSPF
  interface type on an interface. Ensure the interface is downed before
  the type is changed.
* ospf_interface.h: (ospf_if_reset_type) Export, for ospf_vty.c
Paul Jakma 4 years ago
parent
commit
0c175f82a8
3 changed files with 28 additions and 36 deletions
  1. 23 0
      ospfd/ospf_interface.c
  2. 1 0
      ospfd/ospf_interface.h
  3. 4 36
      ospfd/ospf_vty.c

+ 23 - 0
ospfd/ospf_interface.c

@@ -144,6 +144,29 @@ ospf_if_reset_variables (struct ospf_interface *oi)
   oi->v_ls_ack = 1;  
 }
 
+void
+ospf_if_reset_type (struct interface *ifp, u_char type)
+{
+  struct route_node *rn;
+  
+  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
+    {
+      struct ospf_interface *oi = rn->info;
+      u_char orig_ism_state;
+      
+      if (!oi)
+	continue;
+      
+      orig_ism_state = oi->state;
+      OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
+      
+      oi->type = IF_DEF_PARAMS (ifp)->type;
+      
+      if (orig_ism_state > ISM_Down)
+        OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceUp);
+    }
+}
+
 /* lookup oi for specified prefix/ifp */
 struct ospf_interface *
 ospf_if_table_lookup (struct interface *ifp, struct prefix *prefix)

+ 1 - 0
ospfd/ospf_interface.h

@@ -276,6 +276,7 @@ extern void ospf_if_init (void);
 extern void ospf_if_stream_set (struct ospf_interface *);
 extern void ospf_if_stream_unset (struct ospf_interface *);
 extern void ospf_if_reset_variables (struct ospf_interface *);
+extern void ospf_if_reset_type (struct interface *, u_char type);
 extern int ospf_if_is_enable (struct ospf_interface *);
 extern int ospf_if_get_output_cost (struct ospf_interface *);
 extern void ospf_if_recalculate_output_cost (struct interface *);

+ 4 - 36
ospfd/ospf_vty.c

@@ -5418,7 +5418,6 @@ DEFUN (ip_ospf_network,
 {
   struct interface *ifp = vty->index;
   int old_type = IF_DEF_PARAMS (ifp)->type;
-  struct route_node *rn;
 
   if (old_type == OSPF_IFTYPE_LOOPBACK)
     {
@@ -5439,23 +5438,7 @@ DEFUN (ip_ospf_network,
     return CMD_SUCCESS;
 
   SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
-
-  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
-    {
-      struct ospf_interface *oi = rn->info;
-
-      if (!oi)
-	continue;
-      
-      oi->type = IF_DEF_PARAMS (ifp)->type;
-      
-      if (oi->state > ISM_Down)
-	{
-	  OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
-	  OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceUp);
-	}
-    }
-
+  ospf_if_reset_type (ifp, IF_DEF_PARAMS (ifp)->type);
   return CMD_SUCCESS;
 }
 
@@ -5479,29 +5462,14 @@ DEFUN (no_ip_ospf_network,
 {
   struct interface *ifp = vty->index;
   int old_type = IF_DEF_PARAMS (ifp)->type;
-  struct route_node *rn;
 
   IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
 
   if (IF_DEF_PARAMS (ifp)->type == old_type)
     return CMD_SUCCESS;
-
-  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
-    {
-      struct ospf_interface *oi = rn->info;
-
-      if (!oi)
-	continue;
-      
-      oi->type = IF_DEF_PARAMS (ifp)->type;
-      
-      if (oi->state > ISM_Down)
-	{
-	  OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
-	  OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceUp);
-	}
-    }
-
+  
+  ospf_if_reset_type (ifp, IF_DEF_PARAMS (ifp)->type);
+  
   return CMD_SUCCESS;
 }