return NULL;
}
-static int vty_access_list_remark_unset(struct vty *vty, afi_t afi,
- const char *name)
-{
- struct access_list *access;
-
- access = access_list_lookup(afi, name);
- if (!access) {
- vty_out(vty, "%% access-list %s doesn't exist\n", name);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- XFREE(MTYPE_TMP, access->remark);
-
- if (access->head == NULL && access->tail == NULL)
- access_list_delete(access);
-
- return CMD_SUCCESS;
-}
-
-static int filter_set_cisco(struct vty *vty, const char *name_str,
- const char *seq, const char *type_str,
- const char *addr_str, const char *addr_mask_str,
- const char *mask_str, const char *mask_mask_str,
- int extended, int set)
-{
- int ret;
- enum filter_type type = FILTER_DENY;
- struct filter *mfilter;
- struct filter_cisco *filter;
- struct access_list *access;
- struct in_addr addr;
- struct in_addr addr_mask;
- struct in_addr mask;
- struct in_addr mask_mask;
- int64_t seqnum = -1;
-
- if (seq)
- seqnum = (int64_t)atol(seq);
-
- /* Check of filter type. */
- if (type_str) {
- if (strncmp(type_str, "p", 1) == 0)
- type = FILTER_PERMIT;
- else if (strncmp(type_str, "d", 1) == 0)
- type = FILTER_DENY;
- else {
- vty_out(vty, "%% filter type must be permit or deny\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
-
- ret = inet_aton(addr_str, &addr);
- if (ret <= 0) {
- vty_out(vty, "%%Inconsistent address and mask\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- ret = inet_aton(addr_mask_str, &addr_mask);
- if (ret <= 0) {
- vty_out(vty, "%%Inconsistent address and mask\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (extended) {
- ret = inet_aton(mask_str, &mask);
- if (ret <= 0) {
- vty_out(vty, "%%Inconsistent address and mask\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- ret = inet_aton(mask_mask_str, &mask_mask);
- if (ret <= 0) {
- vty_out(vty, "%%Inconsistent address and mask\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
-
- mfilter = filter_new();
- mfilter->type = type;
- mfilter->cisco = 1;
- mfilter->seq = seqnum;
- filter = &mfilter->u.cfilter;
- filter->extended = extended;
- filter->addr.s_addr = addr.s_addr & ~addr_mask.s_addr;
- filter->addr_mask.s_addr = addr_mask.s_addr;
-
- if (extended) {
- filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
- filter->mask_mask.s_addr = mask_mask.s_addr;
- }
-
- /* Install new filter to the access_list. */
- access = access_list_get(AFI_IP, name_str);
-
- if (set) {
- if (filter_lookup_cisco(access, mfilter))
- filter_free(mfilter);
- else
- access_list_filter_add(access, mfilter);
- } else {
- struct filter *delete_filter;
-
- delete_filter = filter_lookup_cisco(access, mfilter);
- if (delete_filter)
- access_list_filter_delete(access, delete_filter);
-
- filter_free(mfilter);
- }
-
- return CMD_SUCCESS;
-}
-
-/* Standard access-list */
-DEFUN (access_list_standard,
- access_list_standard_cmd,
- "access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> A.B.C.D A.B.C.D",
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP standard access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Address to match\n"
- "Wildcard bits\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *address = NULL;
- char *wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- address = argv[idx]->arg;
- wildcard = argv[idx + 1]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- address, wildcard, NULL, NULL, 0, 1);
-}
-
-DEFUN (access_list_standard_nomask,
- access_list_standard_nomask_cmd,
- "access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> A.B.C.D",
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP standard access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Address to match\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *address = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx)
- address = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- address, "0.0.0.0", NULL, NULL, 0, 1);
-}
-
-DEFUN (access_list_standard_host,
- access_list_standard_host_cmd,
- "access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> host A.B.C.D",
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP standard access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "A single host address\n"
- "Address to match\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *address = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx)
- address = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- address, "0.0.0.0", NULL, NULL, 0, 1);
-}
-
-DEFUN (access_list_standard_any,
- access_list_standard_any_cmd,
- "access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> any",
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP standard access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any source host\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- "0.0.0.0", "255.255.255.255", NULL, NULL, 0, 1);
-}
-
-DEFUN (no_access_list_standard,
- no_access_list_standard_cmd,
- "no access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> A.B.C.D A.B.C.D",
- NO_STR
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP standard access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Address to match\n"
- "Wildcard bits\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *address = NULL;
- char *wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- address = argv[idx]->arg;
- wildcard = argv[idx + 1]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- address, wildcard, NULL, NULL, 0, 0);
-}
-
-DEFUN (no_access_list_standard_nomask,
- no_access_list_standard_nomask_cmd,
- "no access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> A.B.C.D",
- NO_STR
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP standard access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Address to match\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *address = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx)
- address = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- address, "0.0.0.0", NULL, NULL, 0, 0);
-}
-
-DEFUN (no_access_list_standard_host,
- no_access_list_standard_host_cmd,
- "no access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> host A.B.C.D",
- NO_STR
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP standard access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "A single host address\n"
- "Address to match\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *address = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx)
- address = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- address, "0.0.0.0", NULL, NULL, 0, 0);
-}
-
-DEFUN (no_access_list_standard_any,
- no_access_list_standard_any_cmd,
- "no access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> any",
- NO_STR
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP standard access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any source host\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- "0.0.0.0", "255.255.255.255", NULL, NULL, 0, 0);
-}
-
-/* Extended access-list */
-DEFUN (access_list_extended,
- access_list_extended_cmd,
- "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Source address\n"
- "Source wildcard bits\n"
- "Destination address\n"
- "Destination Wildcard bits\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *dst = NULL;
- char *src_wildcard = NULL;
- char *dst_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- src_wildcard = argv[idx + 1]->arg;
- dst = argv[idx + 2]->arg;
- dst_wildcard = argv[idx + 3]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- src_wildcard, dst, dst_wildcard, 1, 1);
-}
-
-DEFUN (access_list_extended_mask_any,
- access_list_extended_mask_any_cmd,
- "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D any",
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Source address\n"
- "Source wildcard bits\n"
- "Any destination host\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *src_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- src_wildcard = argv[idx + 1]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- src_wildcard, "0.0.0.0", "255.255.255.255", 1,
- 1);
-}
-
-DEFUN (access_list_extended_any_mask,
- access_list_extended_any_mask_cmd,
- "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any A.B.C.D A.B.C.D",
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Any source host\n"
- "Destination address\n"
- "Destination Wildcard bits\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *dst = NULL;
- char *dst_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- dst = argv[idx]->arg;
- dst_wildcard = argv[idx + 1]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- "0.0.0.0", "255.255.255.255", dst, dst_wildcard,
- 1, 1);
-}
-
-DEFUN (access_list_extended_any_any,
- access_list_extended_any_any_cmd,
- "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any any",
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Any source host\n"
- "Any destination host\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- "0.0.0.0", "255.255.255.255", "0.0.0.0",
- "255.255.255.255", 1, 1);
-}
-
-DEFUN (access_list_extended_mask_host,
- access_list_extended_mask_host_cmd,
- "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D host A.B.C.D",
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Source address\n"
- "Source wildcard bits\n"
- "A single destination host\n"
- "Destination address\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *dst = NULL;
- char *src_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- src_wildcard = argv[idx + 1]->arg;
- dst = argv[idx + 3]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- src_wildcard, dst, "0.0.0.0", 1, 1);
-}
-
-DEFUN (access_list_extended_host_mask,
- access_list_extended_host_mask_cmd,
- "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D A.B.C.D A.B.C.D",
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "A single source host\n"
- "Source address\n"
- "Destination address\n"
- "Destination Wildcard bits\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *dst = NULL;
- char *dst_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- dst = argv[idx + 1]->arg;
- dst_wildcard = argv[idx + 2]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- "0.0.0.0", dst, dst_wildcard, 1, 1);
-}
-
-DEFUN (access_list_extended_host_host,
- access_list_extended_host_host_cmd,
- "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D host A.B.C.D",
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "A single source host\n"
- "Source address\n"
- "A single destination host\n"
- "Destination address\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *dst = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- dst = argv[idx + 2]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- "0.0.0.0", dst, "0.0.0.0", 1, 1);
-}
-
-DEFUN (access_list_extended_any_host,
- access_list_extended_any_host_cmd,
- "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any host A.B.C.D",
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Any source host\n"
- "A single destination host\n"
- "Destination address\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *dst = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx)
- dst = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- "0.0.0.0", "255.255.255.255", dst, "0.0.0.0", 1,
- 1);
-}
-
-DEFUN (access_list_extended_host_any,
- access_list_extended_host_any_cmd,
- "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D any",
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "A single source host\n"
- "Source address\n"
- "Any destination host\n")
-{
- int idx_acl = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx)
- src = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- "0.0.0.0", "0.0.0.0", "255.255.255.255", 1, 1);
-}
-
-DEFUN (no_access_list_extended,
- no_access_list_extended_cmd,
- "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
- NO_STR
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Source address\n"
- "Source wildcard bits\n"
- "Destination address\n"
- "Destination Wildcard bits\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *dst = NULL;
- char *src_wildcard = NULL;
- char *dst_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- src_wildcard = argv[idx + 1]->arg;
- dst = argv[idx + 2]->arg;
- dst_wildcard = argv[idx + 3]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- src_wildcard, dst, dst_wildcard, 1, 0);
-}
-
-DEFUN (no_access_list_extended_mask_any,
- no_access_list_extended_mask_any_cmd,
- "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D any",
- NO_STR
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Source address\n"
- "Source wildcard bits\n"
- "Any destination host\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *src_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- src_wildcard = argv[idx + 1]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- src_wildcard, "0.0.0.0", "255.255.255.255", 1,
- 0);
-}
-
-DEFUN (no_access_list_extended_any_mask,
- no_access_list_extended_any_mask_cmd,
- "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any A.B.C.D A.B.C.D",
- NO_STR
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Any source host\n"
- "Destination address\n"
- "Destination Wildcard bits\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *dst = NULL;
- char *dst_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- dst = argv[idx]->arg;
- dst_wildcard = argv[idx + 1]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- "0.0.0.0", "255.255.255.255", dst, dst_wildcard,
- 1, 0);
-}
-
-DEFUN (no_access_list_extended_any_any,
- no_access_list_extended_any_any_cmd,
- "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any any",
- NO_STR
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Any source host\n"
- "Any destination host\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- "0.0.0.0", "255.255.255.255", "0.0.0.0",
- "255.255.255.255", 1, 0);
-}
-
-DEFUN (no_access_list_extended_mask_host,
- no_access_list_extended_mask_host_cmd,
- "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D host A.B.C.D",
- NO_STR
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Source address\n"
- "Source wildcard bits\n"
- "A single destination host\n"
- "Destination address\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *dst = NULL;
- char *src_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- src_wildcard = argv[idx + 1]->arg;
- dst = argv[idx + 3]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- src_wildcard, dst, "0.0.0.0", 1, 0);
-}
-
-DEFUN (no_access_list_extended_host_mask,
- no_access_list_extended_host_mask_cmd,
- "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D A.B.C.D A.B.C.D",
- NO_STR
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "A single source host\n"
- "Source address\n"
- "Destination address\n"
- "Destination Wildcard bits\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *dst = NULL;
- char *dst_wildcard = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- dst = argv[idx + 1]->arg;
- dst_wildcard = argv[idx + 2]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- "0.0.0.0", dst, dst_wildcard, 1, 0);
-}
-
-DEFUN (no_access_list_extended_host_host,
- no_access_list_extended_host_host_cmd,
- "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D host A.B.C.D",
- NO_STR
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "A single source host\n"
- "Source address\n"
- "A single destination host\n"
- "Destination address\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
- char *dst = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx) {
- src = argv[idx]->arg;
- dst = argv[idx + 2]->arg;
- }
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- "0.0.0.0", dst, "0.0.0.0", 1, 0);
-}
-
-DEFUN (no_access_list_extended_any_host,
- no_access_list_extended_any_host_cmd,
- "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any host A.B.C.D",
- NO_STR
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "Any source host\n"
- "A single destination host\n"
- "Destination address\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *dst = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx)
- dst = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
- "0.0.0.0", "255.255.255.255", dst, "0.0.0.0", 1,
- 0);
-}
-
-DEFUN (no_access_list_extended_host_any,
- no_access_list_extended_host_any_cmd,
- "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D any",
- NO_STR
- "Add an access list entry\n"
- "IP extended access list\n"
- "IP extended access list (expanded range)\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any Internet Protocol\n"
- "A single source host\n"
- "Source address\n"
- "Any destination host\n")
-{
- int idx_acl = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *src = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D", &idx);
- if (idx)
- src = argv[idx]->arg;
-
- return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
- "0.0.0.0", "0.0.0.0", "255.255.255.255", 1, 0);
-}
-
-static int filter_set_zebra(struct vty *vty, const char *name_str,
- const char *seq, const char *type_str, afi_t afi,
- const char *prefix_str, int exact, int set)
-{
- int ret;
- enum filter_type type = FILTER_DENY;
- struct filter *mfilter;
- struct filter_zebra *filter;
- struct access_list *access;
- struct prefix p;
- int64_t seqnum = -1;
-
- if (strlen(name_str) > ACL_NAMSIZ) {
- vty_out(vty,
- "%% ACL name %s is invalid: length exceeds "
- "%d characters\n",
- name_str, ACL_NAMSIZ);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (seq)
- seqnum = (int64_t)atol(seq);
-
- /* Check of filter type. */
- if (type_str) {
- if (strncmp(type_str, "p", 1) == 0)
- type = FILTER_PERMIT;
- else if (strncmp(type_str, "d", 1) == 0)
- type = FILTER_DENY;
- else {
- vty_out(vty, "filter type must be [permit|deny]\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
-
- /* Check string format of prefix and prefixlen. */
- if (afi == AFI_IP) {
- ret = str2prefix_ipv4(prefix_str, (struct prefix_ipv4 *)&p);
- if (ret <= 0) {
- vty_out(vty,
- "IP address prefix/prefixlen is malformed\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- } else if (afi == AFI_IP6) {
- ret = str2prefix_ipv6(prefix_str, (struct prefix_ipv6 *)&p);
- if (ret <= 0) {
- vty_out(vty,
- "IPv6 address prefix/prefixlen is malformed\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- } else if (afi == AFI_L2VPN) {
- ret = str2prefix_eth(prefix_str, (struct prefix_eth *)&p);
- if (ret <= 0) {
- vty_out(vty, "MAC address is malformed\n");
- return CMD_WARNING;
- }
- } else
- return CMD_WARNING_CONFIG_FAILED;
-
- mfilter = filter_new();
- mfilter->type = type;
- mfilter->seq = seqnum;
- filter = &mfilter->u.zfilter;
- prefix_copy(&filter->prefix, &p);
-
- /* "exact-match" */
- if (exact)
- filter->exact = 1;
-
- /* Install new filter to the access_list. */
- access = access_list_get(afi, name_str);
-
- if (set) {
- if (filter_lookup_zebra(access, mfilter))
- filter_free(mfilter);
- else
- access_list_filter_add(access, mfilter);
- } else {
- struct filter *delete_filter;
- delete_filter = filter_lookup_zebra(access, mfilter);
- if (delete_filter)
- access_list_filter_delete(access, delete_filter);
-
- filter_free(mfilter);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (mac_access_list,
- mac_access_list_cmd,
- "mac access-list WORD [seq (1-4294967295)] <deny|permit> X:X:X:X:X:X",
- "Add a mac access-list\n"
- "Add an access list entry\n"
- "MAC zebra access-list name\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "MAC address to match. e.g. 00:01:00:01:00:01\n")
-{
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *mac = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "X:X:X:X:X:X", &idx);
- if (idx)
- mac = argv[idx]->arg;
- assert(mac);
-
- return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN,
- mac, 0, 1);
-}
-
-DEFUN (no_mac_access_list,
- no_mac_access_list_cmd,
- "no mac access-list WORD [seq (1-4294967295)] <deny|permit> X:X:X:X:X:X",
- NO_STR
- "Remove a mac access-list\n"
- "Remove an access list entry\n"
- "MAC zebra access-list name\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "MAC address to match. e.g. 00:01:00:01:00:01\n")
-{
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *mac = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "X:X:X:X:X:X", &idx);
- if (idx)
- mac = argv[idx]->arg;
- assert(mac);
-
- return filter_set_zebra(vty, argv[3]->arg, seq, permit_deny, AFI_L2VPN,
- mac, 0, 0);
-}
-
-DEFUN (mac_access_list_any,
- mac_access_list_any_cmd,
- "mac access-list WORD [seq (1-4294967295)] <deny|permit> any",
- "Add a mac access-list\n"
- "Add an access list entry\n"
- "MAC zebra access-list name\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "MAC address to match. e.g. 00:01:00:01:00:01\n")
-{
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN,
- "00:00:00:00:00:00", 0, 1);
-}
-
-DEFUN (no_mac_access_list_any,
- no_mac_access_list_any_cmd,
- "no mac access-list WORD [seq (1-4294967295)] <deny|permit> any",
- NO_STR
- "Remove a mac access-list\n"
- "Remove an access list entry\n"
- "MAC zebra access-list name\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "MAC address to match. e.g. 00:01:00:01:00:01\n")
-{
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN,
- "00:00:00:00:00:00", 0, 0);
-}
-
-DEFUN (access_list_exact,
- access_list_exact_cmd,
- "access-list WORD [seq (1-4294967295)] <deny|permit> A.B.C.D/M [exact-match]",
- "Add an access list entry\n"
- "IP zebra access-list name\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Prefix to match. e.g. 10.0.0.0/8\n"
- "Exact match of the prefixes\n")
-{
- int idx = 0;
- int exact = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *prefix = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D/M", &idx);
- if (idx)
- prefix = argv[idx]->arg;
- assert(prefix);
-
- idx = 0;
- if (argv_find(argv, argc, "exact-match", &idx))
- exact = 1;
-
- return filter_set_zebra(vty, argv[1]->arg, seq, permit_deny,
- AFI_IP, prefix, exact, 1);
-}
-
-DEFUN (access_list_any,
- access_list_any_cmd,
- "access-list WORD [seq (1-4294967295)] <deny|permit> any",
- "Add an access list entry\n"
- "IP zebra access-list name\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Prefix to match. e.g. 10.0.0.0/8\n")
-{
- int idx_word = 1;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
- AFI_IP, "0.0.0.0/0", 0, 1);
-}
-
-DEFUN (no_access_list_exact,
- no_access_list_exact_cmd,
- "no access-list WORD [seq (1-4294967295)] <deny|permit> A.B.C.D/M [exact-match]",
- NO_STR
- "Add an access list entry\n"
- "IP zebra access-list name\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Prefix to match. e.g. 10.0.0.0/8\n"
- "Exact match of the prefixes\n")
-{
- int idx = 0;
- int exact = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *prefix = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "A.B.C.D/M", &idx);
- if (idx)
- prefix = argv[idx]->arg;
- assert(prefix);
-
- idx = 0;
- if (argv_find(argv, argc, "exact-match", &idx))
- exact = 1;
-
- return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny,
- AFI_IP, prefix, exact, 0);
-}
-
-DEFUN (no_access_list_any,
- no_access_list_any_cmd,
- "no access-list WORD [seq (1-4294967295)] <deny|permit> any",
- NO_STR
- "Add an access list entry\n"
- "IP zebra access-list name\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Prefix to match. e.g. 10.0.0.0/8\n")
-{
- int idx_word = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
- AFI_IP, "0.0.0.0/0", 0, 0);
-}
-
-DEFUN (no_access_list_all,
- no_access_list_all_cmd,
- "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD>",
- NO_STR
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP extended access list\n"
- "IP standard access list (expanded range)\n"
- "IP extended access list (expanded range)\n"
- "IP zebra access-list name\n")
-{
- int idx_acl = 2;
- struct access_list *access;
- struct access_master *master;
-
- /* Looking up access_list. */
- access = access_list_lookup(AFI_IP, argv[idx_acl]->arg);
- if (access == NULL) {
- vty_out(vty, "%% access-list %s doesn't exist\n",
- argv[idx_acl]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- master = access->master;
-
- route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_DELETED);
- /* Run hook function. */
- if (master->delete_hook)
- (*master->delete_hook)(access);
-
- /* Delete all filter from access-list. */
- access_list_delete(access);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (access_list_remark,
- access_list_remark_cmd,
- "access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD> remark LINE...",
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP extended access list\n"
- "IP standard access list (expanded range)\n"
- "IP extended access list (expanded range)\n"
- "IP zebra access-list\n"
- "Access list entry comment\n"
- "Comment up to 100 characters\n")
-{
- int idx_acl = 1;
- int idx_remark = 3;
- struct access_list *access;
-
- access = access_list_get(AFI_IP, argv[idx_acl]->arg);
-
- if (access->remark) {
- XFREE(MTYPE_TMP, access->remark);
- access->remark = NULL;
- }
- access->remark = argv_concat(argv, argc, idx_remark);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_access_list_remark,
- no_access_list_remark_cmd,
- "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD> remark",
- NO_STR
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP extended access list\n"
- "IP standard access list (expanded range)\n"
- "IP extended access list (expanded range)\n"
- "IP zebra access-list\n"
- "Access list entry comment\n")
-{
- int idx_acl = 2;
- return vty_access_list_remark_unset(vty, AFI_IP, argv[idx_acl]->arg);
-}
-
-/* ALIAS_FIXME */
-DEFUN (no_access_list_remark_comment,
- no_access_list_remark_comment_cmd,
- "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD> remark LINE...",
- NO_STR
- "Add an access list entry\n"
- "IP standard access list\n"
- "IP extended access list\n"
- "IP standard access list (expanded range)\n"
- "IP extended access list (expanded range)\n"
- "IP zebra access-list\n"
- "Access list entry comment\n"
- "Comment up to 100 characters\n")
-{
- return no_access_list_remark(self, vty, argc, argv);
-}
-
-DEFUN (ipv6_access_list_exact,
- ipv6_access_list_exact_cmd,
- "ipv6 access-list WORD [seq (1-4294967295)] <deny|permit> X:X::X:X/M [exact-match]",
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "IPv6 prefix\n"
- "Exact match of the prefixes\n")
-{
- int idx = 0;
- int exact = 0;
- int idx_word = 2;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *prefix = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "X:X::X:X/M", &idx);
- if (idx)
- prefix = argv[idx]->arg;
-
- idx = 0;
- if (argv_find(argv, argc, "exact-match", &idx))
- exact = 1;
-
- assert(prefix);
- return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
- AFI_IP6, prefix, exact, 1);
-}
-
-DEFUN (ipv6_access_list_any,
- ipv6_access_list_any_cmd,
- "ipv6 access-list WORD [seq (1-4294967295)] <deny|permit> any",
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any prefixi to match\n")
-{
- int idx_word = 2;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
- AFI_IP6, "::/0", 0, 1);
-}
-
-DEFUN (no_ipv6_access_list_exact,
- no_ipv6_access_list_exact_cmd,
- "no ipv6 access-list WORD [seq (1-4294967295)] <deny|permit> X:X::X:X/M [exact-match]",
- NO_STR
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Prefix to match. e.g. 3ffe:506::/32\n"
- "Exact match of the prefixes\n")
-{
- int idx = 0;
- int exact = 0;
- int idx_word = 3;
- char *seq = NULL;
- char *permit_deny = NULL;
- char *prefix = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "X:X::X:X/M", &idx);
- if (idx)
- prefix = argv[idx]->arg;
- assert(prefix);
-
- idx = 0;
- if (argv_find(argv, argc, "exact-match", &idx))
- exact = 1;
-
- return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
- AFI_IP6, prefix, exact, 0);
-}
-
-DEFUN (no_ipv6_access_list_any,
- no_ipv6_access_list_any_cmd,
- "no ipv6 access-list WORD [seq (1-4294967295)] <deny|permit> any",
- NO_STR
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n"
- "Sequence number of an entry\n"
- "Sequence number\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Any prefixi to match\n")
-{
- int idx_word = 3;
- int idx = 0;
- char *seq = NULL;
- char *permit_deny = NULL;
-
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
- seq = argv[idx]->arg;
-
- idx = 0;
- argv_find(argv, argc, "permit", &idx);
- argv_find(argv, argc, "deny", &idx);
- if (idx)
- permit_deny = argv[idx]->arg;
-
- return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
- AFI_IP6, "::/0", 0, 0);
-}
-
-
-DEFUN (no_ipv6_access_list_all,
- no_ipv6_access_list_all_cmd,
- "no ipv6 access-list WORD",
- NO_STR
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n")
-{
- int idx_word = 3;
- struct access_list *access;
- struct access_master *master;
-
- /* Looking up access_list. */
- access = access_list_lookup(AFI_IP6, argv[idx_word]->arg);
- if (access == NULL) {
- vty_out(vty, "%% access-list %s doesn't exist\n",
- argv[idx_word]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- master = access->master;
-
- route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_DELETED);
- /* Run hook function. */
- if (master->delete_hook)
- (*master->delete_hook)(access);
-
- /* Delete all filter from access-list. */
- access_list_delete(access);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (ipv6_access_list_remark,
- ipv6_access_list_remark_cmd,
- "ipv6 access-list WORD remark LINE...",
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n"
- "Access list entry comment\n"
- "Comment up to 100 characters\n")
-{
- int idx_word = 2;
- int idx_line = 4;
- struct access_list *access;
-
- access = access_list_get(AFI_IP6, argv[idx_word]->arg);
-
- if (access->remark) {
- XFREE(MTYPE_TMP, access->remark);
- access->remark = NULL;
- }
- access->remark = argv_concat(argv, argc, idx_line);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ipv6_access_list_remark,
- no_ipv6_access_list_remark_cmd,
- "no ipv6 access-list WORD remark",
- NO_STR
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n"
- "Access list entry comment\n")
-{
- int idx_word = 3;
- return vty_access_list_remark_unset(vty, AFI_IP6, argv[idx_word]->arg);
-}
-
-/* ALIAS_FIXME */
-DEFUN (no_ipv6_access_list_remark_comment,
- no_ipv6_access_list_remark_comment_cmd,
- "no ipv6 access-list WORD remark LINE...",
- NO_STR
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n"
- "Access list entry comment\n"
- "Comment up to 100 characters\n")
-{
- return no_ipv6_access_list_remark(self, vty, argc, argv);
-}
-
static void config_write_access_zebra(struct vty *, struct filter *);
static void config_write_access_cisco(struct vty *, struct filter *);
install_element(ENABLE_NODE, &show_mac_access_list_cmd);
install_element(ENABLE_NODE, &show_mac_access_list_name_cmd);
-
- /* Zebra access-list */
- install_element(CONFIG_NODE, &mac_access_list_cmd);
- install_element(CONFIG_NODE, &no_mac_access_list_cmd);
- install_element(CONFIG_NODE, &mac_access_list_any_cmd);
- install_element(CONFIG_NODE, &no_mac_access_list_any_cmd);
}
/* Access-list node. */
install_element(ENABLE_NODE, &show_ip_access_list_cmd);
install_element(ENABLE_NODE, &show_ip_access_list_name_cmd);
-
- /* Zebra access-list */
- install_element(CONFIG_NODE, &access_list_exact_cmd);
- install_element(CONFIG_NODE, &access_list_any_cmd);
- install_element(CONFIG_NODE, &no_access_list_exact_cmd);
- install_element(CONFIG_NODE, &no_access_list_any_cmd);
-
- /* Standard access-list */
- install_element(CONFIG_NODE, &access_list_standard_cmd);
- install_element(CONFIG_NODE, &access_list_standard_nomask_cmd);
- install_element(CONFIG_NODE, &access_list_standard_host_cmd);
- install_element(CONFIG_NODE, &access_list_standard_any_cmd);
- install_element(CONFIG_NODE, &no_access_list_standard_cmd);
- install_element(CONFIG_NODE, &no_access_list_standard_nomask_cmd);
- install_element(CONFIG_NODE, &no_access_list_standard_host_cmd);
- install_element(CONFIG_NODE, &no_access_list_standard_any_cmd);
-
- /* Extended access-list */
- install_element(CONFIG_NODE, &access_list_extended_cmd);
- install_element(CONFIG_NODE, &access_list_extended_any_mask_cmd);
- install_element(CONFIG_NODE, &access_list_extended_mask_any_cmd);
- install_element(CONFIG_NODE, &access_list_extended_any_any_cmd);
- install_element(CONFIG_NODE, &access_list_extended_host_mask_cmd);
- install_element(CONFIG_NODE, &access_list_extended_mask_host_cmd);
- install_element(CONFIG_NODE, &access_list_extended_host_host_cmd);
- install_element(CONFIG_NODE, &access_list_extended_any_host_cmd);
- install_element(CONFIG_NODE, &access_list_extended_host_any_cmd);
- install_element(CONFIG_NODE, &no_access_list_extended_cmd);
- install_element(CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
- install_element(CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
- install_element(CONFIG_NODE, &no_access_list_extended_any_any_cmd);
- install_element(CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
- install_element(CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
- install_element(CONFIG_NODE, &no_access_list_extended_host_host_cmd);
- install_element(CONFIG_NODE, &no_access_list_extended_any_host_cmd);
- install_element(CONFIG_NODE, &no_access_list_extended_host_any_cmd);
-
- install_element(CONFIG_NODE, &access_list_remark_cmd);
- install_element(CONFIG_NODE, &no_access_list_all_cmd);
- install_element(CONFIG_NODE, &no_access_list_remark_cmd);
- install_element(CONFIG_NODE, &no_access_list_remark_comment_cmd);
}
static int config_write_access_ipv6(struct vty *vty);
install_element(ENABLE_NODE, &show_ipv6_access_list_cmd);
install_element(ENABLE_NODE, &show_ipv6_access_list_name_cmd);
-
- install_element(CONFIG_NODE, &ipv6_access_list_exact_cmd);
- install_element(CONFIG_NODE, &ipv6_access_list_any_cmd);
- install_element(CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
- install_element(CONFIG_NODE, &no_ipv6_access_list_any_cmd);
-
- install_element(CONFIG_NODE, &no_ipv6_access_list_all_cmd);
- install_element(CONFIG_NODE, &ipv6_access_list_remark_cmd);
- install_element(CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
- install_element(CONFIG_NODE, &no_ipv6_access_list_remark_comment_cmd);
}
void access_list_init(void)
access_list_init_ipv4();
access_list_init_ipv6();
access_list_init_mac();
+
+ filter_cli_init();
}
void access_list_reset(void)
--- /dev/null
+/*
+ * FRR filter CLI implementation.
+ *
+ * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
+ * Rafael Zalamena
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+#include "zebra.h"
+
+#include "lib/command.h"
+#include "lib/filter.h"
+#include "lib/northbound_cli.h"
+
+#ifndef VTYSH_EXTRACT_PL
+#include "lib/filter_cli_clippy.c"
+#endif /* VTYSH_EXTRACT_PL */
+
+#define ACCESS_LIST_STR "Access list entry\n"
+#define ACCESS_LIST_LEG_STR "IP standard access list\n"
+#define ACCESS_LIST_LEG_EXT_STR "IP standard access list (expanded range)\n"
+#define ACCESS_LIST_ELEG_STR "IP extended access list\n"
+#define ACCESS_LIST_ELEG_EXT_STR "IP extended access list (expanded range)\n"
+#define ACCESS_LIST_XLEG_STR \
+ ACCESS_LIST_LEG_STR \
+ ACCESS_LIST_LEG_EXT_STR \
+ ACCESS_LIST_ELEG_STR \
+ ACCESS_LIST_ELEG_EXT_STR
+#define ACCESS_LIST_ZEBRA_STR "Access list entry\n"
+#define ACCESS_LIST_SEQ_STR \
+ "Sequence number of an entry\n" \
+ "Sequence number\n"
+#define ACCESS_LIST_ACTION_STR \
+ "Specify packets to reject\n" \
+ "Specify packets to forward\n"
+#define ACCESS_LIST_REMARK_STR "Access list entry comment\n"
+#define ACCESS_LIST_REMARK_LINE_STR "Comment up to 100 characters\n"
+
+/*
+ * Helper function to locate filter data structures for Cisco-style ACLs.
+ */
+static int64_t acl_cisco_get_seq(struct access_list *acl, const char *action,
+ const char *src, const char *src_mask,
+ const char *dst, const char *dst_mask)
+{
+ struct filter_cisco *fc;
+ struct filter f, *fn;
+
+ memset(&f, 0, sizeof(f));
+ memset(&fc, 0, sizeof(fc));
+ f.cisco = 1;
+ if (strcmp(action, "permit") == 0)
+ f.type = FILTER_PERMIT;
+ else
+ f.type = FILTER_DENY;
+
+ fc = &f.u.cfilter;
+ inet_pton(AF_INET, src, &fc->addr);
+ inet_pton(AF_INET, src_mask, &fc->addr_mask);
+ fc->addr.s_addr &= ~fc->addr_mask.s_addr;
+ if (dst != NULL) {
+ fc->extended = 1;
+ inet_pton(AF_INET, dst, &fc->mask);
+ inet_pton(AF_INET, dst_mask, &fc->mask_mask);
+ fc->mask.s_addr &= ~fc->mask_mask.s_addr;
+ }
+
+ fn = filter_lookup_cisco(acl, &f);
+ if (fn == NULL)
+ return -1;
+
+ return fn->seq;
+}
+
+/*
+ * Helper function to locate filter data structures for zebra-style ACLs.
+ */
+static int64_t acl_zebra_get_seq(struct access_list *acl, const char *action,
+ const struct prefix *p, bool exact)
+{
+ struct filter_zebra *fz;
+ struct filter f, *fn;
+
+ memset(&f, 0, sizeof(f));
+ memset(&fz, 0, sizeof(fz));
+ if (strcmp(action, "permit") == 0)
+ f.type = FILTER_PERMIT;
+ else
+ f.type = FILTER_DENY;
+
+ fz = &f.u.zfilter;
+ fz->prefix = *p;
+ fz->exact = exact;
+
+ fn = filter_lookup_zebra(acl, &f);
+ if (fn == NULL)
+ return -1;
+
+ return fn->seq;
+}
+
+/*
+ * Helper function to concatenate address with mask in Cisco style.
+ */
+static void concat_addr_mask_v4(const char *addr, const char *mask, char *dst,
+ size_t dstlen)
+{
+ struct in_addr ia;
+ int plen;
+
+ assert(inet_pton(AF_INET, mask, &ia) == 1);
+ plen = ip_masklen(ia);
+ snprintf(dst, dstlen, "%s/%d", addr, plen);
+}
+
+/*
+ * Cisco (legacy) access lists.
+ */
+DEFPY(
+ access_list_std, access_list_std_cmd,
+ "access-list <(1-99)|(1300-1999)>$number [seq (1-4294967295)$seq] <deny|permit>$action <[host] A.B.C.D$host|A.B.C.D$host A.B.C.D$mask|any>",
+ ACCESS_LIST_STR
+ ACCESS_LIST_LEG_STR
+ ACCESS_LIST_LEG_EXT_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "A single host address\n"
+ "Address to match\n"
+ "Address to match\n"
+ "Wildcard bits\n"
+ "Any source host\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int rv;
+ int64_t sseq;
+ char ipmask[64];
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+ char xpath_value[XPATH_MAXLEN + 64];
+
+ /*
+ * Create the access-list first, so we can generate sequence if
+ * none given (backward compatibility).
+ */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list-legacy[number='%s']", number_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ rv = nb_cli_apply_changes(vty, NULL);
+ if (rv != CMD_SUCCESS)
+ return rv;
+
+ /* Use access-list data structure to generate sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (seq_str == NULL) {
+ sseq = filter_new_seq_get(acl);
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ } else
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%s']", xpath, seq_str);
+
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_value, sizeof(xpath_value), "%s/action", xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, action);
+
+ if (host_str != NULL && mask_str == NULL) {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/host",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, host_str);
+ } else if (host_str != NULL && mask_str != NULL) {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/network",
+ xpath_entry);
+ concat_addr_mask_v4(host_str, mask_str, ipmask, sizeof(ipmask));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, ipmask);
+ } else {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/any",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+ }
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ no_access_list_std, no_access_list_std_cmd,
+ "no access-list <(1-99)|(1300-1999)>$number [seq (1-4294967295)$seq] <deny|permit>$action <[host] A.B.C.D$host|A.B.C.D$host A.B.C.D$mask|any>",
+ NO_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_LEG_STR
+ ACCESS_LIST_LEG_EXT_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "A single host address\n"
+ "Address to match\n"
+ "Address to match\n"
+ "Wildcard bits\n"
+ "Any source host\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int64_t sseq;
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+
+ /* If the user provided sequence number, then just go for it. */
+ if (seq_str != NULL) {
+ snprintf(
+ xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list-legacy[number='%s']/entry[sequence='%s']",
+ number_str, seq_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+ }
+
+ /* Otherwise, to keep compatibility, we need to figure it out. */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list-legacy[number='%s']", number_str);
+
+ /* Access-list must exist before entries. */
+ if (yang_dnode_exists(running_config->dnode, xpath) == false)
+ return CMD_WARNING;
+
+ /* Use access-list data structure to fetch sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (host_str != NULL)
+ sseq = acl_cisco_get_seq(acl, action, host_str,
+ mask_str ? mask_str : "0.0.0.0", NULL,
+ NULL);
+ else
+ sseq = acl_cisco_get_seq(acl, action, "0.0.0.0",
+ "255.255.255.255", NULL, NULL);
+ if (sseq == -1)
+ return CMD_WARNING;
+
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ access_list_ext, access_list_ext_cmd,
+ "access-list <(100-199)|(2000-2699)>$number [seq (1-4294967295)$seq] <deny|permit>$action ip <A.B.C.D$src A.B.C.D$src_mask|host A.B.C.D$src|any> <A.B.C.D$dst A.B.C.D$dst_mask|host A.B.C.D$dst|any>",
+ ACCESS_LIST_STR
+ ACCESS_LIST_ELEG_STR
+ ACCESS_LIST_ELEG_EXT_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "IPv4 address\n"
+ "Source address to match\n"
+ "Source address mask to apply\n"
+ "Single source host\n"
+ "Source address to match\n"
+ "Any source host\n"
+ "Destination address to match\n"
+ "Destination address mask to apply\n"
+ "Single destination host\n"
+ "Destination address to match\n"
+ "Any destination host\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int rv;
+ int64_t sseq;
+ char ipmask[64];
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+ char xpath_value[XPATH_MAXLEN + 64];
+
+ /*
+ * Create the access-list first, so we can generate sequence if
+ * none given (backward compatibility).
+ */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list-legacy[number='%s']", number_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ rv = nb_cli_apply_changes(vty, NULL);
+ if (rv != CMD_SUCCESS)
+ return rv;
+
+ /* Use access-list data structure to generate sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (seq_str == NULL) {
+ sseq = filter_new_seq_get(acl);
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ } else
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%s']", xpath, seq_str);
+
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_value, sizeof(xpath_value), "%s/action", xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, action);
+
+ if (src_str != NULL && src_mask_str == NULL) {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/host",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, src_str);
+ } else if (src_str != NULL && src_mask_str != NULL) {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/network",
+ xpath_entry);
+ concat_addr_mask_v4(src_str, src_mask_str, ipmask,
+ sizeof(ipmask));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, ipmask);
+ } else {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/any",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+ }
+
+ if (dst_str != NULL && dst_mask_str == NULL) {
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/destination-host", xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, src_str);
+ } else if (dst_str != NULL && dst_mask_str != NULL) {
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/destination-network", xpath_entry);
+ concat_addr_mask_v4(dst_str, dst_mask_str, ipmask,
+ sizeof(ipmask));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, ipmask);
+ } else {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/destination-any",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+ }
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ no_access_list_ext, no_access_list_ext_cmd,
+ "no access-list <(100-199)|(2000-2699)>$number [seq (1-4294967295)$seq] <deny|permit>$action ip <A.B.C.D$src A.B.C.D$src_mask|host A.B.C.D$src|any> <A.B.C.D$dst A.B.C.D$dst_mask|host A.B.C.D$dst|any>",
+ NO_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ELEG_STR
+ ACCESS_LIST_ELEG_EXT_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "Any Internet Protocol\n"
+ "Source address to match\n"
+ "Source address mask to apply\n"
+ "Single source host\n"
+ "Source address to match\n"
+ "Any source host\n"
+ "Destination address to match\n"
+ "Destination address mask to apply\n"
+ "Single destination host\n"
+ "Destination address to match\n"
+ "Any destination host\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int64_t sseq;
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+
+ /* If the user provided sequence number, then just go for it. */
+ if (seq_str != NULL) {
+ snprintf(
+ xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list-legacy[number='%s']/entry[sequence='%s']",
+ number_str, seq_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+ }
+
+ /* Otherwise, to keep compatibility, we need to figure it out. */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list-legacy[number='%s']", number_str);
+
+ /* Access-list must exist before entries. */
+ if (yang_dnode_exists(running_config->dnode, xpath) == false)
+ return CMD_WARNING;
+
+ /* Use access-list data structure to fetch sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (src_str != NULL) {
+ if (dst_str != NULL)
+ sseq = acl_cisco_get_seq(
+ acl, action, src_str,
+ src_mask_str ? src_mask_str : "0.0.0.0",
+ dst_str,
+ dst_mask_str ? dst_mask_str : "0.0.0.0");
+ else
+ sseq = acl_cisco_get_seq(acl, action, src_str,
+ src_mask_str ? src_mask_str
+ : "0.0.0.0",
+ "0.0.0.0", "255.255.255.255");
+ } else {
+ if (dst_str != NULL)
+ sseq = acl_cisco_get_seq(acl, action, "0.0.0.0",
+ "255.255.255.255", dst_str,
+ dst_mask_str ? dst_mask_str
+ : "0.0.0.0");
+ else
+ sseq = acl_cisco_get_seq(acl, action, "0.0.0.0",
+ "255.255.255.255", "0.0.0.0",
+ "255.255.255.255");
+ }
+ if (sseq == -1)
+ return CMD_WARNING;
+
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ no_access_list_legacy, no_access_list_legacy_cmd,
+ "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)>$number",
+ NO_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_XLEG_STR)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list-legacy[number='%s']", number_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ access_list_legacy_remark, access_list_legacy_remark_cmd,
+ "access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)>$number remark LINE...",
+ ACCESS_LIST_STR
+ ACCESS_LIST_XLEG_STR
+ ACCESS_LIST_REMARK_STR
+ ACCESS_LIST_REMARK_LINE_STR)
+{
+ int rv;
+ char *remark;
+ char xpath[XPATH_MAXLEN];
+ char xpath_remark[XPATH_MAXLEN + 32];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list-legacy[number='%s']", number_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_remark, sizeof(xpath_remark), "%s/remark", xpath);
+ remark = argv_concat(argv, argc, 3);
+ nb_cli_enqueue_change(vty, xpath_remark, NB_OP_CREATE, remark);
+ rv = nb_cli_apply_changes(vty, NULL);
+ XFREE(MTYPE_TMP, remark);
+
+ return rv;
+}
+
+DEFPY(
+ no_access_list_legacy_remark, no_access_list_legacy_remark_cmd,
+ "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)>$number remark",
+ NO_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_XLEG_STR
+ ACCESS_LIST_REMARK_STR)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list-legacy[number='%s']/remark",
+ number_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+/*
+ * Zebra access lists.
+ */
+DEFPY(
+ access_list, access_list_cmd,
+ "access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <A.B.C.D/M$prefix [exact-match$exact]|any>",
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "Prefix to match. e.g. 10.0.0.0/8\n"
+ "Exact match of the prefixes\n"
+ "Match any IPv4\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int rv;
+ int64_t sseq;
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+ char xpath_value[XPATH_MAXLEN + 64];
+
+ /*
+ * Create the access-list first, so we can generate sequence if
+ * none given (backward compatibility).
+ */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv4'][name='%s']", name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ rv = nb_cli_apply_changes(vty, NULL);
+ if (rv != CMD_SUCCESS)
+ return rv;
+
+ /* Use access-list data structure to generate sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (seq_str == NULL) {
+ sseq = filter_new_seq_get(acl);
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ } else
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%s']", xpath, seq_str);
+
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_value, sizeof(xpath_value), "%s/action", xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, action);
+
+ if (prefix_str != NULL) {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/ipv4-prefix",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+ prefix_str);
+
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/ipv4-exact-match", xpath_entry);
+ if (exact)
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE,
+ NULL);
+ else
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
+ NULL);
+ } else {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/any",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+ }
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ no_access_list, no_access_list_cmd,
+ "no access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <A.B.C.D/M$prefix [exact-match$exact]|any>",
+ NO_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "Prefix to match. e.g. 10.0.0.0/8\n"
+ "Exact match of the prefixes\n"
+ "Match any IPv4\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int64_t sseq;
+ struct prefix pany;
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+
+ /* If the user provided sequence number, then just go for it. */
+ if (seq_str != NULL) {
+ snprintf(
+ xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv4'][name='%s']/entry[sequence='%s']",
+ name, seq_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+ }
+
+ /* Otherwise, to keep compatibility, we need to figure it out. */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv4'][name='%s']", name);
+
+ /* Access-list must exist before entries. */
+ if (yang_dnode_exists(running_config->dnode, xpath) == false)
+ return CMD_WARNING;
+
+ /* Use access-list data structure to fetch sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (prefix == NULL) {
+ memset(&pany, 0, sizeof(pany));
+ pany.family = AF_INET;
+ sseq = acl_zebra_get_seq(acl, action, &pany, exact);
+ } else
+ sseq = acl_zebra_get_seq(acl, action, (struct prefix *)prefix,
+ exact);
+ if (sseq == -1)
+ return CMD_WARNING;
+
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ no_access_list_all, no_access_list_all_cmd,
+ "no access-list WORD$name",
+ NO_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv4'][name='%s']", name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ access_list_remark, access_list_remark_cmd,
+ "access-list WORD$name remark LINE...",
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_REMARK_STR
+ ACCESS_LIST_REMARK_LINE_STR)
+{
+ int rv;
+ char *remark;
+ char xpath[XPATH_MAXLEN];
+ char xpath_remark[XPATH_MAXLEN + 32];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv4'][name='%s']", name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_remark, sizeof(xpath_remark), "%s/remark", xpath);
+ remark = argv_concat(argv, argc, 3);
+ nb_cli_enqueue_change(vty, xpath_remark, NB_OP_CREATE, remark);
+ rv = nb_cli_apply_changes(vty, NULL);
+ XFREE(MTYPE_TMP, remark);
+
+ return rv;
+}
+
+DEFPY(
+ no_access_list_remark, no_access_list_remark_cmd,
+ "no access-list WORD$name remark",
+ NO_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_REMARK_STR)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv4'][name='%s']/remark",
+ name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ ipv6_access_list, ipv6_access_list_cmd,
+ "ipv6 access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X::X:X/M$prefix [exact-match$exact]|any>",
+ IPV6_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "IPv6 prefix\n"
+ "Exact match of the prefixes\n"
+ "Match any IPv6\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int rv;
+ int64_t sseq;
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+ char xpath_value[XPATH_MAXLEN + 64];
+
+ /*
+ * Create the access-list first, so we can generate sequence if
+ * none given (backward compatibility).
+ */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv6'][name='%s']", name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ rv = nb_cli_apply_changes(vty, NULL);
+ if (rv != CMD_SUCCESS)
+ return rv;
+
+ /* Use access-list data structure to generate sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (seq_str == NULL) {
+ sseq = filter_new_seq_get(acl);
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ } else
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%s']", xpath, seq_str);
+
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_value, sizeof(xpath_value), "%s/action", xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, action);
+
+ if (prefix_str != NULL) {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/ipv6-prefix",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+ prefix_str);
+
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/ipv6-exact-match", xpath_entry);
+ if (exact)
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE,
+ NULL);
+ else
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
+ NULL);
+ } else {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/any",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+ }
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ no_ipv6_access_list, no_ipv6_access_list_cmd,
+ "no ipv6 access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X::X:X/M$prefix [exact-match$exact]|any>",
+ NO_STR
+ IPV6_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "IPv6 prefix\n"
+ "Exact match of the prefixes\n"
+ "Match any IPv6\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int64_t sseq;
+ struct prefix pany;
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+
+ /* If the user provided sequence number, then just go for it. */
+ if (seq_str != NULL) {
+ snprintf(
+ xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv6'][name='%s']/entry[sequence='%s']",
+ name, seq_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+ }
+
+ /* Otherwise, to keep compatibility, we need to figure it out. */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv6'][name='%s']", name);
+
+ /* Access-list must exist before entries. */
+ if (yang_dnode_exists(running_config->dnode, xpath) == false)
+ return CMD_WARNING;
+
+ /* Use access-list data structure to fetch sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (prefix == NULL) {
+ memset(&pany, 0, sizeof(pany));
+ pany.family = AF_INET6;
+ sseq = acl_zebra_get_seq(acl, action, &pany, exact);
+ } else
+ sseq = acl_zebra_get_seq(acl, action, (struct prefix *)prefix,
+ exact);
+ if (sseq == -1)
+ return CMD_WARNING;
+
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ no_ipv6_access_list_all, no_ipv6_access_list_all_cmd,
+ "no ipv6 access-list WORD$name",
+ NO_STR
+ IPV6_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv6'][name='%s']", name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ ipv6_access_list_remark, ipv6_access_list_remark_cmd,
+ "ipv6 access-list WORD$name remark LINE...",
+ IPV6_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_REMARK_STR
+ ACCESS_LIST_REMARK_LINE_STR)
+{
+ int rv;
+ char *remark;
+ char xpath[XPATH_MAXLEN];
+ char xpath_remark[XPATH_MAXLEN + 32];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv6'][name='%s']", name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_remark, sizeof(xpath_remark), "%s/remark", xpath);
+ remark = argv_concat(argv, argc, 3);
+ nb_cli_enqueue_change(vty, xpath_remark, NB_OP_CREATE, remark);
+ rv = nb_cli_apply_changes(vty, NULL);
+ XFREE(MTYPE_TMP, remark);
+
+ return rv;
+}
+
+DEFPY(
+ no_ipv6_access_list_remark, no_ipv6_access_list_remark_cmd,
+ "no ipv6 access-list WORD$name remark",
+ NO_STR
+ IPV6_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_REMARK_STR)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='ipv6'][name='%s']/remark",
+ name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ mac_access_list, mac_access_list_cmd,
+ "mac access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>",
+ MAC_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "MAC address\n"
+ "Match any MAC address\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int rv;
+ int64_t sseq;
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+ char xpath_value[XPATH_MAXLEN + 64];
+
+ /*
+ * Create the access-list first, so we can generate sequence if
+ * none given (backward compatibility).
+ */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='mac'][name='%s']", name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ rv = nb_cli_apply_changes(vty, NULL);
+ if (rv != CMD_SUCCESS)
+ return rv;
+
+ /* Use access-list data structure to generate sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (seq_str == NULL) {
+ sseq = filter_new_seq_get(acl);
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ } else
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%s']", xpath, seq_str);
+
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_value, sizeof(xpath_value), "%s/action", xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, action);
+
+ if (mac_str != NULL) {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/mac",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, mac_str);
+ } else {
+ snprintf(xpath_value, sizeof(xpath_value), "%s/any",
+ xpath_entry);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+ }
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ no_mac_access_list, no_mac_access_list_cmd,
+ "no mac access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X::X:X/M$prefix [exact-match$exact]|any>",
+ NO_STR
+ MAC_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_SEQ_STR
+ ACCESS_LIST_ACTION_STR
+ "MAC address\n"
+ "Exact match of the prefixes\n"
+ "Match any MAC address\n")
+{
+ struct access_list *acl;
+ struct lyd_node *dnode;
+ int64_t sseq;
+ struct prefix pany;
+ char xpath[XPATH_MAXLEN];
+ char xpath_entry[XPATH_MAXLEN + 32];
+
+ /* If the user provided sequence number, then just go for it. */
+ if (seq_str != NULL) {
+ snprintf(
+ xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='mac'][name='%s']/entry[sequence='%s']",
+ name, seq_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+ }
+
+ /* Otherwise, to keep compatibility, we need to figure it out. */
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='mac'][name='%s']", name);
+
+ /* Access-list must exist before entries. */
+ if (yang_dnode_exists(running_config->dnode, xpath) == false)
+ return CMD_WARNING;
+
+ /* Use access-list data structure to fetch sequence. */
+ dnode = yang_dnode_get(running_config->dnode, xpath);
+ acl = nb_running_get_entry(dnode, NULL, true);
+ if (prefix == NULL) {
+ memset(&pany, 0, sizeof(pany));
+ pany.family = AF_ETHERNET;
+ sseq = acl_zebra_get_seq(acl, action, &pany, exact);
+ } else
+ sseq = acl_zebra_get_seq(acl, action, (struct prefix *)prefix,
+ exact);
+ if (sseq == -1)
+ return CMD_WARNING;
+
+ snprintf(xpath_entry, sizeof(xpath_entry),
+ "%s/entry[sequence='%" PRId64 "']", xpath, sseq);
+ nb_cli_enqueue_change(vty, xpath_entry, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ no_mac_access_list_all, no_mac_access_list_all_cmd,
+ "no mac access-list WORD$name",
+ NO_STR
+ MAC_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='mac'][name='%s']", name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+ mac_access_list_remark, mac_access_list_remark_cmd,
+ "mac access-list WORD$name remark LINE...",
+ MAC_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_REMARK_STR
+ ACCESS_LIST_REMARK_LINE_STR)
+{
+ int rv;
+ char *remark;
+ char xpath[XPATH_MAXLEN];
+ char xpath_remark[XPATH_MAXLEN + 32];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='mac'][name='%s']", name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_remark, sizeof(xpath_remark), "%s/remark", xpath);
+ remark = argv_concat(argv, argc, 3);
+ nb_cli_enqueue_change(vty, xpath_remark, NB_OP_CREATE, remark);
+ rv = nb_cli_apply_changes(vty, NULL);
+ XFREE(MTYPE_TMP, remark);
+
+ return rv;
+}
+
+DEFPY(
+ no_mac_access_list_remark, no_mac_access_list_remark_cmd,
+ "no mac access-list WORD$name remark",
+ NO_STR
+ MAC_STR
+ ACCESS_LIST_STR
+ ACCESS_LIST_ZEBRA_STR
+ ACCESS_LIST_REMARK_STR)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath),
+ "/frr-filter:lib/access-list[type='mac'][name='%s']/remark",
+ name);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+void filter_cli_init(void)
+{
+ /* access-list cisco-style (legacy). */
+ install_element(CONFIG_NODE, &access_list_std_cmd);
+ install_element(CONFIG_NODE, &no_access_list_std_cmd);
+ install_element(CONFIG_NODE, &access_list_ext_cmd);
+ install_element(CONFIG_NODE, &no_access_list_ext_cmd);
+ install_element(CONFIG_NODE, &no_access_list_legacy_cmd);
+ install_element(CONFIG_NODE, &access_list_legacy_remark_cmd);
+ install_element(CONFIG_NODE, &no_access_list_legacy_remark_cmd);
+
+ /* access-list zebra-style. */
+ install_element(CONFIG_NODE, &access_list_cmd);
+ install_element(CONFIG_NODE, &no_access_list_cmd);
+ install_element(CONFIG_NODE, &no_access_list_all_cmd);
+ install_element(CONFIG_NODE, &access_list_remark_cmd);
+ install_element(CONFIG_NODE, &no_access_list_remark_cmd);
+
+ install_element(CONFIG_NODE, &ipv6_access_list_cmd);
+ install_element(CONFIG_NODE, &no_ipv6_access_list_cmd);
+ install_element(CONFIG_NODE, &no_ipv6_access_list_all_cmd);
+ install_element(CONFIG_NODE, &ipv6_access_list_remark_cmd);
+ install_element(CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
+
+ install_element(CONFIG_NODE, &mac_access_list_cmd);
+ install_element(CONFIG_NODE, &no_mac_access_list_cmd);
+ install_element(CONFIG_NODE, &no_mac_access_list_all_cmd);
+ install_element(CONFIG_NODE, &mac_access_list_remark_cmd);
+ install_element(CONFIG_NODE, &no_mac_access_list_remark_cmd);
+}