]> git.puffer.fish Git - matthieu/frr.git/commitdiff
[ospfd] Restructure opsf_if_update() and ospf_network_run()
authorJoakim Tjernlund <Joakim.Tjernlund@transmode.se>
Tue, 2 Sep 2008 18:06:31 +0000 (19:06 +0100)
committerPaul Jakma <paul@quagga.net>
Tue, 2 Sep 2008 20:38:00 +0000 (21:38 +0100)
    Add an struct interface paramenter and adjust the affected
    code accordingly.

    The old code was a mess looping over all interfaces several times
    when one interface was added/changed.

    * ospfd/ospfd.h: Add struct interface parameter to ospf_if_update()
    * ospfd/ospf_zebra.c: Add ifp arg to ospf_if_update() calls.
      (ospf_interface_address_delete) delete ospf_if_update() call,
      redundant as function calls ospf_if_free() itself.
    * ospfd/ospfd.c: (ospf_network_unset) handle deconfiguration here,
      rather than ospf_if_update.
      (ospf_network_run_interface) ospf_network_run, for
      any given interface.
      (ospf_network_run) move guts to previous, and use it.
      (ospf_if_update) Adjust to take struct interface as argument, as
      all callers have a specific ifp in mind.
      Iterate over ifp's connected list and call ospf_network_run_interface
      instead of ospf_network_run, turning this path into O(nm) rather
      than O(n^2).
      Adjust all code dealing with opsf_if_update and ospf_network_run to
      pass the new struct interface * arg.

     (some minor modifications and bug-additions by Paul Jakma).

Signed-off-by: Paul Jakma <paul@quagga.net>
ospfd/ospf_zebra.c
ospfd/ospfd.c
ospfd/ospfd.h

index f302d28d60827d026f378db046d511278a008b2b..e27f1394ca9fabb076874cd4ee3a2ea5f87d30e8 100644 (file)
@@ -87,7 +87,6 @@ static int
 ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
 {
   struct interface *ifp;
-  struct ospf *ospf;
 
   ifp = zebra_interface_add_read (zclient->ibuf);
 
@@ -103,9 +102,7 @@ ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
       IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
     }
 
-  ospf = ospf_lookup ();
-  if (ospf != NULL)
-    ospf_if_update (ospf);
+  ospf_if_update (NULL, ifp);
 
 #ifdef HAVE_SNMP
   ospf_snmp_if_update (ifp);
@@ -255,7 +252,6 @@ static int
 ospf_interface_address_add (int command, struct zclient *zclient,
                             zebra_size_t length)
 {
-  struct ospf *ospf;
   struct connected *c;
 
   c = zebra_interface_address_read (command, zclient->ibuf);
@@ -270,9 +266,7 @@ ospf_interface_address_add (int command, struct zclient *zclient,
       zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);
     }
 
-  ospf = ospf_lookup ();
-  if (ospf != NULL)
-    ospf_if_update (ospf);
+  ospf_if_update (NULL, c->ifp);
 
 #ifdef HAVE_SNMP
   ospf_snmp_if_update (c->ifp);
@@ -285,7 +279,6 @@ static int
 ospf_interface_address_delete (int command, struct zclient *zclient,
                                zebra_size_t length)
 {
-  struct ospf *ospf;
   struct connected *c;
   struct interface *ifp;
   struct ospf_interface *oi;
@@ -327,10 +320,6 @@ ospf_interface_address_delete (int command, struct zclient *zclient,
 
   connected_free (c);
 
-  ospf = ospf_lookup ();
-  if (ospf != NULL)
-    ospf_if_update (ospf);
-
   return 0;
 }
 
index a4c4fac31d55e4c0a118925a6b0803cc068c6075..32580ccf1d6a994c9497d38fadd848bfceabcad9 100644 (file)
@@ -68,7 +68,9 @@ extern struct in_addr router_id_zebra;
 static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
 static void ospf_network_free (struct ospf *, struct ospf_network *);
 static void ospf_area_free (struct ospf_area *);
-static void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
+static void ospf_network_run (struct prefix *, struct ospf_area *);
+static void ospf_network_run_interface (struct prefix *, struct ospf_area *,
+                                        struct interface *);
 static void ospf_finish_final (struct ospf *);
 
 #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
@@ -78,6 +80,7 @@ ospf_router_id_update (struct ospf *ospf)
 {
   struct in_addr router_id, router_id_old;
   struct ospf_interface *oi;
+  struct interface *ifp;
   struct listnode *node;
 
   if (IS_DEBUG_OSPF_EVENT)
@@ -130,7 +133,8 @@ ospf_router_id_update (struct ospf *ospf)
                     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
       
       /* update ospf_interface's */
-      ospf_if_update (ospf);
+      for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
+        ospf_if_update (ospf, ifp);
     }
 }
 \f
@@ -745,7 +749,7 @@ ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
   area = ospf_area_get (ospf, area_id, ret);
 
   /* Run network config now. */
-  ospf_network_run (ospf, (struct prefix *)p, area);
+  ospf_network_run ((struct prefix *)p, area);
 
   /* Update connected redistribute. */
   if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
@@ -770,6 +774,8 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
   struct route_node *rn;
   struct ospf_network *network;
   struct external_info *ei;
+  struct listnode *node, *nnode;
+  struct ospf_interface *oi;
 
   rn = route_node_lookup (ospf->networks, (struct prefix *)p);
   if (rn == NULL)
@@ -783,7 +789,31 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
   rn->info = NULL;
   route_unlock_node (rn);
 
