[quagga-dev 5529] Re: ospf network command w.r.t unnumberd interfaces

Joakim Tjernlund joakim.tjernlund at transmode.se
Mon Jun 30 17:34:02 BST 2008


On Sun, 2008-06-22 at 15:34 +0200, Joakim Tjernlund wrote:
> 
> So this leaves me with impl. 'ip ospf area' subcommand or
> adding PtP with the 'network x/y area 0' command once the
> remote network is known. This last one appears a bit tricky, seems
> like I need to count the remote networks. When the first instance
> of a particular remote network appears I need the do a 'network x/y area 0'
> and when the last interface to a particular remote network goes down/is removed
> I need to do 'no network x/y area 0'

Here is a first draft for the ip ospf area subcommand. There is room for
code improvement but I think this is what the command should do, please
comment.

 Jocke

PS.
    This is my last work week before a long vacation so I would
    appreciate any comments as soon as possible.

diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index e7ae4ba..0cee81b 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -47,6 +47,7 @@ struct ospf_if_params
   DECLARE_IF_PARAM (u_int32_t, retransmit_interval); /* Retransmission Interval */
   DECLARE_IF_PARAM (u_char, passive_interface);      /* OSPF Interface is passive: no sending or receiving (no need to join multicast groups) */
   DECLARE_IF_PARAM (u_char, priority);               /* OSPF Interface priority */
+  DECLARE_IF_PARAM (struct in_addr, run_ospf);       /* Run OSPF on this interface */
   DECLARE_IF_PARAM (u_char, type);                   /* type of interface */
 #define OSPF_IF_ACTIVE                  0
 #define OSPF_IF_PASSIVE		        1
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 76ea0a3..ac65eb0 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -5710,6 +5710,71 @@ ALIAS (no_ip_ospf_transmit_delay,
        "OSPF interface commands\n"
        "Link state transmit delay\n")
 
