[quagga-dev 11475] [PATCH 1/4] lib: simplify distribute.c's code.

Matthieu Boutier boutier at pps.univ-paris-diderot.fr
Wed Sep 10 15:50:42 BST 2014


Use loops and variables instead of doing each cases by hand.
Use static functions instead of rewriting code.
---
 lib/distribute.c | 296 +++++++++++++++++++++++--------------------------------
 1 file changed, 124 insertions(+), 172 deletions(-)

diff --git a/lib/distribute.c b/lib/distribute.c
index ba8043c..4603e13 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -45,22 +45,33 @@ distribute_new (void)
 static void
 distribute_free (struct distribute *dist)
 {
+  int i = 0;
   if (dist->ifname)
     XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
 
-  if (dist->list[DISTRIBUTE_IN])
-    free (dist->list[DISTRIBUTE_IN]);
-  if (dist->list[DISTRIBUTE_OUT])
-    free (dist->list[DISTRIBUTE_OUT]);
+  for (i=0; i < DISTRIBUTE_MAX; i++)
+    if (dist->list[i])
+      free(dist->list[i]);
 
-  if (dist->prefix[DISTRIBUTE_IN])
-    free (dist->prefix[DISTRIBUTE_IN]);
-  if (dist->prefix[DISTRIBUTE_OUT])
-    free (dist->prefix[DISTRIBUTE_OUT]);
+  for (i=0; i < DISTRIBUTE_MAX; i++)
+    if (dist->prefix[i])
+      free(dist->prefix[i]);
 
   XFREE (MTYPE_DISTRIBUTE, dist);
 }
 
+static void
+distribute_free_if_empty(struct distribute *dist)
+{
+  int i;
+  for (i=0; i < DISTRIBUTE_MAX; i++)
+    if (dist->list[i] != NULL || dist->prefix[i] != NULL)
+      return;
+
+  hash_release (disthash, dist);
+  distribute_free (dist);
+}
+
 /* Lookup interface's distribute list. */
 struct distribute *
 distribute_lookup (const char *ifname)
@@ -136,36 +147,27 @@ distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
 
 /* Set access-list name to the distribute list. */
 static struct distribute *
