LCOV - code coverage report
Current view: top level - lib - distribute.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 306 0.0 %
Date: 2015-11-19 Functions: 0 25 0.0 %

          Line data    Source code
       1             : /* Distribute list functions
       2             :  * Copyright (C) 1998, 1999 Kunihiro Ishiguro
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published
       8             :  * by the Free Software Foundation; either version 2, or (at your
       9             :  * option) any later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with GNU Zebra; see the file COPYING.  If not, write to the
      18             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      19             :  * Boston, MA 02111-1307, USA.
      20             :  */
      21             : 
      22             : #include <zebra.h>
      23             : 
      24             : #include "hash.h"
      25             : #include "if.h"
      26             : #include "filter.h"
      27             : #include "command.h"
      28             : #include "distribute.h"
      29             : #include "memory.h"
      30             : 
      31             : /* Hash of distribute list. */
      32             : struct hash *disthash;
      33             : 
      34             : /* Hook functions. */
      35             : void (*distribute_add_hook) (struct distribute *);
      36             : void (*distribute_delete_hook) (struct distribute *);
      37             : 
      38             : static struct distribute *
      39           0 : distribute_new (void)
      40             : {
      41           0 :   return XCALLOC (MTYPE_DISTRIBUTE, sizeof (struct distribute));
      42             : }
      43             : 
      44             : /* Free distribute object. */
      45             : static void
      46           0 : distribute_free (struct distribute *dist)
      47             : {
      48           0 :   if (dist->ifname)
      49           0 :     XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
      50             : 
      51           0 :   if (dist->list[DISTRIBUTE_IN])
      52           0 :     free (dist->list[DISTRIBUTE_IN]);
      53           0 :   if (dist->list[DISTRIBUTE_OUT])
      54           0 :     free (dist->list[DISTRIBUTE_OUT]);
      55             : 
      56           0 :   if (dist->prefix[DISTRIBUTE_IN])
      57           0 :     free (dist->prefix[DISTRIBUTE_IN]);
      58           0 :   if (dist->prefix[DISTRIBUTE_OUT])
      59           0 :     free (dist->prefix[DISTRIBUTE_OUT]);
      60             : 
      61           0 :   XFREE (MTYPE_DISTRIBUTE, dist);
      62           0 : }
      63             : 
      64             : /* Lookup interface's distribute list. */
      65             : struct distribute *
      66           0 : distribute_lookup (const char *ifname)
      67             : {
      68             :   struct distribute key;
      69             :   struct distribute *dist;
      70             : 
      71             :   /* temporary reference */
      72           0 :   key.ifname = (char *)ifname;
      73             : 
      74           0 :   dist = hash_lookup (disthash, &key);
      75             :   
      76           0 :   return dist;
      77             : }
      78             : 
      79             : void
      80           0 : distribute_list_add_hook (void (*func) (struct distribute *))
      81             : {
      82           0 :   distribute_add_hook = func;
      83           0 : }
      84             : 
      85             : void
      86           0 : distribute_list_delete_hook (void (*func) (struct distribute *))
      87             : {
      88           0 :   distribute_delete_hook = func;
      89           0 : }
      90             : 
      91             : static void *
      92           0 : distribute_hash_alloc (struct distribute *arg)
      93             : {
      94             :   struct distribute *dist;
      95             : 
      96           0 :   dist = distribute_new ();
      97           0 :   if (arg->ifname)
      98           0 :     dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
      99             :   else
     100           0 :     dist->ifname = NULL;
     101           0 :   return dist;
     102             : }
     103             : 
     104             : /* Make new distribute list and push into hash. */
     105             : static struct distribute *
     106           0 : distribute_get (const char *ifname)
     107             : {
     108             :   struct distribute key;
     109             : 
     110             :   /* temporary reference */
     111           0 :   key.ifname = (char *)ifname;
     112             :   
     113           0 :   return hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
     114             : }
     115             : 
     116             : static unsigned int
     117           0 : distribute_hash_make (void *arg)
     118             : {
     119           0 :   const struct distribute *dist = arg;
     120             : 
     121           0 :   return dist->ifname ? string_hash_make (dist->ifname) : 0;
     122             : }
     123             : 
     124             : /* If two distribute-list have same value then return 1 else return
     125             :    0. This function is used by hash package. */
     126             : static int
     127           0 : distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
     128             : {
     129           0 :   if (dist1->ifname && dist2->ifname)
     130           0 :     if (strcmp (dist1->ifname, dist2->ifname) == 0)
     131           0 :       return 1;
     132           0 :   if (! dist1->ifname && ! dist2->ifname)
     133           0 :     return 1;
     134           0 :   return 0;
     135             : }
     136             : 
     137             : /* Set access-list name to the distribute list. */
     138             : static struct distribute *
     139           0 : distribute_list_set (const char *ifname, enum distribute_type type, 
     140             :                      const char *alist_name)
     141             : {
     142             :   struct distribute *dist;
     143             : 
     144           0 :   dist = distribute_get (ifname);
     145             : 
     146           0 :   if (type == DISTRIBUTE_IN)
     147             :     {
     148           0 :       if (dist->list[DISTRIBUTE_IN])
     149           0 :         free (dist->list[DISTRIBUTE_IN]);
     150           0 :       dist->list[DISTRIBUTE_IN] = strdup (alist_name);
     151             :     }
     152           0 :   if (type == DISTRIBUTE_OUT)
     153             :     {
     154           0 :       if (dist->list[DISTRIBUTE_OUT])
     155           0 :         free (dist->list[DISTRIBUTE_OUT]);
     156           0 :       dist->list[DISTRIBUTE_OUT] = strdup (alist_name);
     157             :     }
     158             : 
     159             :   /* Apply this distribute-list to the interface. */
     160           0 :   (*distribute_add_hook) (dist);
     161             :   
     162           0 :   return dist;
     163             : }
     164             : 
     165             : /* Unset distribute-list.  If matched distribute-list exist then
     166             :    return 1. */
     167             : static int
     168           0 : distribute_list_unset (const char *ifname, enum distribute_type type, 
     169             :                        const char *alist_name)
     170             : {
     171             :   struct distribute *dist;
     172             : 
     173           0 :   dist = distribute_lookup (ifname);
     174           0 :   if (!dist)
     175           0 :     return 0;
     176             : 
     177           0 :   if (type == DISTRIBUTE_IN)
     178             :     {
     179           0 :       if (!dist->list[DISTRIBUTE_IN])
     180           0 :         return 0;
     181           0 :       if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
     182           0 :         return 0;
     183             : 
     184           0 :       free (dist->list[DISTRIBUTE_IN]);
     185           0 :       dist->list[DISTRIBUTE_IN] = NULL;      
     186             :     }
     187             : 
     188           0 :   if (type == DISTRIBUTE_OUT)
     189             :     {
     190           0 :       if (!dist->list[DISTRIBUTE_OUT])
     191           0 :         return 0;
     192           0 :       if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
     193           0 :         return 0;
     194             : 
     195           0 :       free (dist->list[DISTRIBUTE_OUT]);
     196           0 :       dist->list[DISTRIBUTE_OUT] = NULL;      
     197             :     }
     198             : 
     199             :   /* Apply this distribute-list to the interface. */
     200           0 :   (*distribute_delete_hook) (dist);
     201             : 
     202             :   /* If both out and in is NULL then free distribute list. */
     203           0 :   if (dist->list[DISTRIBUTE_IN] == NULL &&
     204           0 :       dist->list[DISTRIBUTE_OUT] == NULL &&
     205           0 :       dist->prefix[DISTRIBUTE_IN] == NULL &&
     206           0 :       dist->prefix[DISTRIBUTE_OUT] == NULL)
     207             :     {
     208           0 :       hash_release (disthash, dist);
     209           0 :       distribute_free (dist);
     210             :     }
     211             : 
     212           0 :   return 1;
     213             : }
     214             : 
     215             : /* Set access-list name to the distribute list. */
     216             : static struct distribute *
     217           0 : distribute_list_prefix_set (const char *ifname, enum distribute_type type,
     218             :                             const char *plist_name)
     219             : {
     220             :   struct distribute *dist;
     221             : 
     222           0 :   dist = distribute_get (ifname);
     223             : 
     224           0 :   if (type == DISTRIBUTE_IN)
     225             :     {
     226           0 :       if (dist->prefix[DISTRIBUTE_IN])
     227           0 :         free (dist->prefix[DISTRIBUTE_IN]);
     228           0 :       dist->prefix[DISTRIBUTE_IN] = strdup (plist_name);
     229             :     }
     230           0 :   if (type == DISTRIBUTE_OUT)
     231             :     {
     232           0 :       if (dist->prefix[DISTRIBUTE_OUT])
     233           0 :         free (dist->prefix[DISTRIBUTE_OUT]);
     234           0 :       dist->prefix[DISTRIBUTE_OUT] = strdup (plist_name);
     235             :     }
     236             : 
     237             :   /* Apply this distribute-list to the interface. */
     238           0 :   (*distribute_add_hook) (dist);
     239             :   
     240           0 :   return dist;
     241             : }
     242             : 
     243             : /* Unset distribute-list.  If matched distribute-list exist then
     244             :    return 1. */
     245             : static int
     246           0 : distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
     247             :                               const char *plist_name)
     248             : {
     249             :   struct distribute *dist;
     250             : 
     251           0 :   dist = distribute_lookup (ifname);
     252           0 :   if (!dist)
     253           0 :     return 0;
     254             : 
     255           0 :   if (type == DISTRIBUTE_IN)
     256             :     {
     257           0 :       if (!dist->prefix[DISTRIBUTE_IN])
     258           0 :         return 0;
     259           0 :       if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
     260           0 :         return 0;
     261             : 
     262           0 :       free (dist->prefix[DISTRIBUTE_IN]);
     263           0 :       dist->prefix[DISTRIBUTE_IN] = NULL;      
     264             :     }
     265             : 
     266           0 :   if (type == DISTRIBUTE_OUT)
     267             :     {
     268           0 :       if (!dist->prefix[DISTRIBUTE_OUT])
     269           0 :         return 0;
     270           0 :       if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
     271           0 :         return 0;
     272             : 
     273           0 :       free (dist->prefix[DISTRIBUTE_OUT]);
     274           0 :       dist->prefix[DISTRIBUTE_OUT] = NULL;      
     275             :     }
     276             : 
     277             :   /* Apply this distribute-list to the interface. */
     278           0 :   (*distribute_delete_hook) (dist);
     279             : 
     280             :   /* If both out and in is NULL then free distribute list. */
     281           0 :   if (dist->list[DISTRIBUTE_IN] == NULL &&
     282           0 :       dist->list[DISTRIBUTE_OUT] == NULL &&
     283           0 :       dist->prefix[DISTRIBUTE_IN] == NULL &&
     284           0 :       dist->prefix[DISTRIBUTE_OUT] == NULL)
     285             :     {
     286           0 :       hash_release (disthash, dist);
     287           0 :       distribute_free (dist);
     288             :     }
     289             : 
     290           0 :   return 1;
     291             : }
     292             : 
     293           0 : DEFUN (distribute_list_all,
     294             :        distribute_list_all_cmd,
     295             :        "distribute-list WORD (in|out)",
     296             :        "Filter networks in routing updates\n"
     297             :        "Access-list name\n"
     298             :        "Filter incoming routing updates\n"
     299             :        "Filter outgoing routing updates\n")
     300             : {
     301             :   enum distribute_type type;
     302             : 
     303             :   /* Check of distribute list type. */
     304           0 :   if (strncmp (argv[1], "i", 1) == 0)
     305           0 :     type = DISTRIBUTE_IN;
     306           0 :   else if (strncmp (argv[1], "o", 1) == 0)
     307           0 :     type = DISTRIBUTE_OUT;
     308             :   else
     309             :     {
     310           0 :       vty_out (vty, "distribute list direction must be [in|out]%s",
     311           0 :                VTY_NEWLINE);
     312           0 :       return CMD_WARNING;
     313             :     }
     314             : 
     315             :   /* Get interface name corresponding distribute list. */
     316           0 :   distribute_list_set (NULL, type, argv[0]);
     317             : 
     318           0 :   return CMD_SUCCESS;
     319             : }
     320             : 
     321             : ALIAS (distribute_list_all,
     322             :        ipv6_distribute_list_all_cmd,
     323             :        "distribute-list WORD (in|out)",
     324             :        "Filter networks in routing updates\n"
     325             :        "Access-list name\n"
     326             :        "Filter incoming routing updates\n"
     327             :        "Filter outgoing routing updates\n")
     328             : 
     329           0 : DEFUN (no_distribute_list_all,
     330             :        no_distribute_list_all_cmd,
     331             :        "no distribute-list WORD (in|out)",
     332             :        NO_STR
     333             :        "Filter networks in routing updates\n"
     334             :        "Access-list name\n"
     335             :        "Filter incoming routing updates\n"
     336             :        "Filter outgoing routing updates\n")
     337             : {
     338             :   int ret;
     339             :   enum distribute_type type;
     340             : 
     341             :   /* Check of distribute list type. */
     342           0 :   if (strncmp (argv[1], "i", 1) == 0)
     343           0 :     type = DISTRIBUTE_IN;
     344           0 :   else if (strncmp (argv[1], "o", 1) == 0)
     345           0 :     type = DISTRIBUTE_OUT;
     346             :   else
     347             :     {
     348           0 :       vty_out (vty, "distribute list direction must be [in|out]%s",
     349           0 :                VTY_NEWLINE);
     350           0 :       return CMD_WARNING;
     351             :     }
     352             : 
     353           0 :   ret = distribute_list_unset (NULL, type, argv[0]);
     354           0 :   if (! ret)
     355             :     {
     356           0 :       vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
     357           0 :       return CMD_WARNING;
     358             :     }
     359           0 :   return CMD_SUCCESS;
     360             : }
     361             : 
     362             : ALIAS (no_distribute_list_all,
     363             :        no_ipv6_distribute_list_all_cmd,
     364             :        "no distribute-list WORD (in|out)",
     365             :        NO_STR
     366             :        "Filter networks in routing updates\n"
     367             :        "Access-list name\n"
     368             :        "Filter incoming routing updates\n"
     369             :        "Filter outgoing routing updates\n")
     370             : 
     371           0 : DEFUN (distribute_list,
     372             :        distribute_list_cmd,
     373             :        "distribute-list WORD (in|out) WORD",
     374             :        "Filter networks in routing updates\n"
     375             :        "Access-list name\n"
     376             :        "Filter incoming routing updates\n"
     377             :        "Filter outgoing routing updates\n"
     378             :        "Interface name\n")
     379             : {
     380             :   enum distribute_type type;
     381             : 
     382             :   /* Check of distribute list type. */
     383           0 :   if (strncmp (argv[1], "i", 1) == 0)
     384           0 :     type = DISTRIBUTE_IN;
     385           0 :   else if (strncmp (argv[1], "o", 1) == 0)
     386           0 :     type = DISTRIBUTE_OUT;
     387             :   else
     388             :     {
     389           0 :       vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
     390           0 :       return CMD_WARNING;
     391             :     }
     392             : 
     393             :   /* Get interface name corresponding distribute list. */
     394           0 :   distribute_list_set (argv[2], type, argv[0]);
     395             : 
     396           0 :   return CMD_SUCCESS;
     397             : }       
     398             : 
     399             : ALIAS (distribute_list,
     400             :        ipv6_distribute_list_cmd,
     401             :        "distribute-list WORD (in|out) WORD",
     402             :        "Filter networks in routing updates\n"
     403             :        "Access-list name\n"
     404             :        "Filter incoming routing updates\n"
     405             :        "Filter outgoing routing updates\n"
     406             :        "Interface name\n")
     407             : 
     408           0 : DEFUN (no_distribute_list, no_distribute_list_cmd,
     409             :        "no distribute-list WORD (in|out) WORD",
     410             :        NO_STR
     411             :        "Filter networks in routing updates\n"
     412             :        "Access-list name\n"
     413             :        "Filter incoming routing updates\n"
     414             :        "Filter outgoing routing updates\n"
     415             :        "Interface name\n")
     416             : {
     417             :   int ret;
     418             :   enum distribute_type type;
     419             : 
     420             :   /* Check of distribute list type. */
     421           0 :   if (strncmp (argv[1], "i", 1) == 0)
     422           0 :     type = DISTRIBUTE_IN;
     423           0 :   else if (strncmp (argv[1], "o", 1) == 0)
     424           0 :     type = DISTRIBUTE_OUT;
     425             :   else
     426             :     {
     427           0 :       vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
     428           0 :       return CMD_WARNING;
     429             :     }
     430             : 
     431           0 :   ret = distribute_list_unset (argv[2], type, argv[0]);
     432           0 :   if (! ret)
     433             :     {
     434           0 :       vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
     435           0 :       return CMD_WARNING;
     436             :     }
     437           0 :   return CMD_SUCCESS;
     438             : }       
     439             : 
     440             : ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
     441             :        "no distribute-list WORD (in|out) WORD",
     442             :        NO_STR
     443             :        "Filter networks in routing updates\n"
     444             :        "Access-list name\n"
     445             :        "Filter incoming routing updates\n"
     446             :        "Filter outgoing routing updates\n"
     447             :        "Interface name\n")
     448             : 
     449           0 : DEFUN (distribute_list_prefix_all,
     450             :        distribute_list_prefix_all_cmd,
     451             :        "distribute-list prefix WORD (in|out)",
     452             :        "Filter networks in routing updates\n"
     453             :        "Filter prefixes in routing updates\n"
     454             :        "Name of an IP prefix-list\n"
     455             :        "Filter incoming routing updates\n"
     456             :        "Filter outgoing routing updates\n")
     457             : {
     458             :   enum distribute_type type;
     459             : 
     460             :   /* Check of distribute list type. */
     461           0 :   if (strncmp (argv[1], "i", 1) == 0)
     462           0 :     type = DISTRIBUTE_IN;
     463           0 :   else if (strncmp (argv[1], "o", 1) == 0)
     464           0 :     type = DISTRIBUTE_OUT;
     465             :   else
     466             :     {
     467           0 :       vty_out (vty, "distribute list direction must be [in|out]%s", 
     468           0 :                VTY_NEWLINE);
     469           0 :       return CMD_WARNING;
     470             :     }
     471             : 
     472             :   /* Get interface name corresponding distribute list. */
     473           0 :   distribute_list_prefix_set (NULL, type, argv[0]);
     474             : 
     475           0 :   return CMD_SUCCESS;
     476             : }       
     477             : 
     478             : ALIAS (distribute_list_prefix_all,
     479             :        ipv6_distribute_list_prefix_all_cmd,
     480             :        "distribute-list prefix WORD (in|out)",
     481             :        "Filter networks in routing updates\n"
     482             :        "Filter prefixes in routing updates\n"
     483             :        "Name of an IP prefix-list\n"
     484             :        "Filter incoming routing updates\n"
     485             :        "Filter outgoing routing updates\n")
     486             : 
     487           0 : DEFUN (no_distribute_list_prefix_all,
     488             :        no_distribute_list_prefix_all_cmd,
     489             :        "no distribute-list prefix WORD (in|out)",
     490             :        NO_STR
     491             :        "Filter networks in routing updates\n"
     492             :        "Filter prefixes in routing updates\n"
     493             :        "Name of an IP prefix-list\n"
     494             :        "Filter incoming routing updates\n"
     495             :        "Filter outgoing routing updates\n")
     496             : {
     497             :   int ret;
     498             :   enum distribute_type type;
     499             : 
     500             :   /* Check of distribute list type. */
     501           0 :   if (strncmp (argv[1], "i", 1) == 0)
     502           0 :     type = DISTRIBUTE_IN;
     503           0 :   else if (strncmp (argv[1], "o", 1) == 0)
     504           0 :     type = DISTRIBUTE_OUT;
     505             :   else
     506             :     {
     507           0 :       vty_out (vty, "distribute list direction must be [in|out]%s", 
     508           0 :                VTY_NEWLINE);
     509           0 :       return CMD_WARNING;
     510             :     }
     511             : 
     512           0 :   ret = distribute_list_prefix_unset (NULL, type, argv[0]);
     513           0 :   if (! ret)
     514             :     {
     515           0 :       vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
     516           0 :       return CMD_WARNING;
     517             :     }
     518           0 :   return CMD_SUCCESS;
     519             : }       
     520             : 
     521             : ALIAS (no_distribute_list_prefix_all,
     522             :        no_ipv6_distribute_list_prefix_all_cmd,
     523             :        "no distribute-list prefix WORD (in|out)",
     524             :        NO_STR
     525             :        "Filter networks in routing updates\n"
     526             :        "Filter prefixes in routing updates\n"
     527             :        "Name of an IP prefix-list\n"
     528             :        "Filter incoming routing updates\n"
     529             :        "Filter outgoing routing updates\n")
     530             : 
     531           0 : DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
     532             :        "distribute-list prefix WORD (in|out) WORD",
     533             :        "Filter networks in routing updates\n"
     534             :        "Filter prefixes in routing updates\n"
     535             :        "Name of an IP prefix-list\n"
     536             :        "Filter incoming routing updates\n"
     537             :        "Filter outgoing routing updates\n"
     538             :        "Interface name\n")
     539             : {
     540             :   enum distribute_type type;
     541             : 
     542             :   /* Check of distribute list type. */
     543           0 :   if (strncmp (argv[1], "i", 1) == 0)
     544           0 :     type = DISTRIBUTE_IN;
     545           0 :   else if (strncmp (argv[1], "o", 1) == 0)
     546           0 :     type = DISTRIBUTE_OUT;
     547             :   else
     548             :     {
     549           0 :       vty_out (vty, "distribute list direction must be [in|out]%s", 
     550           0 :                VTY_NEWLINE);
     551           0 :       return CMD_WARNING;
     552             :     }
     553             : 
     554             :   /* Get interface name corresponding distribute list. */
     555           0 :   distribute_list_prefix_set (argv[2], type, argv[0]);
     556             : 
     557           0 :   return CMD_SUCCESS;
     558             : }       
     559             : 
     560             : ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
     561             :        "distribute-list prefix WORD (in|out) WORD",
     562             :        "Filter networks in routing updates\n"
     563             :        "Filter prefixes in routing updates\n"
     564             :        "Name of an IP prefix-list\n"
     565             :        "Filter incoming routing updates\n"
     566             :        "Filter outgoing routing updates\n"
     567             :        "Interface name\n")
     568             : 
     569           0 : DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
     570             :        "no distribute-list prefix WORD (in|out) WORD",
     571             :        NO_STR
     572             :        "Filter networks in routing updates\n"
     573             :        "Filter prefixes in routing updates\n"
     574             :        "Name of an IP prefix-list\n"
     575             :        "Filter incoming routing updates\n"
     576             :        "Filter outgoing routing updates\n"
     577             :        "Interface name\n")
     578             : {
     579             :   int ret;
     580             :   enum distribute_type type;
     581             : 
     582             :   /* Check of distribute list type. */
     583           0 :   if (strncmp (argv[1], "i", 1) == 0)
     584           0 :     type = DISTRIBUTE_IN;
     585           0 :   else if (strncmp (argv[1], "o", 1) == 0)
     586           0 :     type = DISTRIBUTE_OUT;
     587             :   else
     588             :     {
     589           0 :       vty_out (vty, "distribute list direction must be [in|out]%s", 
     590           0 :                VTY_NEWLINE);
     591           0 :       return CMD_WARNING;
     592             :     }
     593             : 
     594           0 :   ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
     595           0 :   if (! ret)
     596             :     {
     597           0 :       vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
     598           0 :       return CMD_WARNING;
     599             :     }
     600           0 :   return CMD_SUCCESS;
     601             : }       
     602             : 
     603             : ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
     604             :        "no distribute-list prefix WORD (in|out) WORD",
     605             :        NO_STR
     606             :        "Filter networks in routing updates\n"
     607             :        "Filter prefixes in routing updates\n"
     608             :        "Name of an IP prefix-list\n"
     609             :        "Filter incoming routing updates\n"
     610             :        "Filter outgoing routing updates\n"
     611             :        "Interface name\n")
     612             : 
     613             : int
     614           0 : config_show_distribute (struct vty *vty)
     615             : {
     616             :   unsigned int i;
     617             :   struct hash_backet *mp;
     618             :   struct distribute *dist;
     619             : 
     620             :   /* Output filter configuration. */
     621           0 :   dist = distribute_lookup (NULL);
     622           0 :   if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
     623             :     {
     624           0 :       vty_out (vty, "  Outgoing update filter list for all interface is");
     625           0 :       if (dist->list[DISTRIBUTE_OUT])
     626           0 :         vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
     627           0 :       if (dist->prefix[DISTRIBUTE_OUT])
     628           0 :         vty_out (vty, "%s (prefix-list) %s",
     629           0 :                  dist->list[DISTRIBUTE_OUT] ? "," : "",
     630             :                  dist->prefix[DISTRIBUTE_OUT]);
     631           0 :       vty_out (vty, "%s", VTY_NEWLINE);
     632             :     }
     633             :   else
     634           0 :     vty_out (vty, "  Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
     635             : 
     636           0 :   for (i = 0; i < disthash->size; i++)
     637           0 :     for (mp = disthash->index[i]; mp; mp = mp->next)
     638             :       {
     639           0 :         dist = mp->data;
     640           0 :         if (dist->ifname)
     641           0 :           if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
     642             :             {
     643           0 :               vty_out (vty, "    %s filtered by", dist->ifname);
     644           0 :               if (dist->list[DISTRIBUTE_OUT])
     645           0 :                 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
     646           0 :               if (dist->prefix[DISTRIBUTE_OUT])
     647           0 :                 vty_out (vty, "%s (prefix-list) %s",
     648           0 :                          dist->list[DISTRIBUTE_OUT] ? "," : "",
     649             :                          dist->prefix[DISTRIBUTE_OUT]);
     650           0 :               vty_out (vty, "%s", VTY_NEWLINE);
     651             :             }
     652             :       }
     653             : 
     654             : 
     655             :   /* Input filter configuration. */
     656           0 :   dist = distribute_lookup (NULL);
     657           0 :   if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
     658             :     {
     659           0 :       vty_out (vty, "  Incoming update filter list for all interface is");
     660           0 :       if (dist->list[DISTRIBUTE_IN])
     661           0 :         vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
     662           0 :       if (dist->prefix[DISTRIBUTE_IN])
     663           0 :         vty_out (vty, "%s (prefix-list) %s",
     664           0 :                  dist->list[DISTRIBUTE_IN] ? "," : "",
     665             :                  dist->prefix[DISTRIBUTE_IN]);
     666           0 :       vty_out (vty, "%s", VTY_NEWLINE);
     667             :     }
     668             :   else
     669           0 :     vty_out (vty, "  Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
     670             : 
     671           0 :   for (i = 0; i < disthash->size; i++)
     672           0 :     for (mp = disthash->index[i]; mp; mp = mp->next)
     673             :       {
     674           0 :         dist = mp->data;
     675           0 :         if (dist->ifname)
     676           0 :           if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
     677             :             {
     678           0 :               vty_out (vty, "    %s filtered by", dist->ifname);
     679           0 :               if (dist->list[DISTRIBUTE_IN])
     680           0 :                 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
     681           0 :               if (dist->prefix[DISTRIBUTE_IN])
     682           0 :                 vty_out (vty, "%s (prefix-list) %s",
     683           0 :                          dist->list[DISTRIBUTE_IN] ? "," : "",
     684             :                          dist->prefix[DISTRIBUTE_IN]);
     685           0 :               vty_out (vty, "%s", VTY_NEWLINE);
     686             :             }
     687             :       }
     688           0 :   return 0;
     689             : }
     690             : 
     691             : /* Configuration write function. */
     692             : int
     693           0 : config_write_distribute (struct vty *vty)
     694             : {
     695             :   unsigned int i;
     696             :   struct hash_backet *mp;
     697           0 :   int write = 0;
     698             : 
     699           0 :   for (i = 0; i < disthash->size; i++)
     700           0 :     for (mp = disthash->index[i]; mp; mp = mp->next)
     701             :       {
     702             :         struct distribute *dist;
     703             : 
     704           0 :         dist = mp->data;
     705             : 
     706           0 :         if (dist->list[DISTRIBUTE_IN])
     707             :           {
     708           0 :             vty_out (vty, " distribute-list %s in %s%s", 
     709             :                      dist->list[DISTRIBUTE_IN],
     710           0 :                      dist->ifname ? dist->ifname : "",
     711           0 :                      VTY_NEWLINE);
     712           0 :             write++;
     713             :           }
     714             : 
     715           0 :         if (dist->list[DISTRIBUTE_OUT])
     716             :           {
     717           0 :             vty_out (vty, " distribute-list %s out %s%s", 
     718             : 
     719             :                      dist->list[DISTRIBUTE_OUT],
     720           0 :                      dist->ifname ? dist->ifname : "",
     721           0 :                      VTY_NEWLINE);
     722           0 :             write++;
     723             :           }
     724             : 
     725           0 :         if (dist->prefix[DISTRIBUTE_IN])
     726             :           {
     727           0 :             vty_out (vty, " distribute-list prefix %s in %s%s",
     728             :                      dist->prefix[DISTRIBUTE_IN],
     729           0 :                      dist->ifname ? dist->ifname : "",
     730           0 :                      VTY_NEWLINE);
     731           0 :             write++;
     732             :           }
     733             : 
     734           0 :         if (dist->prefix[DISTRIBUTE_OUT])
     735             :           {
     736           0 :             vty_out (vty, " distribute-list prefix %s out %s%s",
     737             :                      dist->prefix[DISTRIBUTE_OUT],
     738           0 :                      dist->ifname ? dist->ifname : "",
     739           0 :                      VTY_NEWLINE);
     740           0 :             write++;
     741             :           }
     742             :       }
     743           0 :   return write;
     744             : }
     745             : 
     746             : /* Clear all distribute list. */
     747             : void
     748           0 : distribute_list_reset ()
     749             : {
     750           0 :   hash_clean (disthash, (void (*) (void *)) distribute_free);
     751           0 : }
     752             : 
     753             : /* Initialize distribute list related hash. */
     754             : void
     755           0 : distribute_list_init (int node)
     756             : {
     757           0 :   disthash = hash_create (distribute_hash_make,
     758             :                           (int (*) (const void *, const void *)) distribute_cmp);
     759             : 
     760           0 :   if(node==RIP_NODE) {
     761           0 :     install_element (node, &distribute_list_all_cmd);
     762           0 :     install_element (node, &no_distribute_list_all_cmd);
     763           0 :     install_element (node, &distribute_list_cmd);
     764           0 :     install_element (node, &no_distribute_list_cmd);
     765           0 :     install_element (node, &distribute_list_prefix_all_cmd);
     766           0 :     install_element (node, &no_distribute_list_prefix_all_cmd);
     767           0 :     install_element (node, &distribute_list_prefix_cmd);
     768           0 :     install_element (node, &no_distribute_list_prefix_cmd);
     769           0 :   } else if (node == RIPNG_NODE || node == BABEL_NODE) {
     770             :     /* WARNING: two identical commands installed do a crash, so be worry with
     771             :      aliases. For this reason, and because all these commands are aliases, Babel
     772             :      is not set with RIP. */
     773           0 :     install_element (node, &ipv6_distribute_list_all_cmd);
     774           0 :     install_element (node, &no_ipv6_distribute_list_all_cmd);
     775           0 :     install_element (node, &ipv6_distribute_list_cmd);
     776           0 :     install_element (node, &no_ipv6_distribute_list_cmd);
     777           0 :     install_element (node, &ipv6_distribute_list_prefix_all_cmd);
     778           0 :     install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
     779           0 :     install_element (node, &ipv6_distribute_list_prefix_cmd);
     780           0 :     install_element (node, &no_ipv6_distribute_list_prefix_cmd);
     781             :   }
     782           0 : }

Generated by: LCOV version 1.10