]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_filter.c
Merge pull request #3394 from karamalla0406/frr3360
[mirror_frr.git] / bgpd / bgp_filter.c
index 0de2663dd4c7cd2221ac6050da146c21ecba466a..1ccb8fb245191b77699da7f8d38590a0bbc98639 100644 (file)
@@ -1,22 +1,22 @@
 /* AS path filter list.
  Copyright (C) 1999 Kunihiro Ishiguro
-
-This file is part of GNU Zebra.
-
-GNU Zebra is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-GNU Zebra is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Zebra; see the file COPYING.  If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
* Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
 
 #include <zebra.h>
 
@@ -33,522 +33,577 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "bgpd/bgp_filter.h"
 
 /* List of AS filter list. */
-struct as_list_list
-{
-  struct as_list *head;
-  struct as_list *tail;
+struct as_list_list {
+       struct as_list *head;
+       struct as_list *tail;
 };
 
 /* AS path filter master. */
-struct as_list_master
-{
-  /* List of access_list which name is number. */
-  struct as_list_list num;
+struct as_list_master {
+       /* List of access_list which name is number. */
+       struct as_list_list num;
 
-  /* List of access_list which name is string. */
-  struct as_list_list str;
+       /* List of access_list which name is string. */
+       struct as_list_list str;
 
-  /* Hook function which is executed when new access_list is added. */
-  void (*add_hook) (char *);
+       /* Hook function which is executed when new access_list is added. */
+       void (*add_hook)(char *);
 
-  /* Hook function which is executed when access_list is deleted. */
-  void (*delete_hook) (const char *);
+       /* Hook function which is executed when access_list is deleted. */
+       void (*delete_hook)(const char *);
 };
 
 /* Element of AS path filter. */
-struct as_filter
-{
-  struct as_filter *next;
-  struct as_filter *prev;
+struct as_filter {
+       struct as_filter *next;
+       struct as_filter *prev;
 
-  enum as_filter_type type;
+       enum as_filter_type type;
 
-  regex_t *reg;
-  char *reg_str;
+       regex_t *reg;
+       char *reg_str;
 };
 
 /* AS path filter list. */
-struct as_list
-{
-  char *name;
+struct as_list {
+       char *name;
 
-  enum access_type type;
+       enum access_type type;
 
-  struct as_list *next;
-  struct as_list *prev;
+       struct as_list *next;
+       struct as_list *prev;
 
-  struct as_filter *head;
-  struct as_filter *tail;
+       struct as_filter *head;
+       struct as_filter *tail;
 };
 
-/* ip as-path access-list 10 permit AS1. */
+/* as-path access-list 10 permit AS1. */
 
-static struct as_list_master as_list_master =
-{
-  {NULL, NULL},
-  {NULL, NULL},
-  NULL,
-  NULL
-};
+static struct as_list_master as_list_master = {{NULL, NULL},
+                                              {NULL, NULL},
+                                              NULL,
+                                              NULL};
 
 /* Allocate new AS filter. */
-static struct as_filter *
-as_filter_new (void)
+static struct as_filter *as_filter_new(void)
 {
-  return XCALLOC (MTYPE_AS_FILTER, sizeof (struct as_filter));
+       return XCALLOC(MTYPE_AS_FILTER, sizeof(struct as_filter));
 }
 
 /* Free allocated AS filter. */
-static void
-as_filter_free (struct as_filter *asfilter)
+static void as_filter_free(struct as_filter *asfilter)
 {
-  if (asfilter->reg)
-    bgp_regex_free (asfilter->reg);
-  if (asfilter->reg_str)
-    XFREE (MTYPE_AS_FILTER_STR, asfilter->reg_str);
-  XFREE (MTYPE_AS_FILTER, asfilter);
+       if (asfilter->reg)
+               bgp_regex_free(asfilter->reg);
+       if (asfilter->reg_str)
+               XFREE(MTYPE_AS_FILTER_STR, asfilter->reg_str);
+       XFREE(MTYPE_AS_FILTER, asfilter);
 }
 
 /* Make new AS filter. */
-static struct as_filter *
-as_filter_make (regex_t *reg, const char *reg_str, enum as_filter_type type)
+static struct as_filter *as_filter_make(regex_t *reg, const char *reg_str,
+                                       enum as_filter_type type)
 {
-  struct as_filter *asfilter;
+       struct as_filter *asfilter;
 
-  asfilter = as_filter_new ();
-  asfilter->reg = reg;
-  asfilter->type = type;
-  asfilter->reg_str = XSTRDUP (MTYPE_AS_FILTER_STR, reg_str);
+       asfilter = as_filter_new();
+       asfilter->reg = reg;
+       asfilter->type = type;
+       asfilter->reg_str = XSTRDUP(MTYPE_AS_FILTER_STR, reg_str);
 
-  return asfilter;
+       return asfilter;
 }
 
-static struct as_filter *
-as_filter_lookup (struct as_list *aslist, const char *reg_str,
-                 enum as_filter_type type)
+static struct as_filter *as_filter_lookup(struct as_list *aslist,
+                                         const char *reg_str,
+                                         enum as_filter_type type)
 {
-  struct as_filter *asfilter;
+       struct as_filter *asfilter;
 
-  for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
-    if (strcmp (reg_str, asfilter->reg_str) == 0)
-      return asfilter;
-  return NULL;
+       for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
+               if (strcmp(reg_str, asfilter->reg_str) == 0)
+                       return asfilter;
+       return NULL;
 }
 
-static void
-as_list_filter_add (struct as_list *aslist, struct as_filter *asfilter)
+static void as_list_filter_add(struct as_list *aslist,
+                              struct as_filter *asfilter)
 {
-  asfilter->next = NULL;
-  asfilter->prev = aslist->tail;
+       asfilter->next = NULL;
+       asfilter->prev = aslist->tail;
 
-  if (aslist->tail)
-    aslist->tail->next = asfilter;
-  else
-    aslist->head = asfilter;
-  aslist->tail = asfilter;
-
-  /* Run hook function. */
-  if (as_list_master.add_hook)
-    (*as_list_master.add_hook) (aslist->name);
+       if (aslist->tail)
+               aslist->tail->next = asfilter;
+       else
+               aslist->head = asfilter;
+       aslist->tail = asfilter;
 
+       /* Run hook function. */
+       if (as_list_master.add_hook)
+               (*as_list_master.add_hook)(aslist->name);
 }
 
 /* Lookup as_list from list of as_list by name. */
-struct as_list *
-as_list_lookup (const char *name)
+struct as_list *as_list_lookup(const char *name)
 {
-  struct as_list *aslist;
+       struct as_list *aslist;
 
-  if (name == NULL)
-    return NULL;
+       if (name == NULL)
+               return NULL;
 
-  for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
-    if (strcmp (aslist->name, name) == 0)
-      return aslist;
+       for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
+               if (strcmp(aslist->name, name) == 0)
+                       return aslist;
 
-  for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
-    if (strcmp (aslist->name, name) == 0)
-      return aslist;
+       for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
+               if (strcmp(aslist->name, name) == 0)
+                       return aslist;
 
-  return NULL;
+       return NULL;
 }
 
-static struct as_list *
-as_list_new (void)
+static struct as_list *as_list_new(void)
 {
-  return XCALLOC (MTYPE_AS_LIST, sizeof (struct as_list));
+       return XCALLOC(MTYPE_AS_LIST, sizeof(struct as_list));
 }
 
-static void
-as_list_free (struct as_list *aslist)
+static void as_list_free(struct as_list *aslist)
 {
-  if (aslist->name)
-    {
-      XFREE(MTYPE_AS_STR, aslist->name);
-      aslist->name = NULL;
-    }
-  XFREE (MTYPE_AS_LIST, aslist);
+       if (aslist->name) {
+               XFREE(MTYPE_AS_STR, aslist->name);
+               aslist->name = NULL;
+       }
+       XFREE(MTYPE_AS_LIST, aslist);
 }
 
 /* Insert new AS list to list of as_list.  Each as_list is sorted by
    the name. */
-static struct as_list *
-as_list_insert (const char *name)
-{
-  size_t i;
-  long number;
-  struct as_list *aslist;
-  struct as_list *point;
-  struct as_list_list *list;
-
-  /* Allocate new access_list and copy given name. */
-  aslist = as_list_new ();
-  aslist->name = XSTRDUP(MTYPE_AS_STR, name);
-  assert (aslist->name);
-
-  /* If name is made by all digit character.  We treat it as
-     number. */
-  for (number = 0, i = 0; i < strlen (name); i++)
-    {
-      if (isdigit ((int) name[i]))
-       number = (number * 10) + (name[i] - '0');
-      else
-       break;
-    }
-
-  /* In case of name is all digit character */
-  if (i == strlen (name))
-    {
-      aslist->type = ACCESS_TYPE_NUMBER;
-
-      /* Set access_list to number list. */
-      list = &as_list_master.num;
-
-      for (point = list->head; point; point = point->next)
-       if (atol (point->name) >= number)
-         break;
-    }
-  else
-    {
-      aslist->type = ACCESS_TYPE_STRING;
-
-      /* Set access_list to string list. */
-      list = &as_list_master.str;
-  
-      /* Set point to insertion point. */
-      for (point = list->head; point; point = point->next)
-       if (strcmp (point->name, name) >= 0)
-         break;
-    }
-
-  /* In case of this is the first element of master. */
-  if (list->head == NULL)
-    {
-      list->head = list->tail = aslist;
-      return aslist;
-    }
-
-  /* In case of insertion is made at the tail of access_list. */
-  if (point == NULL)
-    {
-      aslist->prev = list->tail;
-      list->tail->next = aslist;
-      list->tail = aslist;
-      return aslist;
-    }
-
-  /* In case of insertion is made at the head of access_list. */
-  if (point == list->head)
-    {
-      aslist->next = list->head;
-      list->head->prev = aslist;
-      list->head = aslist;
-      return aslist;
-    }
-
-  /* Insertion is made at middle of the access_list. */
-  aslist->next = point;
-  aslist->prev = point->prev;
-
-  if (point->prev)
-    point->prev->next = aslist;
-  point->prev = aslist;
-
-  return aslist;
+static struct as_list *as_list_insert(const char *name)
+{
+       size_t i;
+       long number;
+       struct as_list *aslist;
+       struct as_list *point;
+       struct as_list_list *list;
+
+       /* Allocate new access_list and copy given name. */
+       aslist = as_list_new();
+       aslist->name = XSTRDUP(MTYPE_AS_STR, name);
+       assert(aslist->name);
+
+       /* If name is made by all digit character.  We treat it as
+          number. */
+       for (number = 0, i = 0; i < strlen(name); i++) {
+               if (isdigit((int)name[i]))
+                       number = (number * 10) + (name[i] - '0');
+               else
+                       break;
+       }
+
+       /* In case of name is all digit character */
+       if (i == strlen(name)) {
+               aslist->type = ACCESS_TYPE_NUMBER;
+
+               /* Set access_list to number list. */
+               list = &as_list_master.num;
+
+               for (point = list->head; point; point = point->next)
+                       if (atol(point->name) >= number)
+                               break;
+       } else {
+               aslist->type = ACCESS_TYPE_STRING;
+
+               /* Set access_list to string list. */
+               list = &as_list_master.str;
+
+               /* Set point to insertion point. */
+               for (point = list->head; point; point = point->next)
+                       if (strcmp(point->name, name) >= 0)
+                               break;
+       }
+
+       /* In case of this is the first element of master. */
+       if (list->head == NULL) {
+               list->head = list->tail = aslist;
+               return aslist;
+       }
+
+       /* In case of insertion is made at the tail of access_list. */
+       if (point == NULL) {
+               aslist->prev = list->tail;
+               list->tail->next = aslist;
+               list->tail = aslist;
+               return aslist;
+       }
+
+       /* In case of insertion is made at the head of access_list. */
+       if (point == list->head) {
+               aslist->next = list->head;
+               list->head->prev = aslist;
+               list->head = aslist;
+               return aslist;
+       }
+
+       /* Insertion is made at middle of the access_list. */
+       aslist->next = point;
+       aslist->prev = point->prev;
+
+       if (point->prev)
+               point->prev->next = aslist;
+       point->prev = aslist;
+
+       return aslist;
 }
 
-static struct as_list *
-as_list_get (const char *name)
+static struct as_list *as_list_get(const char *name)
 {
-  struct as_list *aslist;
+       struct as_list *aslist;
 
-  aslist = as_list_lookup (name);
-  if (aslist == NULL)
-    aslist = as_list_insert (name);
+       aslist = as_list_lookup(name);
+       if (aslist == NULL)
+               aslist = as_list_insert(name);
 
-  return aslist;
+       return aslist;
 }
 
-static const char *
-filter_type_str (enum as_filter_type type)
+static const char *filter_type_str(enum as_filter_type type)
 {
-  switch (type)
-    {
-    case AS_FILTER_PERMIT:
-      return "permit";
-    case AS_FILTER_DENY:
-      return "deny";
-    default:
-      return "";
-    }
+       switch (type) {
+       case AS_FILTER_PERMIT:
+               return "permit";
+       case AS_FILTER_DENY:
+               return "deny";
+       default:
+               return "";
+       }
 }
 
-static void
-as_list_delete (struct as_list *aslist)
+static void as_list_delete(struct as_list *aslist)
 {
-  struct as_list_list *list;
-  struct as_filter *filter, *next;
-
-  for (filter = aslist->head; filter; filter = next)
-    {
-      next = filter->next;
-      as_filter_free (filter);
-    }
-
-  if (aslist->type == ACCESS_TYPE_NUMBER)
-    list = &as_list_master.num;
-  else
-    list = &as_list_master.str;
-
-  if (aslist->next)
-    aslist->next->prev = aslist->prev;
-  else
-    list->tail = aslist->prev;
-
-  if (aslist->prev)
-    aslist->prev->next = aslist->next;
-  else
-    list->head = aslist->next;
-
-  as_list_free (aslist);
+       struct as_list_list *list;
+       struct as_filter *filter, *next;
+
+       for (filter = aslist->head; filter; filter = next) {
+               next = filter->next;
+               as_filter_free(filter);
+       }
+
+       if (aslist->type == ACCESS_TYPE_NUMBER)
+               list = &as_list_master.num;
+       else
+               list = &as_list_master.str;
+
+       if (aslist->next)
+               aslist->next->prev = aslist->prev;
+       else
+               list->tail = aslist->prev;
+
+       if (aslist->prev)
+               aslist->prev->next = aslist->next;
+       else
+               list->head = aslist->next;
+
+       as_list_free(aslist);
 }
 
-static int
-as_list_empty (struct as_list *aslist)
+static int as_list_empty(struct as_list *aslist)
 {
-  if (aslist->head == NULL && aslist->tail == NULL)
-    return 1;
-  else
-    return 0;
+       if (aslist->head == NULL && aslist->tail == NULL)
+               return 1;
+       else
+               return 0;
 }
 
-static void
-as_list_filter_delete (struct as_list *aslist, struct as_filter *asfilter)
+static void as_list_filter_delete(struct as_list *aslist,
+                                 struct as_filter *asfilter)
 {
-  char *name = XSTRDUP(MTYPE_AS_STR, aslist->name);
+       char *name = XSTRDUP(MTYPE_AS_STR, aslist->name);
 
-  if (asfilter->next)
-    asfilter->next->prev = asfilter->prev;
-  else
-    aslist->tail = asfilter->prev;
+       if (asfilter->next)
+               asfilter->next->prev = asfilter->prev;
+       else
+               aslist->tail = asfilter->prev;
 
-  if (asfilter->prev)
-    asfilter->prev->next = asfilter->next;
-  else
-    aslist->head = asfilter->next;
+       if (asfilter->prev)
+               asfilter->prev->next = asfilter->next;
+       else
+               aslist->head = asfilter->next;
 
-  as_filter_free (asfilter);
+       as_filter_free(asfilter);
 
-  /* If access_list becomes empty delete it from access_master. */
-  if (as_list_empty (aslist))
-    as_list_delete (aslist);
+       /* If access_list becomes empty delete it from access_master. */
+       if (as_list_empty(aslist))
+               as_list_delete(aslist);
 
-  /* Run hook function. */
-  if (as_list_master.delete_hook)
-    (*as_list_master.delete_hook) (name);
-  if (name)
-    XFREE(MTYPE_AS_STR, name);
+       /* Run hook function. */
+       if (as_list_master.delete_hook)
+               (*as_list_master.delete_hook)(name);
+       if (name)
+               XFREE(MTYPE_AS_STR, name);
 }
 
-static int
-as_filter_match (struct as_filter *asfilter, struct aspath *aspath)
+static int as_filter_match(struct as_filter *asfilter, struct aspath *aspath)
 {
-  if (bgp_regexec (asfilter->reg, aspath) != REG_NOMATCH)
-    return 1;
-  return 0;
+       if (bgp_regexec(asfilter->reg, aspath) != REG_NOMATCH)
+               return 1;
+       return 0;
 }
 
 /* Apply AS path filter to AS. */
-enum as_filter_type
-as_list_apply (struct as_list *aslist, void *object)
+enum as_filter_type as_list_apply(struct as_list *aslist, void *object)
 {
-  struct as_filter *asfilter;
-  struct aspath *aspath;
+       struct as_filter *asfilter;
+       struct aspath *aspath;
 
-  aspath = (struct aspath *) object;
+       aspath = (struct aspath *)object;
 
-  if (aslist == NULL)
-    return AS_FILTER_DENY;
+       if (aslist == NULL)
+               return AS_FILTER_DENY;
 
-  for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
-    {
-      if (as_filter_match (asfilter, aspath))
-       return asfilter->type;
-    }
-  return AS_FILTER_DENY;
+       for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
+               if (as_filter_match(asfilter, aspath))
+                       return asfilter->type;
+       }
+       return AS_FILTER_DENY;
 }
 
 /* Add hook function. */
-void
-as_list_add_hook (void (*func) (char *))
+void as_list_add_hook(void (*func)(char *))
 {
-  as_list_master.add_hook = func;
+       as_list_master.add_hook = func;
 }
 
 /* Delete hook function. */
-void
-as_list_delete_hook (void (*func) (const char *))
+void as_list_delete_hook(void (*func)(const char *))
 {
-  as_list_master.delete_hook = func;
+       as_list_master.delete_hook = func;
 }
 
-static int
-as_list_dup_check (struct as_list *aslist, struct as_filter *new)
+static int as_list_dup_check(struct as_list *aslist, struct as_filter *new)
 {
-  struct as_filter *asfilter;
-
-  for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
-    {
-      if (asfilter->type == new->type
-         && strcmp (asfilter->reg_str, new->reg_str) == 0)
-       return 1;
-    }
-  return 0;
+       struct as_filter *asfilter;
+
+       for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
+               if (asfilter->type == new->type
+                   && strcmp(asfilter->reg_str, new->reg_str) == 0)
+                       return 1;
+       }
+       return 0;
 }
 
-DEFUN (ip_as_path,
-       ip_as_path_cmd,
-       "ip as-path access-list WORD <deny|permit> LINE...",
-       IP_STR
-       "BGP autonomous system path filter\n"
-       "Specify an access list name\n"
-       "Regular expression access list name\n"
-       "Specify packets to reject\n"
-       "Specify packets to forward\n"
-       "A regular-expression to match the BGP AS paths\n")
+static int config_bgp_aspath_validate(const char *regstr)
 {
-  int idx = 0;
-  enum as_filter_type type;
-  struct as_filter *asfilter;
-  struct as_list *aslist;
-  regex_t *regex;
-  char *regstr;
-
-  /* Retrieve access list name */
-  char *alname = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
-
-  /* Check the filter type. */
-  type = argv_find (argv, argc, "deny", &idx) ? AS_FILTER_DENY : AS_FILTER_PERMIT;
-
-  /* Check AS path regex. */
-  argv_find (argv, argc, "LINE", &idx);
-  regstr = argv_concat(argv, argc, idx);
-
-  regex = bgp_regcomp (regstr);
-  if (!regex)
-    {
-      vty_out (vty, "can't compile regexp %s%s", regstr, VTY_NEWLINE);
-      XFREE (MTYPE_TMP, regstr);
-      return CMD_WARNING;
-    }
-
-  asfilter = as_filter_make (regex, regstr, type);
-  
-  XFREE (MTYPE_TMP, regstr);
-
-  /* Install new filter to the access_list. */
-  aslist = as_list_get (alname);
-
-  /* Duplicate insertion check. */;
-  if (as_list_dup_check (aslist, asfilter))
-    as_filter_free (asfilter);
-  else
-    as_list_filter_add (aslist, asfilter);
-
-  return CMD_SUCCESS;
+       char valid_chars[] = "1234567890_^|[,{}() ]$*+.?-";
+
+       if (strspn(regstr, valid_chars) == strlen(regstr))
+               return 1;
+
+       return 0;
 }
 
-DEFUN (no_ip_as_path,
-       no_ip_as_path_cmd,
-       "no ip as-path access-list WORD <deny|permit> LINE...",
+DEFUN(as_path, bgp_as_path_cmd,
+      "bgp as-path access-list WORD <deny|permit> LINE...",
+      BGP_STR
+      "BGP autonomous system path filter\n"
+      "Specify an access list name\n"
+      "Regular expression access list name\n"
+      "Specify packets to reject\n"
+      "Specify packets to forward\n"
+      "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n")
+{
+       int idx = 0;
+       enum as_filter_type type;
+       struct as_filter *asfilter;
+       struct as_list *aslist;
+       regex_t *regex;
+       char *regstr;
+
+       if (argv_find(argv, argc, "ip", &idx)) {
+               vty_out(vty, "This config option is deprecated and is scheduled for removal.\n");
+               vty_out(vty, "if you are using this please migrate to the below command\n");
+               vty_out(vty, "'bgp as-path access-list WORD <deny|permit> LINE'\n");
+               zlog_warn("Deprecated option: 'ip as-path access-list WORD <deny|permit> LINE' being used");
+       }
+
+       /* Retrieve access list name */
+       argv_find(argv, argc, "WORD", &idx);
+       char *alname = argv[idx]->arg;
+
+       /* Check the filter type. */
+       type = argv_find(argv, argc, "deny", &idx) ? AS_FILTER_DENY
+                                                  : AS_FILTER_PERMIT;
+
+       /* Check AS path regex. */
+       argv_find(argv, argc, "LINE", &idx);
+       regstr = argv_concat(argv, argc, idx);
+
+       regex = bgp_regcomp(regstr);
+       if (!regex) {
+               vty_out(vty, "can't compile regexp %s\n", regstr);
+               XFREE(MTYPE_TMP, regstr);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (!config_bgp_aspath_validate(regstr)) {
+               vty_out(vty, "Invalid character in as-path access-list %s\n",
+                       regstr);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       asfilter = as_filter_make(regex, regstr, type);
+
+       XFREE(MTYPE_TMP, regstr);
+
+       /* Install new filter to the access_list. */
+       aslist = as_list_get(alname);
+
+       /* Duplicate insertion check. */;
+       if (as_list_dup_check(aslist, asfilter))
+               as_filter_free(asfilter);
+       else
+               as_list_filter_add(aslist, asfilter);
+
+       return CMD_SUCCESS;
+}
+
+#if CONFDATE > 20191005
+CPP_NOTICE("bgpd: remove deprecated 'ip as-path access-list WORD <deny|permit> LINE' command")
+#endif
+ALIAS(as_path, ip_as_path_cmd,
+      "ip as-path access-list WORD <deny|permit> LINE...",
+      IP_STR
+      "BGP autonomous system path filter\n"
+      "Specify an access list name\n"
+      "Regular expression access list name\n"
+      "Specify packets to reject\n"
+      "Specify packets to forward\n"
+      "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n")
+
+DEFUN(no_as_path, no_bgp_as_path_cmd,
+      "no bgp as-path access-list WORD <deny|permit> LINE...",
+      NO_STR
+      BGP_STR
+      "BGP autonomous system path filter\n"
+      "Specify an access list name\n"
+      "Regular expression access list name\n"
+      "Specify packets to reject\n"
+      "Specify packets to forward\n"
+      "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n")
+{
+       int idx = 0;
+       enum as_filter_type type;
+       struct as_filter *asfilter;
+       struct as_list *aslist;
+       char *regstr;
+       regex_t *regex;
+
+       if (argv_find(argv, argc, "ip", &idx)) {
+               vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
+               vty_out(vty, "if you are using this please migrate to the below command\n");
+               vty_out(vty, "'no bgp as-path access-list WORD <deny|permit> LINE'\n");
+               zlog_warn("Deprecated option: 'no ip as-path access-list WORD <deny|permit> LINE' being used");
+       }
+       char *aslistname =
+               argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
+
+       /* Lookup AS list from AS path list. */
+       aslist = as_list_lookup(aslistname);
+       if (aslist == NULL) {
+               vty_out(vty, "bgp as-path access-list %s doesn't exist\n",
+                       aslistname);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       /* Check the filter type. */
+       if (argv_find(argv, argc, "permit", &idx))
+               type = AS_FILTER_PERMIT;
+       else if (argv_find(argv, argc, "deny", &idx))
+               type = AS_FILTER_DENY;
+       else {
+               vty_out(vty, "filter type must be [permit|deny]\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       /* Compile AS path. */
+       argv_find(argv, argc, "LINE", &idx);
+       regstr = argv_concat(argv, argc, idx);
+
+       if (!config_bgp_aspath_validate(regstr)) {
+               vty_out(vty, "Invalid character in as-path access-list %s\n",
+                       regstr);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       regex = bgp_regcomp(regstr);
+       if (!regex) {
+               vty_out(vty, "can't compile regexp %s\n", regstr);
+               XFREE(MTYPE_TMP, regstr);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       /* Lookup asfilter. */
+       asfilter = as_filter_lookup(aslist, regstr, type);
+
+       XFREE(MTYPE_TMP, regstr);
+       bgp_regex_free(regex);
+
+       if (asfilter == NULL) {
+               vty_out(vty, "\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       as_list_filter_delete(aslist, asfilter);
+
+       return CMD_SUCCESS;
+}
+
+ALIAS(no_as_path, no_ip_as_path_cmd,
+      "no ip as-path access-list WORD <deny|permit> LINE...",
+      NO_STR IP_STR
+      "BGP autonomous system path filter\n"
+      "Specify an access list name\n"
+      "Regular expression access list name\n"
+      "Specify packets to reject\n"
+      "Specify packets to forward\n"
+      "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n")
+
+DEFUN (no_as_path_all,
+       no_bgp_as_path_all_cmd,
+       "no bgp as-path access-list WORD",
        NO_STR
-       IP_STR
+       BGP_STR
        "BGP autonomous system path filter\n"
        "Specify an access list name\n"
-       "Regular expression access list name\n"
-       "Specify packets to reject\n"
-       "Specify packets to forward\n"
-       "A regular-expression to match the BGP AS paths\n")
+       "Regular expression access list name\n")
 {
-  int idx = 0;
-  enum as_filter_type type;
-  struct as_filter *asfilter;
-  struct as_list *aslist;
-  char *regstr;
-  regex_t *regex;
-
-  char *aslistname = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
-
-  /* Lookup AS list from AS path list. */
-  aslist = as_list_lookup (aslistname);
-  if (aslist == NULL)
-    {
-      vty_out (vty, "ip as-path access-list %s doesn't exist%s", aslistname,
-              VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-
-  /* Check the filter type. */
-  if (argv_find (argv, argc, "permit", &idx))
-    type = AS_FILTER_PERMIT;
-  else if (argv_find (argv, argc, "deny", &idx))
-    type = AS_FILTER_DENY;
-  else
-    {
-      vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-  
-  /* Compile AS path. */
-  argv_find (argv, argc, "LINE", &idx);
-  regstr = argv_concat(argv, argc, idx);
-
-  regex = bgp_regcomp (regstr);
-  if (!regex)
-    {
-      vty_out (vty, "can't compile regexp %s%s", regstr, VTY_NEWLINE);
-      XFREE (MTYPE_TMP, regstr);
-      return CMD_WARNING;
-    }
-
-  /* Lookup asfilter. */
-  asfilter = as_filter_lookup (aslist, regstr, type);
-
-  XFREE (MTYPE_TMP, regstr);
-  bgp_regex_free (regex);
-
-  if (asfilter == NULL)
-    {
-      vty_out (vty, "%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-
-  as_list_filter_delete (aslist, asfilter);
-
-  return CMD_SUCCESS;
+       int idx_word = 4;
+       struct as_list *aslist;
+       int idx = 0;
+
+       if (argv_find(argv, argc, "ip", &idx)) {
+               vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
+               vty_out(vty, "if you are using this please migrate to the below command\n");
+               vty_out(vty, "'no bgp as-path access-list WORD'\n");
+               zlog_warn("Deprecated option: `no ip as-path access-list WORD` being used");
+       }
+
+       aslist = as_list_lookup(argv[idx_word]->arg);
+       if (aslist == NULL) {
+               vty_out(vty, "bgp as-path access-list %s doesn't exist\n",
+                       argv[idx_word]->arg);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       as_list_delete(aslist);
+
+       /* Run hook function. */
+       if (as_list_master.delete_hook)
+               (*as_list_master.delete_hook)(argv[idx_word]->arg);
+
+       return CMD_SUCCESS;
 }
 
-DEFUN (no_ip_as_path_all,
+ALIAS (no_as_path_all,
        no_ip_as_path_all_cmd,
        "no ip as-path access-list WORD",
        NO_STR
@@ -556,170 +611,170 @@ DEFUN (no_ip_as_path_all,
        "BGP autonomous system path filter\n"
        "Specify an access list name\n"
        "Regular expression access list name\n")
-{
-  int idx_word = 4;
-  struct as_list *aslist;
-
-  aslist = as_list_lookup (argv[idx_word]->arg);
-  if (aslist == NULL)
-    {
-      vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[idx_word]->arg,
-              VTY_NEWLINE);
-      return CMD_WARNING;
-    }
 
-  as_list_delete (aslist);
+static void as_list_show(struct vty *vty, struct as_list *aslist)
+{
+       struct as_filter *asfilter;
 
-  /* Run hook function. */
-  if (as_list_master.delete_hook)
-    (*as_list_master.delete_hook) (argv[idx_word]->arg);
+       vty_out(vty, "AS path access list %s\n", aslist->name);
 
-  return CMD_SUCCESS;
+       for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
+               vty_out(vty, "    %s %s\n", filter_type_str(asfilter->type),
+                       asfilter->reg_str);
+       }
 }
 
-static void
-as_list_show (struct vty *vty, struct as_list *aslist)
+static void as_list_show_all(struct vty *vty)
 {
-  struct as_filter *asfilter;
+       struct as_list *aslist;
+       struct as_filter *asfilter;
 
-  vty_out (vty, "AS path access list %s%s", aslist->name, VTY_NEWLINE);
-
-  for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
-    {
-      vty_out (vty, "    %s %s%s", filter_type_str (asfilter->type),
-              asfilter->reg_str, VTY_NEWLINE);
-    }
-}
+       for (aslist = as_list_master.num.head; aslist; aslist = aslist->next) {
+               vty_out(vty, "AS path access list %s\n", aslist->name);
 
-static void
-as_list_show_all (struct vty *vty)
-{
-  struct as_list *aslist;
-  struct as_filter *asfilter;
+               for (asfilter = aslist->head; asfilter;
+                    asfilter = asfilter->next) {
+                       vty_out(vty, "    %s %s\n",
+                               filter_type_str(asfilter->type),
+                               asfilter->reg_str);
+               }
+       }
 
-  for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
-    {
-      vty_out (vty, "AS path access list %s%s", aslist->name, VTY_NEWLINE);
+       for (aslist = as_list_master.str.head; aslist; aslist = aslist->next) {
+               vty_out(vty, "AS path access list %s\n", aslist->name);
 
-      for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
-       {
-         vty_out (vty, "    %s %s%s", filter_type_str (asfilter->type),
-                  asfilter->reg_str, VTY_NEWLINE);
+               for (asfilter = aslist->head; asfilter;
+                    asfilter = asfilter->next) {
+                       vty_out(vty, "    %s %s\n",
+                               filter_type_str(asfilter->type),
+                               asfilter->reg_str);
+               }
        }
-    }
+}
 
-  for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
-    {
-      vty_out (vty, "AS path access list %s%s", aslist->name, VTY_NEWLINE);
+DEFUN (show_as_path_access_list,
+       show_bgp_as_path_access_list_cmd,
+       "show bgp as-path-access-list WORD",
+       SHOW_STR
+       BGP_STR
+       "List AS path access lists\n"
+       "AS path access list name\n")
+{
+       int idx_word = 3;
+       struct as_list *aslist;
+       int idx = 0;
 
-      for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
-       {
-         vty_out (vty, "    %s %s%s", filter_type_str (asfilter->type),
-                  asfilter->reg_str, VTY_NEWLINE);
+       if (argv_find(argv, argc, "ip", &idx)) {
+               vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
+               vty_out(vty, "if you are using this please migrate to the below command\n");
+               vty_out(vty, "'show bgp as-path-access-list WORD'\n");
+               zlog_warn("Deprecated option: 'show ip as-path-access-list WORD' being used");
        }
-    }
+       aslist = as_list_lookup(argv[idx_word]->arg);
+       if (aslist)
+               as_list_show(vty, aslist);
+
+       return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_as_path_access_list,
+ALIAS (show_as_path_access_list,
        show_ip_as_path_access_list_cmd,
        "show ip as-path-access-list WORD",
        SHOW_STR
        IP_STR
        "List AS path access lists\n"
        "AS path access list name\n")
-{
-  int idx_word = 3;
-  struct as_list *aslist;
 
-  aslist = as_list_lookup (argv[idx_word]->arg);
-  if (aslist)
-    as_list_show (vty, aslist);
+DEFUN (show_as_path_access_list_all,
+       show_bgp_as_path_access_list_all_cmd,
+       "show bgp as-path-access-list",
+       SHOW_STR
+       BGP_STR
+       "List AS path access lists\n")
+{
+       int idx = 0;
 
-  return CMD_SUCCESS;
+       if (argv_find(argv, argc, "ip", &idx)) {
+               vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
+               vty_out(vty, "if you are using this please migrate to the below command\n");
+               vty_out(vty, "'show bgp as-path-access-list'\n");
+               zlog_warn("Deprecated option: 'show ip as-path-access-list' being used");
+       }
+       as_list_show_all(vty);
+       return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_as_path_access_list_all,
+ALIAS (show_as_path_access_list_all,
        show_ip_as_path_access_list_all_cmd,
        "show ip as-path-access-list",
        SHOW_STR
        IP_STR
        "List AS path access lists\n")
-{
-  as_list_show_all (vty);
-  return CMD_SUCCESS;
-}
 
-static int
-config_write_as_list (struct vty *vty)
-{
-  struct as_list *aslist;
-  struct as_filter *asfilter;
-  int write = 0;
-
-  for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
-    for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
-      {
-       vty_out (vty, "ip as-path access-list %s %s %s%s",
-                aslist->name, filter_type_str (asfilter->type), 
-                asfilter->reg_str,
-                VTY_NEWLINE);
-       write++;
-      }
-
-  for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
-    for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
-      {
-       vty_out (vty, "ip as-path access-list %s %s %s%s",
-                aslist->name, filter_type_str (asfilter->type), 
-                asfilter->reg_str,
-                VTY_NEWLINE);
-       write++;
-      }
-  return write;
+static int config_write_as_list(struct vty *vty)
+{
+       struct as_list *aslist;
+       struct as_filter *asfilter;
+       int write = 0;
+
+       for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
+               for (asfilter = aslist->head; asfilter;
+                    asfilter = asfilter->next) {
+                       vty_out(vty, "bgp as-path access-list %s %s %s\n",
+                               aslist->name, filter_type_str(asfilter->type),
+                               asfilter->reg_str);
+                       write++;
+               }
+
+       for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
+               for (asfilter = aslist->head; asfilter;
+                    asfilter = asfilter->next) {
+                       vty_out(vty, "bgp as-path access-list %s %s %s\n",
+                               aslist->name, filter_type_str(asfilter->type),
+                               asfilter->reg_str);
+                       write++;
+               }
+       return write;
 }
 
-static struct cmd_node as_list_node =
-{
-  AS_LIST_NODE,
-  "",
-  1
-};
+static struct cmd_node as_list_node = {AS_LIST_NODE, "", 1};
 
 /* Register functions. */
-void
-bgp_filter_init (void)
+void bgp_filter_init(void)
 {
-  install_node (&as_list_node, config_write_as_list);
+       install_node(&as_list_node, config_write_as_list);
 
-  install_element (CONFIG_NODE, &ip_as_path_cmd);
-  install_element (CONFIG_NODE, &no_ip_as_path_cmd);
-  install_element (CONFIG_NODE, &no_ip_as_path_all_cmd);
+       install_element(CONFIG_NODE, &bgp_as_path_cmd);
+       install_element(CONFIG_NODE, &ip_as_path_cmd);
+       install_element(CONFIG_NODE, &no_bgp_as_path_cmd);
+       install_element(CONFIG_NODE, &no_ip_as_path_cmd);
+       install_element(CONFIG_NODE, &no_bgp_as_path_all_cmd);
+       install_element(CONFIG_NODE, &no_ip_as_path_all_cmd);
 
-  install_element (VIEW_NODE, &show_ip_as_path_access_list_cmd);
-  install_element (VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
+       install_element(VIEW_NODE, &show_bgp_as_path_access_list_cmd);
+       install_element(VIEW_NODE, &show_ip_as_path_access_list_cmd);
+       install_element(VIEW_NODE, &show_bgp_as_path_access_list_all_cmd);
+       install_element(VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
 }
 
-void
-bgp_filter_reset (void)
+void bgp_filter_reset(void)
 {
-  struct as_list *aslist;
-  struct as_list *next;
-
-  for (aslist = as_list_master.num.head; aslist; aslist = next)
-    {
-      next = aslist->next;
-      as_list_delete (aslist);
-    }
-
-  for (aslist = as_list_master.str.head; aslist; aslist = next)
-    {
-      next = aslist->next;
-      as_list_delete (aslist);
-    }
-
-  assert (as_list_master.num.head == NULL);
-  assert (as_list_master.num.tail == NULL);
-
-  assert (as_list_master.str.head == NULL);
-  assert (as_list_master.str.tail == NULL);
+       struct as_list *aslist;
+       struct as_list *next;
+
+       for (aslist = as_list_master.num.head; aslist; aslist = next) {
+               next = aslist->next;
+               as_list_delete(aslist);
+       }
+
+       for (aslist = as_list_master.str.head; aslist; aslist = next) {
+               next = aslist->next;
+               as_list_delete(aslist);
+       }
+
+       assert(as_list_master.num.head == NULL);
+       assert(as_list_master.num.tail == NULL);
+
+       assert(as_list_master.str.head == NULL);
+       assert(as_list_master.str.tail == NULL);
 }