-  ospf_if_update (ospf);
+  /* Find interfaces that not configured already.  */
+  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
+    {
+      int found = 0;
+      struct connected *co = oi->connected;
+      
+      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+        continue;
+      
+      for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
+        {
+          if (rn->info == NULL)
+            continue;
+          
+          if (ospf_network_match_iface(co,&rn->p))
+            {
+              found = 1;
+              route_unlock_node (rn);
+              break;
+            }
+        }
+
+      if (found == 0)
+        ospf_if_free (oi);
+    }
   
   /* Update connected redistribute. */
   if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
@@ -857,73 +887,78 @@ ospf_network_match_iface(struct connected *co, struct prefix *net)
 }
 
 void
-ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
+ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
+                            struct interface *ifp)
 {
-  struct interface *ifp;
+  struct listnode *cnode;
   struct connected *co;
+  
+  if (memcmp (ifp->name, "VLINK", 5) == 0)
+    return;
+  
+  /* if interface prefix is match specified prefix,
+     then create socket and join multicast group. */
+  for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
+    {
+      struct prefix *addr;
+      
+      if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
+        continue;
+
+      addr = CONNECTED_ID(co);
+
+      if (p->family == co->address->family 
+          && ! ospf_if_is_configured (area->ospf, &(addr->u.prefix4))
+          && ospf_network_match_iface(co,p))
+        {
+           struct ospf_interface *oi;
+            
+            oi = ospf_if_new (area->ospf, ifp, co->address);
+            oi->connected = co;
+            
+            oi->area = area;
+
+            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 = area->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 ((area->ospf->router_id.s_addr != 0)
+                && if_is_operative (ifp)) 
+              ospf_if_up (oi);
+          }
+    }
+}
+
+void
+ospf_network_run (struct prefix *p, struct ospf_area *area)
+{
+  struct interface *ifp;
   struct listnode *node;
 
   /* Schedule Router ID Update. */
-  if (ospf->router_id.s_addr == 0)
-    ospf_router_id_update (ospf);
+  if (area->ospf->router_id.s_addr == 0)
+    ospf_router_id_update (area->ospf);
   
   /* Get target interface. */
   for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
-    {
-      struct listnode *cnode;
-      
-      if (memcmp (ifp->name, "VLINK", 5) == 0)
-       continue;
-       
-      /* if interface prefix is match specified prefix,
-        then create socket and join multicast group. */
-      for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
-       {
-         struct prefix *addr;
-         
-          if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
-            continue;
-
-         addr = CONNECTED_ID(co);
-
-         if (p->family == co->address->family 
-             && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
-             && ospf_network_match_iface(co,p))
-           {
-              struct ospf_interface *oi;
-               
-               oi = ospf_if_new (ospf, ifp, co->address);
-               oi->connected = co;
-               
-               oi->area = area;
-
-               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);
-             }
-       }
-    }
+    ospf_network_run_interface (p, area, ifp);
 }
 
 void
@@ -954,55 +989,27 @@ ospf_ls_upd_queue_empty (struct ospf_interface *oi)
 }
 
 void
-ospf_if_update (struct ospf *ospf)
+ospf_if_update (struct ospf *ospf, struct interface *ifp)
 {
   struct route_node *rn;
-  struct listnode *node, *nnode;
   struct ospf_network *network;
   struct ospf_area *area;
-  struct ospf_interface *oi;
+  
+  if (!ospf)
+    ospf = ospf_lookup ();
 
-  if (ospf != NULL)
-    {
-      /* Router-ID must be configured. */
-      if (ospf->router_id.s_addr == 0)
-        return;
-      
-      /* Find interfaces that not configured already.  */
-      for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
-       {
-         int found = 0;
-         struct connected *co = oi->connected;
-         
-         if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
-           continue;
-         
-         for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
-           {
-             if (rn->info == NULL)
-               continue;
-             
-             if (ospf_network_match_iface(co,&rn->p))
-               {
-                 found = 1;
-                 route_unlock_node (rn);
-                 break;
-               }
-           }
-
-         if (found == 0)
-           ospf_if_free (oi);
-       }
-       
-      /* Run each interface. */
-      for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
-       if (rn->info != NULL)
-         {
-           network = (struct ospf_network *) rn->info;
-           area = ospf_area_get (ospf, network->area_id, network->format);
-           ospf_network_run (ospf, &rn->p, area);
-         }
-    }
+  /* Router-ID must be configured. */
+  if (ospf->router_id.s_addr == 0)
+    return;
+  
+  /* Run each netowrk for this interface. */
+  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
+    if (rn->info != NULL)
+      {
+        network = (struct ospf_network *) rn->info;
+        area = ospf_area_get (ospf, network->area_id, network->format);
+        ospf_network_run_interface (&rn->p, area, ifp);
+      }
 }
 
 void
index b618711159403a89cb675e7f6fae05b7c2c125a1..6a60e86f2192a60f391a88d253a66a087ec7d753 100644 (file)
@@ -588,7 +588,7 @@ extern int ospf_nbr_nbma_poll_interval_set (struct ospf *, struct in_addr,
 extern int ospf_nbr_nbma_poll_interval_unset (struct ospf *, struct in_addr);
 extern void ospf_prefix_list_update (struct prefix_list *);
 extern void ospf_init (void);
-extern void ospf_if_update (struct ospf *);
+extern void ospf_if_update (struct ospf *, struct interface *);
 extern void ospf_ls_upd_queue_empty (struct ospf_interface *);
 extern void ospf_terminate (void);
 extern void ospf_nbr_nbma_if_update (struct ospf *, struct ospf_interface *);