-distribute_list_set (const char *ifname, enum distribute_type type, 
+distribute_list_set (const char *ifname, enum distribute_type type,
                      const char *alist_name)
 {
   struct distribute *dist;
 
   dist = distribute_get (ifname);
 
-  if (type == DISTRIBUTE_IN)
-    {
-      if (dist->list[DISTRIBUTE_IN])
-	free (dist->list[DISTRIBUTE_IN]);
-      dist->list[DISTRIBUTE_IN] = strdup (alist_name);
-    }
-  if (type == DISTRIBUTE_OUT)
-    {
-      if (dist->list[DISTRIBUTE_OUT])
-	free (dist->list[DISTRIBUTE_OUT]);
-      dist->list[DISTRIBUTE_OUT] = strdup (alist_name);
-    }
+  if (dist->list[type])
+    free (dist->list[type]);
+  dist->list[type] = strdup (alist_name);
 
   /* Apply this distribute-list to the interface. */
   (*distribute_add_hook) (dist);
-  
+
   return dist;
 }
 
 /* Unset distribute-list.  If matched distribute-list exist then
    return 1. */
 static int
-distribute_list_unset (const char *ifname, enum distribute_type type, 
+distribute_list_unset (const char *ifname, enum distribute_type type,
 		       const char *alist_name)
 {
   struct distribute *dist;
@@ -174,41 +176,19 @@ distribute_list_unset (const char *ifname, enum distribute_type type,
   if (!dist)
     return 0;
 
-  if (type == DISTRIBUTE_IN)
-    {
-      if (!dist->list[DISTRIBUTE_IN])
-	return 0;
-      if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
-	return 0;
-
-      free (dist->list[DISTRIBUTE_IN]);
-      dist->list[DISTRIBUTE_IN] = NULL;      
-    }
-
-  if (type == DISTRIBUTE_OUT)
-    {
-      if (!dist->list[DISTRIBUTE_OUT])
-	return 0;
-      if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
-	return 0;
+  if (!dist->list[type])
+    return 0;
+  if (strcmp (dist->list[type], alist_name) != 0)
+    return 0;
 
-      free (dist->list[DISTRIBUTE_OUT]);
-      dist->list[DISTRIBUTE_OUT] = NULL;      
-    }
+  free (dist->list[type]);
+  dist->list[type] = NULL;
 
   /* Apply this distribute-list to the interface. */
   (*distribute_delete_hook) (dist);
 
-  /* If both out and in is NULL then free distribute list. */
-  if (dist->list[DISTRIBUTE_IN] == NULL &&
-      dist->list[DISTRIBUTE_OUT] == NULL &&
-      dist->prefix[DISTRIBUTE_IN] == NULL &&
-      dist->prefix[DISTRIBUTE_OUT] == NULL)
-    {
-      hash_release (disthash, dist);
-      distribute_free (dist);
-    }
-
+  /* If all dist are NULL, then free distribute list. */
+  distribute_free_if_empty(dist);
   return 1;
 }
 
@@ -221,18 +201,9 @@ distribute_list_prefix_set (const char *ifname, enum distribute_type type,
 
   dist = distribute_get (ifname);
 
-  if (type == DISTRIBUTE_IN)
-    {
-      if (dist->prefix[DISTRIBUTE_IN])
-	free (dist->prefix[DISTRIBUTE_IN]);
-      dist->prefix[DISTRIBUTE_IN] = strdup (plist_name);
-    }
-  if (type == DISTRIBUTE_OUT)
-    {
-      if (dist->prefix[DISTRIBUTE_OUT])
-	free (dist->prefix[DISTRIBUTE_OUT]);
-      dist->prefix[DISTRIBUTE_OUT] = strdup (plist_name);
-    }
+  if (dist->prefix[type])
+    free (dist->prefix[type]);
+  dist->prefix[type] = strdup (plist_name);
 
   /* Apply this distribute-list to the interface. */
   (*distribute_add_hook) (dist);
@@ -252,41 +223,19 @@ distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
   if (!dist)
     return 0;
 
-  if (type == DISTRIBUTE_IN)
-    {
-      if (!dist->prefix[DISTRIBUTE_IN])
-	return 0;
-      if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
-	return 0;
-
-      free (dist->prefix[DISTRIBUTE_IN]);
-      dist->prefix[DISTRIBUTE_IN] = NULL;      
-    }
-
-  if (type == DISTRIBUTE_OUT)
-    {
-      if (!dist->prefix[DISTRIBUTE_OUT])
-	return 0;
-      if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
-	return 0;
+  if (!dist->prefix[type])
+    return 0;
+  if (strcmp (dist->prefix[type], plist_name) != 0)
+    return 0;
 
-      free (dist->prefix[DISTRIBUTE_OUT]);
-      dist->prefix[DISTRIBUTE_OUT] = NULL;      
-    }
+  free (dist->prefix[type]);
+  dist->prefix[type] = NULL;
 
   /* Apply this distribute-list to the interface. */
   (*distribute_delete_hook) (dist);
 
-  /* If both out and in is NULL then free distribute list. */
-  if (dist->list[DISTRIBUTE_IN] == NULL &&
-      dist->list[DISTRIBUTE_OUT] == NULL &&
-      dist->prefix[DISTRIBUTE_IN] == NULL &&
-      dist->prefix[DISTRIBUTE_OUT] == NULL)
-    {
-      hash_release (disthash, dist);
-      distribute_free (dist);
-    }
-
+  /* If all dist are NULL, then free distribute list. */
+  distribute_free_if_empty(dist);
   return 1;
 }
 
@@ -394,7 +343,7 @@ DEFUN (distribute_list,
   distribute_list_set (argv[2], type, argv[0]);
 
   return CMD_SUCCESS;
-}       
+}
 
 ALIAS (distribute_list,
        ipv6_distribute_list_cmd,
@@ -435,7 +384,7 @@ DEFUN (no_distribute_list, no_distribute_list_cmd,
       return CMD_WARNING;
     }
   return CMD_SUCCESS;
-}       
+}
 
 ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
        "no distribute-list WORD (in|out) WORD",
@@ -473,7 +422,7 @@ DEFUN (distribute_list_prefix_all,
   distribute_list_prefix_set (NULL, type, argv[0]);
 
   return CMD_SUCCESS;
-}       
+}
 
 ALIAS (distribute_list_prefix_all,
        ipv6_distribute_list_prefix_all_cmd,
@@ -516,7 +465,7 @@ DEFUN (no_distribute_list_prefix_all,
       return CMD_WARNING;
     }
   return CMD_SUCCESS;
-}       
+}
 
 ALIAS (no_distribute_list_prefix_all,
        no_ipv6_distribute_list_prefix_all_cmd,
@@ -555,7 +504,7 @@ DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
   distribute_list_prefix_set (argv[2], type, argv[0]);
 
   return CMD_SUCCESS;
-}       
+}
 
 ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
        "distribute-list prefix WORD (in|out) WORD",
