back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_filter.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 24 342 7.0 %
Date: 2023-02-24 14:41:08 Functions: 4 28 14.3 %

          Line data    Source code
       1             : /* AS path filter list.
       2             :  * Copyright (C) 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 it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * 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 along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <zebra.h>
      22             : 
      23             : #include "command.h"
      24             : #include "log.h"
      25             : #include "memory.h"
      26             : #include "buffer.h"
      27             : #include "queue.h"
      28             : #include "filter.h"
      29             : 
      30             : #include "bgpd/bgpd.h"
      31             : #include "bgpd/bgp_aspath.h"
      32             : #include "bgpd/bgp_regex.h"
      33             : #include "bgpd/bgp_filter.h"
      34             : 
      35             : /* List of AS filter list. */
      36             : struct as_list_list {
      37             :         struct as_list *head;
      38             :         struct as_list *tail;
      39             : };
      40             : 
      41             : /* AS path filter master. */
      42             : struct as_list_master {
      43             :         /* List of access_list which name is string. */
      44             :         struct as_list_list str;
      45             : 
      46             :         /* Hook function which is executed when new access_list is added. */
      47             :         void (*add_hook)(char *);
      48             : 
      49             :         /* Hook function which is executed when access_list is deleted. */
      50             :         void (*delete_hook)(const char *);
      51             : };
      52             : 
      53             : /* Element of AS path filter. */
      54             : struct as_filter {
      55             :         struct as_filter *next;
      56             :         struct as_filter *prev;
      57             : 
      58             :         enum as_filter_type type;
      59             : 
      60             :         regex_t *reg;
      61             :         char *reg_str;
      62             : 
      63             :         /* Sequence number. */
      64             :         int64_t seq;
      65             : };
      66             : 
      67             : /* AS path filter list. */
      68             : struct as_list {
      69             :         char *name;
      70             : 
      71             :         struct as_list *next;
      72             :         struct as_list *prev;
      73             : 
      74             :         struct as_filter *head;
      75             :         struct as_filter *tail;
      76             : };
      77             : 
      78             : 
      79             : /* Calculate new sequential number. */
      80           0 : static int64_t bgp_alist_new_seq_get(struct as_list *list)
      81             : {
      82           0 :         int64_t maxseq;
      83           0 :         int64_t newseq;
      84           0 :         struct as_filter *entry;
      85             : 
      86           0 :         maxseq = 0;
      87             : 
      88           0 :         for (entry = list->head; entry; entry = entry->next) {
      89           0 :                 if (maxseq < entry->seq)
      90             :                         maxseq = entry->seq;
      91             :         }
      92             : 
      93           0 :         newseq = ((maxseq / 5) * 5) + 5;
      94             : 
      95           0 :         return (newseq > UINT_MAX) ? UINT_MAX : newseq;
      96             : }
      97             : 
      98             : /* Return as-list entry which has same seq number. */
      99           0 : static struct as_filter *bgp_aslist_seq_check(struct as_list *list, int64_t seq)
     100             : {
     101           0 :         struct as_filter *entry;
     102             : 
     103           0 :         for (entry = list->head; entry; entry = entry->next)
     104           0 :                 if (entry->seq == seq)
     105             :                         return entry;
     106             : 
     107             :         return NULL;
     108             : }
     109             : 
     110             : /* as-path access-list 10 permit AS1. */
     111             : 
     112             : static struct as_list_master as_list_master = {{NULL, NULL},
     113             :                                                NULL,
     114             :                                                NULL};
     115             : 
     116             : /* Allocate new AS filter. */
     117           0 : static struct as_filter *as_filter_new(void)
     118             : {
     119           0 :         return XCALLOC(MTYPE_AS_FILTER, sizeof(struct as_filter));
     120             : }
     121             : 
     122             : /* Free allocated AS filter. */
     123           0 : static void as_filter_free(struct as_filter *asfilter)
     124             : {
     125           0 :         if (asfilter->reg)
     126           0 :                 bgp_regex_free(asfilter->reg);
     127           0 :         XFREE(MTYPE_AS_FILTER_STR, asfilter->reg_str);
     128           0 :         XFREE(MTYPE_AS_FILTER, asfilter);
     129           0 : }
     130             : 
     131             : /* Make new AS filter. */
     132           0 : static struct as_filter *as_filter_make(regex_t *reg, const char *reg_str,
     133             :                                         enum as_filter_type type)
     134             : {
     135           0 :         struct as_filter *asfilter;
     136             : 
     137           0 :         asfilter = as_filter_new();
     138           0 :         asfilter->reg = reg;
     139           0 :         asfilter->type = type;
     140           0 :         asfilter->reg_str = XSTRDUP(MTYPE_AS_FILTER_STR, reg_str);
     141             : 
     142           0 :         return asfilter;
     143             : }
     144             : 
     145           0 : static struct as_filter *as_filter_lookup(struct as_list *aslist,
     146             :                                           const char *reg_str,
     147             :                                           enum as_filter_type type)
     148             : {
     149           0 :         struct as_filter *asfilter;
     150             : 
     151           0 :         for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
     152           0 :                 if (strcmp(reg_str, asfilter->reg_str) == 0)
     153           0 :                         return asfilter;
     154             :         return NULL;
     155             : }
     156             : 
     157           0 : static void as_filter_entry_replace(struct as_list *list,
     158             :                                     struct as_filter *replace,
     159             :                                     struct as_filter *entry)
     160             : {
     161           0 :         if (replace->next) {
     162           0 :                 entry->next = replace->next;
     163           0 :                 replace->next->prev = entry;
     164             :         } else {
     165           0 :                 entry->next = NULL;
     166           0 :                 list->tail = entry;
     167             :         }
     168             : 
     169           0 :         if (replace->prev) {
     170           0 :                 entry->prev = replace->prev;
     171           0 :                 replace->prev->next = entry;
     172             :         } else {
     173           0 :                 entry->prev = NULL;
     174           0 :                 list->head = entry;
     175             :         }
     176             : 
     177           0 :         as_filter_free(replace);
     178           0 : }
     179             : 
     180           0 : static void as_list_filter_add(struct as_list *aslist,
     181             :                                struct as_filter *asfilter)
     182             : {
     183           0 :         struct as_filter *point;
     184           0 :         struct as_filter *replace;
     185             : 
     186           0 :         if (aslist->tail && asfilter->seq > aslist->tail->seq)
     187             :                 point = NULL;
     188             :         else {
     189           0 :                 replace = bgp_aslist_seq_check(aslist, asfilter->seq);
     190           0 :                 if (replace) {
     191           0 :                         as_filter_entry_replace(aslist, replace, asfilter);
     192           0 :                         goto hook;
     193             :                 }
     194             : 
     195             :                 /* Check insert point. */
     196           0 :                 for (point = aslist->head; point; point = point->next)
     197           0 :                         if (point->seq >= asfilter->seq)
     198             :                                 break;
     199             :         }
     200             : 
     201           0 :         asfilter->next = point;
     202             : 
     203           0 :         if (point) {
     204           0 :                 if (point->prev)
     205           0 :                         point->prev->next = asfilter;
     206             :                 else
     207           0 :                         aslist->head = asfilter;
     208             : 
     209           0 :                 asfilter->prev = point->prev;
     210           0 :                 point->prev = asfilter;
     211             :         } else {
     212           0 :                 if (aslist->tail)
     213           0 :                         aslist->tail->next = asfilter;
     214             :                 else
     215           0 :                         aslist->head = asfilter;
     216             : 
     217           0 :                 asfilter->prev = aslist->tail;
     218           0 :                 aslist->tail = asfilter;
     219             :         }
     220             : 
     221           0 : hook:
     222             :         /* Run hook function. */
     223           0 :         if (as_list_master.add_hook)
     224           0 :                 (*as_list_master.add_hook)(aslist->name);
     225           0 : }
     226             : 
     227             : /* Lookup as_list from list of as_list by name. */
     228           0 : struct as_list *as_list_lookup(const char *name)
     229             : {
     230           0 :         struct as_list *aslist;
     231             : 
     232           0 :         if (name == NULL)
     233             :                 return NULL;
     234             : 
     235           0 :         for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
     236           0 :                 if (strcmp(aslist->name, name) == 0)
     237           0 :                         return aslist;
     238             : 
     239             :         return NULL;
     240             : }
     241             : 
     242           0 : static struct as_list *as_list_new(void)
     243             : {
     244           0 :         return XCALLOC(MTYPE_AS_LIST, sizeof(struct as_list));
     245             : }
     246             : 
     247           0 : static void as_list_free(struct as_list *aslist)
     248             : {
     249           0 :         XFREE(MTYPE_AS_STR, aslist->name);
     250           0 :         XFREE(MTYPE_AS_LIST, aslist);
     251           0 : }
     252             : 
     253             : /* Insert new AS list to list of as_list.  Each as_list is sorted by
     254             :    the name. */
     255           0 : static struct as_list *as_list_insert(const char *name)
     256             : {
     257           0 :         struct as_list *aslist;
     258           0 :         struct as_list *point;
     259           0 :         struct as_list_list *list;
     260             : 
     261             :         /* Allocate new access_list and copy given name. */
     262           0 :         aslist = as_list_new();
     263           0 :         aslist->name = XSTRDUP(MTYPE_AS_STR, name);
     264           0 :         assert(aslist->name);
     265             : 
     266             :         /* Set access_list to string list. */
     267           0 :         list = &as_list_master.str;
     268             : 
     269             :         /* Set point to insertion point. */
     270           0 :         for (point = list->head; point; point = point->next)
     271           0 :                 if (strcmp(point->name, name) >= 0)
     272             :                         break;
     273             : 
     274             :         /* In case of this is the first element of master. */
     275           0 :         if (list->head == NULL) {
     276           0 :                 list->head = list->tail = aslist;
     277           0 :                 return aslist;
     278             :         }
     279             : 
     280             :         /* In case of insertion is made at the tail of access_list. */
     281           0 :         if (point == NULL) {
     282           0 :                 aslist->prev = list->tail;
     283           0 :                 list->tail->next = aslist;
     284           0 :                 list->tail = aslist;
     285           0 :                 return aslist;
     286             :         }
     287             : 
     288             :         /* In case of insertion is made at the head of access_list. */
     289           0 :         if (point == list->head) {
     290           0 :                 aslist->next = list->head;
     291           0 :                 list->head->prev = aslist;
     292           0 :                 list->head = aslist;
     293           0 :                 return aslist;
     294             :         }
     295             : 
     296             :         /* Insertion is made at middle of the access_list. */
     297           0 :         aslist->next = point;
     298           0 :         aslist->prev = point->prev;
     299             : 
     300           0 :         if (point->prev)
     301           0 :                 point->prev->next = aslist;
     302           0 :         point->prev = aslist;
     303             : 
     304           0 :         return aslist;
     305             : }
     306             : 
     307           0 : static struct as_list *as_list_get(const char *name)
     308             : {
     309           0 :         struct as_list *aslist;
     310             : 
     311           0 :         aslist = as_list_lookup(name);
     312           0 :         if (aslist == NULL)
     313           0 :                 aslist = as_list_insert(name);
     314             : 
     315           0 :         return aslist;
     316             : }
     317             : 
     318           0 : static const char *filter_type_str(enum as_filter_type type)
     319             : {
     320           0 :         switch (type) {
     321             :         case AS_FILTER_PERMIT:
     322             :                 return "permit";
     323           0 :         case AS_FILTER_DENY:
     324           0 :                 return "deny";
     325           0 :         default:
     326           0 :                 return "";
     327             :         }
     328             : }
     329             : 
     330           0 : static void as_list_delete(struct as_list *aslist)
     331             : {
     332           0 :         struct as_list_list *list;
     333           0 :         struct as_filter *filter, *next;
     334             : 
     335           0 :         for (filter = aslist->head; filter; filter = next) {
     336           0 :                 next = filter->next;
     337           0 :                 as_filter_free(filter);
     338             :         }
     339             : 
     340           0 :         list = &as_list_master.str;
     341             : 
     342           0 :         if (aslist->next)
     343           0 :                 aslist->next->prev = aslist->prev;
     344             :         else
     345           0 :                 list->tail = aslist->prev;
     346             : 
     347           0 :         if (aslist->prev)
     348           0 :                 aslist->prev->next = aslist->next;
     349             :         else
     350           0 :                 list->head = aslist->next;
     351             : 
     352           0 :         as_list_free(aslist);
     353           0 : }
     354             : 
     355           0 : static bool as_list_empty(struct as_list *aslist)
     356             : {
     357           0 :         return aslist->head == NULL && aslist->tail == NULL;
     358             : }
     359             : 
     360           0 : static void as_list_filter_delete(struct as_list *aslist,
     361             :                                   struct as_filter *asfilter)
     362             : {
     363           0 :         char *name = XSTRDUP(MTYPE_AS_STR, aslist->name);
     364             : 
     365           0 :         if (asfilter->next)
     366           0 :                 asfilter->next->prev = asfilter->prev;
     367             :         else
     368           0 :                 aslist->tail = asfilter->prev;
     369             : 
     370           0 :         if (asfilter->prev)
     371           0 :                 asfilter->prev->next = asfilter->next;
     372             :         else
     373           0 :                 aslist->head = asfilter->next;
     374             : 
     375           0 :         as_filter_free(asfilter);
     376             : 
     377             :         /* If access_list becomes empty delete it from access_master. */
     378           0 :         if (as_list_empty(aslist))
     379           0 :                 as_list_delete(aslist);
     380             : 
     381             :         /* Run hook function. */
     382           0 :         if (as_list_master.delete_hook)
     383           0 :                 (*as_list_master.delete_hook)(name);
     384           0 :         XFREE(MTYPE_AS_STR, name);
     385           0 : }
     386             : 
     387           0 : static bool as_filter_match(struct as_filter *asfilter, struct aspath *aspath)
     388             : {
     389           0 :         return bgp_regexec(asfilter->reg, aspath) != REG_NOMATCH;
     390             : }
     391             : 
     392             : /* Apply AS path filter to AS. */
     393           0 : enum as_filter_type as_list_apply(struct as_list *aslist, void *object)
     394             : {
     395           0 :         struct as_filter *asfilter;
     396           0 :         struct aspath *aspath;
     397             : 
     398           0 :         aspath = (struct aspath *)object;
     399             : 
     400           0 :         if (aslist == NULL)
     401             :                 return AS_FILTER_DENY;
     402             : 
     403           0 :         for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
     404           0 :                 if (as_filter_match(asfilter, aspath))
     405           0 :                         return asfilter->type;
     406             :         }
     407             :         return AS_FILTER_DENY;
     408             : }
     409             : 
     410             : /* Add hook function. */
     411          68 : void as_list_add_hook(void (*func)(char *))
     412             : {
     413          68 :         as_list_master.add_hook = func;
     414          68 : }
     415             : 
     416             : /* Delete hook function. */
     417          68 : void as_list_delete_hook(void (*func)(const char *))
     418             : {
     419          68 :         as_list_master.delete_hook = func;
     420          68 : }
     421             : 
     422           0 : static bool as_list_dup_check(struct as_list *aslist, struct as_filter *new)
     423             : {
     424           0 :         struct as_filter *asfilter;
     425             : 
     426           0 :         for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
     427           0 :                 if (asfilter->type == new->type
     428           0 :                     && strcmp(asfilter->reg_str, new->reg_str) == 0)
     429             :                         return true;
     430             :         }
     431             :         return false;
     432             : }
     433             : 
     434           0 : bool config_bgp_aspath_validate(const char *regstr)
     435             : {
     436           0 :         char valid_chars[] = "1234567890_^|[,{}() ]$*+.?-\\";
     437             : 
     438           0 :         if (strspn(regstr, valid_chars) == strlen(regstr))
     439           0 :                 return true;
     440             :         return false;
     441             : }
     442             : 
     443           0 : DEFUN(as_path, bgp_as_path_cmd,
     444             :       "bgp as-path access-list AS_PATH_FILTER_NAME [seq (0-4294967295)] <deny|permit> LINE...",
     445             :       BGP_STR
     446             :       "BGP autonomous system path filter\n"
     447             :       "Specify an access list name\n"
     448             :       "Regular expression access list name\n"
     449             :       "Sequence number of an entry\n"
     450             :       "Sequence number\n"
     451             :       "Specify packets to reject\n"
     452             :       "Specify packets to forward\n"
     453             :       "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
     454             : {
     455           0 :         int idx = 0;
     456           0 :         enum as_filter_type type;
     457           0 :         struct as_filter *asfilter;
     458           0 :         struct as_list *aslist;
     459           0 :         regex_t *regex;
     460           0 :         char *regstr;
     461           0 :         int64_t seqnum = ASPATH_SEQ_NUMBER_AUTO;
     462             : 
     463             :         /* Retrieve access list name */
     464           0 :         argv_find(argv, argc, "AS_PATH_FILTER_NAME", &idx);
     465           0 :         char *alname = argv[idx]->arg;
     466             : 
     467           0 :         if (argv_find(argv, argc, "(0-4294967295)", &idx))
     468           0 :                 seqnum = (int64_t)atol(argv[idx]->arg);
     469             : 
     470             :         /* Check the filter type. */
     471           0 :         type = argv_find(argv, argc, "deny", &idx) ? AS_FILTER_DENY
     472           0 :                                                    : AS_FILTER_PERMIT;
     473             : 
     474             :         /* Check AS path regex. */
     475           0 :         argv_find(argv, argc, "LINE", &idx);
     476           0 :         regstr = argv_concat(argv, argc, idx);
     477             : 
     478           0 :         regex = bgp_regcomp(regstr);
     479           0 :         if (!regex) {
     480           0 :                 vty_out(vty, "can't compile regexp %s\n", regstr);
     481           0 :                 XFREE(MTYPE_TMP, regstr);
     482           0 :                 return CMD_WARNING_CONFIG_FAILED;
     483             :         }
     484             : 
     485           0 :         if (!config_bgp_aspath_validate(regstr)) {
     486           0 :                 vty_out(vty, "Invalid character in as-path access-list %s\n",
     487             :                         regstr);
     488           0 :                 XFREE(MTYPE_TMP, regstr);
     489           0 :                 return CMD_WARNING_CONFIG_FAILED;
     490             :         }
     491             : 
     492           0 :         asfilter = as_filter_make(regex, regstr, type);
     493             : 
     494           0 :         XFREE(MTYPE_TMP, regstr);
     495             : 
     496             :         /* Install new filter to the access_list. */
     497           0 :         aslist = as_list_get(alname);
     498             : 
     499           0 :         if (seqnum == ASPATH_SEQ_NUMBER_AUTO)
     500           0 :                 seqnum = bgp_alist_new_seq_get(aslist);
     501             : 
     502           0 :         asfilter->seq = seqnum;
     503             : 
     504           0 :         /* Duplicate insertion check. */;
     505           0 :         if (as_list_dup_check(aslist, asfilter))
     506           0 :                 as_filter_free(asfilter);
     507             :         else
     508           0 :                 as_list_filter_add(aslist, asfilter);
     509             : 
     510             :         return CMD_SUCCESS;
     511             : }
     512             : 
     513           0 : DEFUN(no_as_path, no_bgp_as_path_cmd,
     514             :       "no bgp as-path access-list AS_PATH_FILTER_NAME [seq (0-4294967295)] <deny|permit> LINE...",
     515             :       NO_STR
     516             :       BGP_STR
     517             :       "BGP autonomous system path filter\n"
     518             :       "Specify an access list name\n"
     519             :       "Regular expression access list name\n"
     520             :       "Sequence number of an entry\n"
     521             :       "Sequence number\n"
     522             :       "Specify packets to reject\n"
     523             :       "Specify packets to forward\n"
     524             :       "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
     525             : {
     526           0 :         int idx = 0;
     527           0 :         enum as_filter_type type;
     528           0 :         struct as_filter *asfilter;
     529           0 :         struct as_list *aslist;
     530           0 :         char *regstr;
     531           0 :         regex_t *regex;
     532             : 
     533           0 :         char *aslistname =
     534           0 :                 argv_find(argv, argc, "AS_PATH_FILTER_NAME", &idx) ? argv[idx]->arg : NULL;
     535             : 
     536             :         /* Lookup AS list from AS path list. */
     537           0 :         aslist = as_list_lookup(aslistname);
     538           0 :         if (aslist == NULL) {
     539           0 :                 vty_out(vty, "bgp as-path access-list %s doesn't exist\n",
     540             :                         aslistname);
     541           0 :                 return CMD_WARNING_CONFIG_FAILED;
     542             :         }
     543             : 
     544             :         /* Check the filter type. */
     545           0 :         if (argv_find(argv, argc, "permit", &idx))
     546             :                 type = AS_FILTER_PERMIT;
     547           0 :         else if (argv_find(argv, argc, "deny", &idx))
     548             :                 type = AS_FILTER_DENY;
     549             :         else {
     550           0 :                 vty_out(vty, "filter type must be [permit|deny]\n");
     551           0 :                 return CMD_WARNING_CONFIG_FAILED;
     552             :         }
     553             : 
     554             :         /* Compile AS path. */
     555           0 :         argv_find(argv, argc, "LINE", &idx);
     556           0 :         regstr = argv_concat(argv, argc, idx);
     557             : 
     558           0 :         if (!config_bgp_aspath_validate(regstr)) {
     559           0 :                 vty_out(vty, "Invalid character in as-path access-list %s\n",
     560             :                         regstr);
     561           0 :                 return CMD_WARNING_CONFIG_FAILED;
     562             :         }
     563             : 
     564           0 :         regex = bgp_regcomp(regstr);
     565           0 :         if (!regex) {
     566           0 :                 vty_out(vty, "can't compile regexp %s\n", regstr);
     567           0 :                 XFREE(MTYPE_TMP, regstr);
     568           0 :                 return CMD_WARNING_CONFIG_FAILED;
     569             :         }
     570             : 
     571             :         /* Lookup asfilter. */
     572           0 :         asfilter = as_filter_lookup(aslist, regstr, type);
     573             : 
     574           0 :         bgp_regex_free(regex);
     575             : 
     576           0 :         if (asfilter == NULL) {
     577           0 :                 vty_out(vty, "Regex entered %s does not exist\n", regstr);
     578           0 :                 XFREE(MTYPE_TMP, regstr);
     579           0 :                 return CMD_WARNING_CONFIG_FAILED;
     580             :         }
     581             : 
     582           0 :         XFREE(MTYPE_TMP, regstr);
     583             : 
     584           0 :         as_list_filter_delete(aslist, asfilter);
     585             : 
     586           0 :         return CMD_SUCCESS;
     587             : }
     588             : 
     589           0 : DEFUN (no_as_path_all,
     590             :        no_bgp_as_path_all_cmd,
     591             :        "no bgp as-path access-list AS_PATH_FILTER_NAME",
     592             :        NO_STR
     593             :        BGP_STR
     594             :        "BGP autonomous system path filter\n"
     595             :        "Specify an access list name\n"
     596             :        "Regular expression access list name\n")
     597             : {
     598           0 :         int idx_word = 4;
     599           0 :         struct as_list *aslist;
     600             : 
     601           0 :         aslist = as_list_lookup(argv[idx_word]->arg);
     602           0 :         if (aslist == NULL) {
     603           0 :                 vty_out(vty, "bgp as-path access-list %s doesn't exist\n",
     604             :                         argv[idx_word]->arg);
     605           0 :                 return CMD_WARNING_CONFIG_FAILED;
     606             :         }
     607             : 
     608           0 :         as_list_delete(aslist);
     609             : 
     610             :         /* Run hook function. */
     611           0 :         if (as_list_master.delete_hook)
     612           0 :                 (*as_list_master.delete_hook)(argv[idx_word]->arg);
     613             : 
     614             :         return CMD_SUCCESS;
     615             : }
     616             : 
     617           0 : static void as_list_show(struct vty *vty, struct as_list *aslist,
     618             :                          json_object *json)
     619             : {
     620           0 :         struct as_filter *asfilter;
     621           0 :         json_object *json_aslist = NULL;
     622             : 
     623           0 :         if (json) {
     624           0 :                 json_aslist = json_object_new_array();
     625           0 :                 json_object_object_add(json, aslist->name, json_aslist);
     626             :         } else
     627           0 :                 vty_out(vty, "AS path access list %s\n", aslist->name);
     628             : 
     629           0 :         for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
     630           0 :                 if (json) {
     631           0 :                         json_object *json_asfilter = json_object_new_object();
     632             : 
     633           0 :                         json_object_int_add(json_asfilter, "sequenceNumber",
     634             :                                             asfilter->seq);
     635           0 :                         json_object_string_add(json_asfilter, "type",
     636             :                                                filter_type_str(asfilter->type));
     637           0 :                         json_object_string_add(json_asfilter, "regExp",
     638           0 :                                                asfilter->reg_str);
     639             : 
     640           0 :                         json_object_array_add(json_aslist, json_asfilter);
     641             :                 } else
     642           0 :                         vty_out(vty, "    %s %s\n",
     643             :                                 filter_type_str(asfilter->type),
     644             :                                 asfilter->reg_str);
     645             :         }
     646           0 : }
     647             : 
     648           0 : static void as_list_show_all(struct vty *vty, json_object *json)
     649             : {
     650           0 :         struct as_list *aslist;
     651             : 
     652           0 :         for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
     653           0 :                 as_list_show(vty, aslist, json);
     654           0 : }
     655             : 
     656           0 : DEFUN (show_as_path_access_list,
     657             :        show_bgp_as_path_access_list_cmd,
     658             :        "show bgp as-path-access-list AS_PATH_FILTER_NAME [json]",
     659             :        SHOW_STR
     660             :        BGP_STR
     661             :        "List AS path access lists\n"
     662             :        "AS path access list name\n"
     663             :        JSON_STR)
     664             : {
     665           0 :         int idx_word = 3;
     666           0 :         struct as_list *aslist;
     667           0 :         bool uj = use_json(argc, argv);
     668           0 :         json_object *json = NULL;
     669             : 
     670           0 :         if (uj)
     671           0 :                 json = json_object_new_object();
     672             : 
     673           0 :         aslist = as_list_lookup(argv[idx_word]->arg);
     674           0 :         if (aslist)
     675           0 :                 as_list_show(vty, aslist, json);
     676             : 
     677           0 :         if (uj)
     678           0 :                 vty_json(vty, json);
     679             : 
     680           0 :         return CMD_SUCCESS;
     681             : }
     682             : 
     683             : ALIAS (show_as_path_access_list,
     684             :        show_ip_as_path_access_list_cmd,
     685             :        "show ip as-path-access-list AS_PATH_FILTER_NAME [json]",
     686             :        SHOW_STR
     687             :        IP_STR
     688             :        "List AS path access lists\n"
     689             :        "AS path access list name\n"
     690             :        JSON_STR)
     691             : 
     692           0 : DEFUN (show_as_path_access_list_all,
     693             :        show_bgp_as_path_access_list_all_cmd,
     694             :        "show bgp as-path-access-list [json]",
     695             :        SHOW_STR
     696             :        BGP_STR
     697             :        "List AS path access lists\n"
     698             :        JSON_STR)
     699             : {
     700           0 :         bool uj = use_json(argc, argv);
     701           0 :         json_object *json = NULL;
     702             : 
     703           0 :         if (uj)
     704           0 :                 json = json_object_new_object();
     705             : 
     706           0 :         as_list_show_all(vty, json);
     707             : 
     708           0 :         if (uj)
     709           0 :                 vty_json(vty, json);
     710             : 
     711           0 :         return CMD_SUCCESS;
     712             : }
     713             : 
     714             : ALIAS (show_as_path_access_list_all,
     715             :        show_ip_as_path_access_list_all_cmd,
     716             :        "show ip as-path-access-list [json]",
     717             :        SHOW_STR
     718             :        IP_STR
     719             :        "List AS path access lists\n"
     720             :        JSON_STR)
     721             : 
     722           0 : static int config_write_as_list(struct vty *vty)
     723             : {
     724           0 :         struct as_list *aslist;
     725           0 :         struct as_filter *asfilter;
     726           0 :         int write = 0;
     727             : 
     728           0 :         for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
     729           0 :                 for (asfilter = aslist->head; asfilter;
     730           0 :                      asfilter = asfilter->next) {
     731           0 :                         vty_out(vty,
     732             :                                 "bgp as-path access-list %s seq %" PRId64
     733             :                                 " %s %s\n",
     734             :                                 aslist->name, asfilter->seq,
     735             :                                 filter_type_str(asfilter->type),
     736             :                                 asfilter->reg_str);
     737           0 :                         write++;
     738             :                 }
     739           0 :         return write;
     740             : }
     741             : 
     742             : static int config_write_as_list(struct vty *vty);
     743             : static struct cmd_node as_list_node = {
     744             :         .name = "as list",
     745             :         .node = AS_LIST_NODE,
     746             :         .prompt = "",
     747             :         .config_write = config_write_as_list,
     748             : };
     749             : 
     750           0 : static void bgp_aspath_filter_cmd_completion(vector comps,
     751             :                                              struct cmd_token *token)
     752             : {
     753           0 :         struct as_list *aslist;
     754             : 
     755           0 :         for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
     756           0 :                 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, aslist->name));
     757           0 : }
     758             : 
     759             : static const struct cmd_variable_handler aspath_filter_handlers[] = {
     760             :         {.tokenname = "AS_PATH_FILTER_NAME",
     761             :          .completions = bgp_aspath_filter_cmd_completion},
     762             :         {.completions = NULL}};
     763             : 
     764             : /* Register functions. */
     765          34 : void bgp_filter_init(void)
     766             : {
     767          34 :         install_node(&as_list_node);
     768             : 
     769          34 :         install_element(CONFIG_NODE, &bgp_as_path_cmd);
     770          34 :         install_element(CONFIG_NODE, &no_bgp_as_path_cmd);
     771          34 :         install_element(CONFIG_NODE, &no_bgp_as_path_all_cmd);
     772             : 
     773          34 :         install_element(VIEW_NODE, &show_bgp_as_path_access_list_cmd);
     774          34 :         install_element(VIEW_NODE, &show_ip_as_path_access_list_cmd);
     775          34 :         install_element(VIEW_NODE, &show_bgp_as_path_access_list_all_cmd);
     776          34 :         install_element(VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
     777             : 
     778          34 :         cmd_variable_handler_register(aspath_filter_handlers);
     779          34 : }
     780             : 
     781          34 : void bgp_filter_reset(void)
     782             : {
     783          34 :         struct as_list *aslist;
     784          34 :         struct as_list *next;
     785             : 
     786          34 :         for (aslist = as_list_master.str.head; aslist; aslist = next) {
     787           0 :                 next = aslist->next;
     788           0 :                 as_list_delete(aslist);
     789             :         }
     790             : 
     791          34 :         assert(as_list_master.str.head == NULL);
     792          34 :         assert(as_list_master.str.tail == NULL);
     793          34 : }

Generated by: LCOV version v1.16-topotato