+DEFUN (ip_ospf_area,
+       ip_ospf_area_cmd,
+       "ip ospf area (A.B.C.D|<0-4294967295>)",
+       "IP Information\n"
+       "OSPF interface commands\n"
+       "Enable OSPF on this interface\n"
+       "OSPF area ID in IP address format\n"
+       "OSPF area ID as a decimal value\n")
+{
+  struct interface *ifp = vty->index;
+  int format, ret;
+  struct in_addr area_id;
+  struct ospf *ospf;
+
+  ret = ospf_str2area_id (argv[0], &area_id, &format);
+
+  if (ret < 0)
+    {
+      vty_out (vty, "Please specify area by A.B.C.D|<0-4294967295>%s",
+	       VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if ((ospf = ospf_lookup ()) == NULL)
+    {
+      vty_out (vty, "There isn't active ospf instance%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if (!ospf_interface_set (ospf, ifp, area_id))
+    {
+      vty_out (vty, "There is already a interface statement.%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_ospf_area,
+       no_ip_ospf_area_cmd,
+       "no ip ospf area",
+       NO_STR
+       "IP Information\n"
+       "OSPF interface commands\n"
+       "Disable OSPF on this interface\n")
+{
+  struct interface *ifp = vty->index;
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup ()) == NULL)
+    {
+      vty_out (vty, "There isn't active ospf instance%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if (!ospf_interface_unset (ospf, ifp))
+    {
+      vty_out (vty, "Can't find specified inteface area configuration.%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  return CMD_SUCCESS;
+}
+
+
 
 DEFUN (ospf_redistribute_source_metric_type,
        ospf_redistribute_source_metric_type_routemap_cmd,
@@ -8145,6 +8210,10 @@ ospf_vty_if_init (void)
   install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_addr_cmd);
   install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_cmd);
 
+  /* "ip ospf area" commands. */
+  install_element (INTERFACE_NODE, &ip_ospf_area_cmd);
+  install_element (INTERFACE_NODE, &no_ip_ospf_area_cmd);
+
   /* These commands are compatibitliy for previous version. */
   install_element (INTERFACE_NODE, &ospf_authentication_key_cmd);
   install_element (INTERFACE_NODE, &no_ospf_authentication_key_cmd);
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 2b3c322..bec3823 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -798,6 +798,120 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
   return 1;
 }
 
+int
+ospf_interface_set (struct ospf *ospf, struct interface *ifp,
+		    struct in_addr area_id)
+{
+  struct ospf_area *area;
+  struct route_node *rn;
+  struct external_info *ei;
+  struct listnode *cnode;
+  struct connected *co;
+  struct ospf_if_params *params;
+  int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
+
+  params = IF_DEF_PARAMS (ifp);
+  if (OSPF_IF_PARAM_CONFIGURED(params, run_ospf))
+    return 0;
+
+  SET_IF_PARAM (params, run_ospf);
+  params->run_ospf = area_id;
+
+  area = ospf_area_get (ospf, area_id, ret);
+
+  for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
+    {
+      struct ospf_interface *oi;
+
+      if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
+	continue;
+
+      oi = ospf_if_table_lookup(ifp, co->address);
+      if (oi) 
+	{ /* Just adjust area for existing interfase */
+	  ospf_area_del_if (oi->area, oi);
+	  oi->area = area;
+	  ospf_area_add_if (oi->area, oi);
+	}
+      else
+	{ /* This should be in a function */
+	  oi = ospf_if_new (ospf, ifp, co->address);
+	  oi->connected = co;
+
+	  oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
+	  oi->output_cost = ospf_if_get_output_cost (oi);
+
+	  /* Add pseudo neighbor. */
+	  ospf_nbr_add_self (oi);
+
+	  /* Relate ospf interface to ospf instance. */
+	  oi->ospf = ospf;
+
+	  /* update network type as interface flag */
+	  /* If network type is specified previously,
+	     skip network type setting. */
+	  oi->type = IF_DEF_PARAMS (ifp)->type;
+
+	  ospf_area_add_if (oi->area, oi);
+
+	  /* if router_id is not configured, dont bring up
+	   * interfaces.
+	   * ospf_router_id_update() will call ospf_if_update
+	   * whenever r-id is configured instead.
+	   */
+	  if ((ospf->router_id.s_addr != 0)
+	      && if_is_operative (ifp)) 
+	    ospf_if_up (oi);
+	}
+    }
+
+  /* Update connected redistribute. */
+  /* This should be in a function */
+  if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
+    if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
+      for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
+	   rn; rn = route_next (rn))
+	if ((ei = rn->info) != NULL)
+	  if (ospf_external_info_find_lsa (ospf, &ei->p))
+	    if (!ospf_distribute_check_connected (ospf, ei))
+	      ospf_external_lsa_flush (ospf, ei->type, &ei->p,
+				       ei->ifindex /*, ei->nexthop */);
+
+  ospf_area_check_free (ospf, area_id);
+
+  return 1;
+}
+
+int
+ospf_interface_unset (struct ospf *ospf, struct interface *ifp)
+{
+  struct route_node *rn;
+  struct external_info *ei;
+  struct ospf_if_params *params;
+
+  params = IF_DEF_PARAMS (ifp);
+
+  if (!OSPF_IF_PARAM_CONFIGURED(params, run_ospf))
+    return 0;
+
+  UNSET_IF_PARAM (params, run_ospf);
+
+  ospf_if_update (ospf);
+
+  /* Update connected redistribute. */
+  if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
+    if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
+      for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
+	   rn; rn = route_next (rn))
+	if ((ei = rn->info) != NULL)
+	  if (!ospf_external_info_find_lsa (ospf, &ei->p))
+	    if (ospf_distribute_check_connected (ospf, ei))
+	      ospf_external_lsa_originate (ospf, ei);
+
+  return 1;
+}
+
+
 /* Check whether interface matches given network
  * returns: 1, true. 0, false
  */
@@ -874,7 +988,10 @@ ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
       
       if (memcmp (ifp->name, "VLINK", 5) == 0)
 	continue;
-	
+
+      if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS (ifp), run_ospf))
+	continue;
+
       /* if interface prefix is match specified prefix,
 	 then create socket and join multicast group. */
       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
@@ -976,7 +1093,9 @@ ospf_if_update (struct ospf *ospf)
 	  
 	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
 	    continue;
-	  
+	  if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS (oi->ifp), run_ospf))
+	    continue;
+
 	  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
 	    {
 	      if (rn->info == NULL)




More information about the Quagga-dev mailing list