@@ -598,7 +547,7 @@ DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
       return CMD_WARNING;
     }
   return CMD_SUCCESS;
-}       
+}
 
 ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
        "no distribute-list prefix WORD (in|out) WORD",
@@ -610,80 +559,96 @@ ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
        "Filter outgoing routing updates\n"
        "Interface name\n")
 
+static int
+distribute_print (struct vty *vty, char *tab[], int is_prefix,
+                  enum distribute_type type, int has_print)
+{
+  if (tab[type]) {
+    vty_out (vty, "%s %s%s",
+             has_print ? "," : "",
+             is_prefix ? "(prefix-list) " : "",
+             tab[type]);
+    return 1;
+  }
+  return has_print;
+}
+
 int
 config_show_distribute (struct vty *vty)
 {
   unsigned int i;
+  int has_print = 0;
   struct hash_backet *mp;
   struct distribute *dist;
 
   /* Output filter configuration. */
   dist = distribute_lookup (NULL);
-  if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
+  vty_out(vty, "  Outgoing update filter list for all interface is");
+  has_print = 0;
+  if (dist)
     {
-      vty_out (vty, "  Outgoing update filter list for all interface is");
-      if (dist->list[DISTRIBUTE_OUT])
-	vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
-      if (dist->prefix[DISTRIBUTE_OUT])
-	vty_out (vty, "%s (prefix-list) %s",
-		 dist->list[DISTRIBUTE_OUT] ? "," : "",
-		 dist->prefix[DISTRIBUTE_OUT]);
-      vty_out (vty, "%s", VTY_NEWLINE);
+      has_print = distribute_print(vty, dist->list,   0,
+                                   DISTRIBUTE_OUT, has_print);
+      has_print = distribute_print(vty, dist->prefix, 1,
+                                   DISTRIBUTE_OUT, has_print);
     }
+  if (has_print)
+    vty_out (vty, "%s", VTY_NEWLINE);
   else
-    vty_out (vty, "  Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
+    vty_out (vty, " not set%s", VTY_NEWLINE);
 
   for (i = 0; i < disthash->size; i++)
     for (mp = disthash->index[i]; mp; mp = mp->next)
       {
 	dist = mp->data;
 	if (dist->ifname)
-	  if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
-	    {
-	      vty_out (vty, "    %s filtered by", dist->ifname);
-	      if (dist->list[DISTRIBUTE_OUT])
-		vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
-	      if (dist->prefix[DISTRIBUTE_OUT])
-		vty_out (vty, "%s (prefix-list) %s",
-			 dist->list[DISTRIBUTE_OUT] ? "," : "",
-			 dist->prefix[DISTRIBUTE_OUT]);
-	      vty_out (vty, "%s", VTY_NEWLINE);
-	    }
+          {
+            vty_out (vty, "    %s filtered by", dist->ifname);
+            has_print = 0;
+            has_print = distribute_print(vty, dist->list,   0,
+                                         DISTRIBUTE_OUT, has_print);
+            has_print = distribute_print(vty, dist->prefix, 1,
+                                         DISTRIBUTE_OUT, has_print);
+            if (has_print)
+              vty_out (vty, "%s", VTY_NEWLINE);
+            else
+              vty_out(vty, " nothing%s", VTY_NEWLINE);
+          }
       }
 
 
   /* Input filter configuration. */
   dist = distribute_lookup (NULL);
-  if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
+  vty_out(vty, "  Incoming update filter list for all interface is");
+  has_print = 0;
+  if (dist)
     {
-      vty_out (vty, "  Incoming update filter list for all interface is");
-      if (dist->list[DISTRIBUTE_IN])
-	vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
-      if (dist->prefix[DISTRIBUTE_IN])
-	vty_out (vty, "%s (prefix-list) %s",
-		 dist->list[DISTRIBUTE_IN] ? "," : "",
-		 dist->prefix[DISTRIBUTE_IN]);
-      vty_out (vty, "%s", VTY_NEWLINE);
-    }
+      has_print = distribute_print(vty, dist->list,   0,
+                                   DISTRIBUTE_IN, has_print);
+      has_print = distribute_print(vty, dist->prefix, 1,
+                                   DISTRIBUTE_IN, has_print);    }
+  if (has_print)
+    vty_out (vty, "%s", VTY_NEWLINE);
   else
-    vty_out (vty, "  Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
+    vty_out (vty, " not set%s", VTY_NEWLINE);
 
   for (i = 0; i < disthash->size; i++)
     for (mp = disthash->index[i]; mp; mp = mp->next)
       {
 	dist = mp->data;
-	if (dist->ifname)
-	  if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
-	    {
-	      vty_out (vty, "    %s filtered by", dist->ifname);
-	      if (dist->list[DISTRIBUTE_IN])
-		vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
-	      if (dist->prefix[DISTRIBUTE_IN])
-		vty_out (vty, "%s (prefix-list) %s",
-			 dist->list[DISTRIBUTE_IN] ? "," : "",
-			 dist->prefix[DISTRIBUTE_IN]);
-	      vty_out (vty, "%s", VTY_NEWLINE);
-	    }
+        if (dist->ifname)
+          {
+            vty_out (vty, "    %s filtered by", dist->ifname);
+            has_print = 0;
+            has_print = distribute_print(vty, dist->list,   0,
+                                         DISTRIBUTE_IN, has_print);
+            has_print = distribute_print(vty, dist->prefix, 1,
+                                         DISTRIBUTE_IN, has_print);
+            if (has_print)
+              vty_out (vty, "%s", VTY_NEWLINE);
+            else
+              vty_out(vty, " nothing%s", VTY_NEWLINE);
+          }
       }
   return 0;
 }
@@ -693,6 +658,8 @@ int
 config_write_distribute (struct vty *vty)
 {
   unsigned int i;
+  int j;
+  int output;
   struct hash_backet *mp;
   int write = 0;
 
@@ -703,38 +670,23 @@ config_write_distribute (struct vty *vty)
 
 	dist = mp->data;
 
-	if (dist->list[DISTRIBUTE_IN])
-	  {
-	    vty_out (vty, " distribute-list %s in %s%s", 
-		     dist->list[DISTRIBUTE_IN],
-		     dist->ifname ? dist->ifname : "",
-		     VTY_NEWLINE);
-	    write++;
-	  }
-
-	if (dist->list[DISTRIBUTE_OUT])
-	  {
-	    vty_out (vty, " distribute-list %s out %s%s", 
-
-		     dist->list[DISTRIBUTE_OUT],
-		     dist->ifname ? dist->ifname : "",
-		     VTY_NEWLINE);
-	    write++;
-	  }
-
-	if (dist->prefix[DISTRIBUTE_IN])
-	  {
-	    vty_out (vty, " distribute-list prefix %s in %s%s",
-		     dist->prefix[DISTRIBUTE_IN],
+	for (j=0; j < DISTRIBUTE_MAX; j++)
+	  if (dist->list[j]) {
+	    output = j == DISTRIBUTE_OUT;
+	    vty_out (vty, " distribute-list %s %s %s%s",
+		     dist->list[j],
+		     output ? "out" : "in",
 		     dist->ifname ? dist->ifname : "",
 		     VTY_NEWLINE);
 	    write++;
 	  }
 
-	if (dist->prefix[DISTRIBUTE_OUT])
-	  {
-	    vty_out (vty, " distribute-list prefix %s out %s%s",
-		     dist->prefix[DISTRIBUTE_OUT],
+	for (j=0; j < DISTRIBUTE_MAX; j++)
+	  if (dist->prefix[j]) {
+	    output = j == DISTRIBUTE_OUT;
+	    vty_out (vty, " distribute-list prefix %s %s %s%s",
+		     dist->prefix[j],
+		     output ? "out" : "in",
 		     dist->ifname ? dist->ifname : "",
 		     VTY_NEWLINE);
 	    write++;
-- 
1.7.12.4 (Apple Git-37)





More information about the Quagga-dev mailing list