summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/atomlist.h10
-rw-r--r--lib/compiler.h7
-rw-r--r--lib/ferr.c12
-rw-r--r--lib/ferr.h1
-rw-r--r--lib/filter.c1373
-rw-r--r--lib/libfrr.c1
-rw-r--r--lib/prefix.c50
-rw-r--r--lib/prefix.h14
-rw-r--r--lib/routemap.c203
-rw-r--r--lib/routemap.h38
-rw-r--r--lib/typerb.c5
-rw-r--r--lib/typerb.h23
-rw-r--r--lib/typesafe.c13
-rw-r--r--lib/typesafe.h51
14 files changed, 1379 insertions, 422 deletions
diff --git a/lib/atomlist.h b/lib/atomlist.h
index e4098ccb54..621db6824f 100644
--- a/lib/atomlist.h
+++ b/lib/atomlist.h
@@ -135,8 +135,10 @@ macro_inline void prefix ## _add_tail(struct prefix##_head *h, type *item) \
macro_inline void prefix ## _del_hint(struct prefix##_head *h, type *item, \
_Atomic atomptr_t *hint) \
{ atomlist_del_hint(&h->ah, &item->field.ai, hint); } \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
-{ atomlist_del_hint(&h->ah, &item->field.ai, NULL); } \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
+{ atomlist_del_hint(&h->ah, &item->field.ai, NULL); \
+ /* TODO: Return NULL if not found */ \
+ return item; } \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ char *p = (char *)atomlist_pop(&h->ah); \
return p ? (type *)(p - offsetof(type, field)) : NULL; } \
@@ -273,9 +275,11 @@ macro_inline void prefix ## _del_hint(struct prefix##_head *h, type *item, \
{ \
atomsort_del_hint(&h->ah, &item->field.ai, hint); \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
atomsort_del_hint(&h->ah, &item->field.ai, NULL); \
+ /* TODO: Return NULL if not found */ \
+ return item; \
} \
macro_inline size_t prefix ## _count(struct prefix##_head *h) \
{ \
diff --git a/lib/compiler.h b/lib/compiler.h
index 7c7f4ce294..6700ca9e8b 100644
--- a/lib/compiler.h
+++ b/lib/compiler.h
@@ -165,6 +165,13 @@ extern "C" {
_min_a < _min_b ? _min_a : _min_b; \
})
+#define numcmp(a, b) \
+ ({ \
+ typeof(a) _cmp_a = (a); \
+ typeof(b) _cmp_b = (b); \
+ (_cmp_a < _cmp_b) ? -1 : ((_cmp_a > _cmp_b) ? 1 : 0); \
+ })
+
#ifndef offsetof
#ifdef __compiler_offsetof
#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE,MEMBER)
diff --git a/lib/ferr.c b/lib/ferr.c
index 65c0cf886d..8afc926c41 100644
--- a/lib/ferr.c
+++ b/lib/ferr.c
@@ -126,10 +126,8 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json)
if (code) {
ref = log_ref_get(code);
- if (!ref) {
- vty_out(vty, "Code %"PRIu32" - Unknown\n", code);
+ if (!ref)
return;
- }
listnode_add(errlist, ref);
}
@@ -197,8 +195,6 @@ void log_ref_init(void)
"Error Reference Texts");
}
pthread_mutex_unlock(&refs_mtx);
-
- install_element(VIEW_NODE, &show_error_code_cmd);
}
void log_ref_fini(void)
@@ -212,6 +208,12 @@ void log_ref_fini(void)
pthread_mutex_unlock(&refs_mtx);
}
+void log_ref_vty_init(void)
+{
+ install_element(VIEW_NODE, &show_error_code_cmd);
+}
+
+
const struct ferr *ferr_get_last(ferr_r errval)
{
struct ferr *last_error = pthread_getspecific(errkey);
diff --git a/lib/ferr.h b/lib/ferr.h
index 93d0ced538..a89b595e87 100644
--- a/lib/ferr.h
+++ b/lib/ferr.h
@@ -158,6 +158,7 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json);
*/
void log_ref_init(void);
void log_ref_fini(void);
+void log_ref_vty_init(void);
/* get error details.
*
diff --git a/lib/filter.c b/lib/filter.c
index 276df4b4d7..14b89217b8 100644
--- a/lib/filter.c
+++ b/lib/filter.c
@@ -60,6 +60,9 @@ struct filter {
/* Filter type information. */
enum filter_type type;
+ /* Sequence number */
+ int64_t seq;
+
/* Cisco access-list */
int cisco;
@@ -406,23 +409,35 @@ void access_list_delete_hook(void (*func)(struct access_list *access))
access_master_mac.delete_hook = func;
}
-/* Add new filter to the end of specified access_list. */
-static void access_list_filter_add(struct access_list *access,
- struct filter *filter)
+/* Calculate new sequential number. */
+static int64_t filter_new_seq_get(struct access_list *access)
{
- filter->next = NULL;
- filter->prev = access->tail;
+ int64_t maxseq;
+ int64_t newseq;
+ struct filter *filter;
- if (access->tail)
- access->tail->next = filter;
- else
- access->head = filter;
- access->tail = filter;
+ maxseq = newseq = 0;
- /* Run hook function. */
- if (access->master->add_hook)
- (*access->master->add_hook)(access);
- route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_ADDED);
+ for (filter = access->head; filter; filter = filter->next) {
+ if (maxseq < filter->seq)
+ maxseq = filter->seq;
+ }
+
+ newseq = ((maxseq / 5) * 5) + 5;
+
+ return (newseq > UINT_MAX) ? UINT_MAX : newseq;
+}
+
+/* Return access list entry which has same seq number. */
+static struct filter *filter_seq_check(struct access_list *access,
+ int64_t seq)
+{
+ struct filter *filter;
+
+ for (filter = access->head; filter; filter = filter->next)
+ if (filter->seq == seq)
+ return filter;
+ return NULL;
}
/* If access_list has no filter then return 1. */
@@ -465,6 +480,58 @@ static void access_list_filter_delete(struct access_list *access,
access_list_delete(access);
}
+/* Add new filter to the end of specified access_list. */
+static void access_list_filter_add(struct access_list *access,
+ struct filter *filter)
+{
+ struct filter *replace;
+ struct filter *point;
+
+ /* Automatic asignment of seq no. */
+ if (filter->seq == -1)
+ filter->seq = filter_new_seq_get(access);
+
+ if (access->tail && filter->seq > access->tail->seq)
+ point = NULL;
+ else {
+ /* Is there any same seq access list filter? */
+ replace = filter_seq_check(access, filter->seq);
+ if (replace)
+ access_list_filter_delete(access, replace);
+
+ /* Check insert point. */
+ for (point = access->head; point; point = point->next)
+ if (point->seq >= filter->seq)
+ break;
+ }
+
+ /* In case of this is the first element of the list. */
+ filter->next = point;
+
+ if (point) {
+ if (point->prev)
+ point->prev->next = filter;
+ else
+ access->head = filter;
+
+ filter->prev = point->prev;
+ point->prev = filter;
+ } else {
+ if (access->tail)
+ access->tail->next = filter;
+ else
+ access->head = filter;
+
+ filter->prev = access->tail;
+ access->tail = filter;
+ }
+
+ /* Run hook function. */
+ if (access->master->add_hook)
+ (*access->master->add_hook)(access);
+ route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_ADDED);
+}
+
/*
deny Specify packets to reject
permit Specify packets to forward
@@ -553,12 +620,13 @@ static int vty_access_list_remark_unset(struct vty *vty, afi_t afi,
}
static int filter_set_cisco(struct vty *vty, const char *name_str,
- 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)
+ 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;
+ enum filter_type type = FILTER_DENY;
struct filter *mfilter;
struct filter_cisco *filter;
struct access_list *access;
@@ -566,15 +634,21 @@ static int filter_set_cisco(struct vty *vty, const char *name_str,
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 (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;
+ 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);
@@ -606,6 +680,7 @@ static int filter_set_cisco(struct vty *vty, const char *name_str,
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;
@@ -640,163 +715,311 @@ static int filter_set_cisco(struct vty *vty, const char *name_str,
/* Standard access-list */
DEFUN (access_list_standard,
access_list_standard_cmd,
- "access-list <(1-99)|(1300-1999)> <deny|permit> A.B.C.D A.B.C.D",
+ "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_permit_deny = 2;
- int idx_ipv4 = 3;
- int idx_ipv4_2 = 4;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, NULL, NULL, 0, 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)> <deny|permit> A.B.C.D",
+ "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_permit_deny = 2;
- int idx_ipv4 = 3;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- "0.0.0.0", NULL, NULL, 0, 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)> <deny|permit> host A.B.C.D",
+ "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_permit_deny = 2;
- int idx_ipv4 = 4;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- "0.0.0.0", NULL, NULL, 0, 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)> <deny|permit> any",
+ "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_permit_deny = 2;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, "0.0.0.0",
- "255.255.255.255", NULL, NULL, 0, 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)> <deny|permit> A.B.C.D A.B.C.D",
+ "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_permit_deny = 3;
- int idx_ipv4 = 4;
- int idx_ipv4_2 = 5;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, NULL, NULL, 0, 0);
+ 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, 0);
}
DEFUN (no_access_list_standard_nomask,
no_access_list_standard_nomask_cmd,
- "no access-list <(1-99)|(1300-1999)> <deny|permit> A.B.C.D",
+ "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_permit_deny = 3;
- int idx_ipv4 = 4;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- "0.0.0.0", NULL, NULL, 0, 0);
+ 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)> <deny|permit> host A.B.C.D",
+ "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_permit_deny = 3;
- int idx_ipv4 = 5;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- "0.0.0.0", NULL, NULL, 0, 0);
+ 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)> <deny|permit> any",
+ "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_permit_deny = 3;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, "0.0.0.0",
- "255.255.255.255", NULL, NULL, 0, 0);
+ 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)> <deny|permit> ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
+ "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"
@@ -806,23 +1029,45 @@ DEFUN (access_list_extended,
"Destination Wildcard bits\n")
{
int idx_acl = 1;
- int idx_permit_deny = 2;
- int idx_ipv4 = 4;
- int idx_ipv4_2 = 5;
- int idx_ipv4_3 = 6;
- int idx_ipv4_4 = 7;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, argv[idx_ipv4_3]->arg,
- argv[idx_ipv4_4]->arg, 1, 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)> <deny|permit> ip A.B.C.D A.B.C.D any",
+ "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"
@@ -831,21 +1076,42 @@ DEFUN (access_list_extended_mask_any,
"Any destination host\n")
{
int idx_acl = 1;
- int idx_permit_deny = 2;
- int idx_ipv4 = 4;
- int idx_ipv4_2 = 5;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, "0.0.0.0",
- "255.255.255.255", 1, 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)> <deny|permit> ip any A.B.C.D A.B.C.D",
+ "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"
@@ -854,21 +1120,42 @@ DEFUN (access_list_extended_any_mask,
"Destination Wildcard bits\n")
{
int idx_acl = 1;
- int idx_permit_deny = 2;
- int idx_ipv4 = 5;
- int idx_ipv4_2 = 6;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, "0.0.0.0",
- "255.255.255.255", argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, 1, 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)> <deny|permit> ip any any",
+ "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"
@@ -876,18 +1163,33 @@ DEFUN (access_list_extended_any_any,
"Any destination host\n")
{
int idx_acl = 1;
- int idx_permit_deny = 2;
- return filter_set_cisco(
- vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
- "255.255.255.255", "0.0.0.0", "255.255.255.255", 1, 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)> <deny|permit> ip A.B.C.D A.B.C.D host A.B.C.D",
+ "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"
@@ -897,22 +1199,43 @@ DEFUN (access_list_extended_mask_host,
"Destination address\n")
{
int idx_acl = 1;
- int idx_permit_deny = 2;
- int idx_ipv4 = 4;
- int idx_ipv4_2 = 5;
- int idx_ipv4_3 = 7;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, argv[idx_ipv4_3]->arg,
- "0.0.0.0", 1, 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)> <deny|permit> ip host A.B.C.D A.B.C.D A.B.C.D",
+ "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"
@@ -922,22 +1245,43 @@ DEFUN (access_list_extended_host_mask,
"Destination Wildcard bits\n")
{
int idx_acl = 1;
- int idx_permit_deny = 2;
- int idx_ipv4 = 5;
- int idx_ipv4_2 = 6;
- int idx_ipv4_3 = 7;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- "0.0.0.0", argv[idx_ipv4_2]->arg,
- argv[idx_ipv4_3]->arg, 1, 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)> <deny|permit> ip host A.B.C.D host A.B.C.D",
+ "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"
@@ -947,21 +1291,41 @@ DEFUN (access_list_extended_host_host,
"Destination address\n")
{
int idx_acl = 1;
- int idx_permit_deny = 2;
- int idx_ipv4 = 5;
- int idx_ipv4_2 = 7;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- "0.0.0.0", argv[idx_ipv4_2]->arg, "0.0.0.0", 1,
- 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)> <deny|permit> ip any host A.B.C.D",
+ "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"
@@ -970,19 +1334,39 @@ DEFUN (access_list_extended_any_host,
"Destination address\n")
{
int idx_acl = 1;
- int idx_permit_deny = 2;
- int idx_ipv4 = 6;
- return filter_set_cisco(
- vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
- "255.255.255.255", argv[idx_ipv4]->arg, "0.0.0.0", 1, 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)> <deny|permit> ip host A.B.C.D any",
+ "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"
@@ -991,20 +1375,39 @@ DEFUN (access_list_extended_host_any,
"Any destination host\n")
{
int idx_acl = 1;
- int idx_permit_deny = 2;
- int idx_ipv4 = 5;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ 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)> <deny|permit> ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
+ "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"
@@ -1014,24 +1417,46 @@ DEFUN (no_access_list_extended,
"Destination Wildcard bits\n")
{
int idx_acl = 2;
- int idx_permit_deny = 3;
- int idx_ipv4 = 5;
- int idx_ipv4_2 = 6;
- int idx_ipv4_3 = 7;
- int idx_ipv4_4 = 8;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, argv[idx_ipv4_3]->arg,
- argv[idx_ipv4_4]->arg, 1, 0);
+ 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)> <deny|permit> ip A.B.C.D A.B.C.D any",
+ "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"
@@ -1040,22 +1465,43 @@ DEFUN (no_access_list_extended_mask_any,
"Any destination host\n")
{
int idx_acl = 2;
- int idx_permit_deny = 3;
- int idx_ipv4 = 5;
- int idx_ipv4_2 = 6;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, "0.0.0.0",
- "255.255.255.255", 1, 0);
+ 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)> <deny|permit> ip any A.B.C.D A.B.C.D",
+ "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"
@@ -1064,22 +1510,43 @@ DEFUN (no_access_list_extended_any_mask,
"Destination Wildcard bits\n")
{
int idx_acl = 2;
- int idx_permit_deny = 3;
- int idx_ipv4 = 6;
- int idx_ipv4_2 = 7;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, "0.0.0.0",
- "255.255.255.255", argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, 1, 0);
+ 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)> <deny|permit> ip any any",
+ "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"
@@ -1087,19 +1554,34 @@ DEFUN (no_access_list_extended_any_any,
"Any destination host\n")
{
int idx_acl = 2;
- int idx_permit_deny = 3;
- return filter_set_cisco(
- vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
- "255.255.255.255", "0.0.0.0", "255.255.255.255", 1, 0);
+ 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)> <deny|permit> ip A.B.C.D A.B.C.D host A.B.C.D",
+ "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"
@@ -1109,23 +1591,44 @@ DEFUN (no_access_list_extended_mask_host,
"Destination address\n")
{
int idx_acl = 2;
- int idx_permit_deny = 3;
- int idx_ipv4 = 5;
- int idx_ipv4_2 = 6;
- int idx_ipv4_3 = 8;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg, argv[idx_ipv4_3]->arg,
- "0.0.0.0", 1, 0);
+ 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)> <deny|permit> ip host A.B.C.D A.B.C.D A.B.C.D",
+ "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"
@@ -1135,23 +1638,44 @@ DEFUN (no_access_list_extended_host_mask,
"Destination Wildcard bits\n")
{
int idx_acl = 2;
- int idx_permit_deny = 3;
- int idx_ipv4 = 6;
- int idx_ipv4_2 = 7;
- int idx_ipv4_3 = 8;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- "0.0.0.0", argv[idx_ipv4_2]->arg,
- argv[idx_ipv4_3]->arg, 1, 0);
+ 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)> <deny|permit> ip host A.B.C.D host A.B.C.D",
+ "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"
@@ -1161,22 +1685,42 @@ DEFUN (no_access_list_extended_host_host,
"Destination address\n")
{
int idx_acl = 2;
- int idx_permit_deny = 3;
- int idx_ipv4 = 6;
- int idx_ipv4_2 = 8;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
- "0.0.0.0", argv[idx_ipv4_2]->arg, "0.0.0.0", 1,
- 0);
+ 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)> <deny|permit> ip any host A.B.C.D",
+ "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"
@@ -1185,20 +1729,40 @@ DEFUN (no_access_list_extended_any_host,
"Destination address\n")
{
int idx_acl = 2;
- int idx_permit_deny = 3;
- int idx_ipv4 = 7;
- return filter_set_cisco(
- vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
- "255.255.255.255", argv[idx_ipv4]->arg, "0.0.0.0", 1, 0);
+ 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)> <deny|permit> ip host A.B.C.D any",
+ "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"
@@ -1207,23 +1771,41 @@ DEFUN (no_access_list_extended_host_any,
"Any destination host\n")
{
int idx_acl = 2;
- int idx_permit_deny = 3;
- int idx_ipv4 = 6;
- return filter_set_cisco(vty, argv[idx_acl]->arg,
- argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ 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 *type_str, afi_t afi,
+ const char *seq, const char *type_str, afi_t afi,
const char *prefix_str, int exact, int set)
{
int ret;
- enum filter_type type;
+ 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,
@@ -1233,14 +1815,19 @@ static int filter_set_zebra(struct vty *vty, const char *name_str,
return CMD_WARNING_CONFIG_FAILED;
}
+ if (seq)
+ seqnum = (int64_t)atol(seq);
+
/* Check of filter type. */
- 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;
+ 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. */
@@ -1269,6 +1856,7 @@ static int filter_set_zebra(struct vty *vty, const char *name_str,
mfilter = filter_new();
mfilter->type = type;
+ mfilter->seq = seqnum;
filter = &mfilter->u.zfilter;
prefix_copy(&filter->prefix, &p);
@@ -1298,67 +1886,145 @@ static int filter_set_zebra(struct vty *vty, const char *name_str,
DEFUN (mac_access_list,
mac_access_list_cmd,
- "mac access-list WORD <deny|permit> X:X:X:X:X:X",
+ "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")
{
- return filter_set_zebra(vty, argv[2]->arg, argv[3]->arg, AFI_L2VPN,
- argv[4]->arg, 0, 1);
+ 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;
+
+ 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 <deny|permit> X:X:X:X:X:X",
+ "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")
{
- return filter_set_zebra(vty, argv[3]->arg, argv[4]->arg, AFI_L2VPN,
- argv[5]->arg, 0, 0);
+ 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;
+
+ return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN,
+ mac, 0, 0);
}
DEFUN (mac_access_list_any,
mac_access_list_any_cmd,
- "mac access-list WORD <deny|permit> any",
+ "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")
{
- return filter_set_zebra(vty, argv[2]->arg, argv[3]->arg, AFI_L2VPN,
+ 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 <deny|permit> any",
+ "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")
{
- return filter_set_zebra(vty, argv[3]->arg, argv[4]->arg, AFI_L2VPN,
+ 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 <deny|permit> A.B.C.D/M [exact-match]",
+ "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"
@@ -1366,41 +2032,71 @@ DEFUN (access_list_exact,
{
int idx = 0;
int exact = 0;
- int idx_word = 1;
- int idx_permit_deny = 2;
- int idx_ipv4_prefixlen = 3;
- idx = idx_ipv4_prefixlen;
-
+ 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;
+
+ idx = 0;
if (argv_find(argv, argc, "exact-match", &idx))
exact = 1;
- return filter_set_zebra(vty, argv[idx_word]->arg,
- argv[idx_permit_deny]->arg, AFI_IP,
- argv[idx_ipv4_prefixlen]->arg, 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 <deny|permit> any",
+ "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_permit_deny = 2;
- return filter_set_zebra(vty, argv[idx_word]->arg,
- argv[idx_permit_deny]->arg, AFI_IP, "0.0.0.0/0",
- 0, 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 <deny|permit> A.B.C.D/M [exact-match]",
+ "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"
@@ -1408,34 +2104,62 @@ DEFUN (no_access_list_exact,
{
int idx = 0;
int exact = 0;
- int idx_word = 2;
- int idx_permit_deny = 3;
- int idx_ipv4_prefixlen = 4;
- idx = idx_ipv4_prefixlen;
-
+ 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;
+
+ idx = 0;
if (argv_find(argv, argc, "exact-match", &idx))
exact = 1;
- return filter_set_zebra(vty, argv[idx_word]->arg,
- argv[idx_permit_deny]->arg, AFI_IP,
- argv[idx_ipv4_prefixlen]->arg, exact, 0);
+ 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 <deny|permit> any",
+ "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_permit_deny = 3;
- return filter_set_zebra(vty, argv[idx_word]->arg,
- argv[idx_permit_deny]->arg, AFI_IP, "0.0.0.0/0",
- 0, 0);
+ 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, 0);
}
DEFUN (no_access_list_all,
@@ -1536,10 +2260,12 @@ DEFUN (no_access_list_remark_comment,
DEFUN (ipv6_access_list_exact,
ipv6_access_list_exact_cmd,
- "ipv6 access-list WORD <deny|permit> X:X::X:X/M [exact-match]",
+ "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"
@@ -1548,41 +2274,73 @@ DEFUN (ipv6_access_list_exact,
int idx = 0;
int exact = 0;
int idx_word = 2;
- int idx_allow = 3;
- int idx_addr = 4;
- idx = idx_addr;
-
+ 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;
- return filter_set_zebra(vty, argv[idx_word]->arg, argv[idx_allow]->text,
- AFI_IP6, argv[idx_addr]->arg, exact, 1);
+ 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 <deny|permit> any",
+ "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_permit_deny = 3;
- return filter_set_zebra(vty, argv[idx_word]->arg,
- argv[idx_permit_deny]->arg, AFI_IP6, "::/0", 0,
- 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_IP6, "::/0", 0, 1);
}
DEFUN (no_ipv6_access_list_exact,
no_ipv6_access_list_exact_cmd,
- "no ipv6 access-list WORD <deny|permit> X:X::X:X/M [exact-match]",
+ "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"
@@ -1590,35 +2348,64 @@ DEFUN (no_ipv6_access_list_exact,
{
int idx = 0;
int exact = 0;
- int idx_word = 3;
- int idx_permit_deny = 4;
- int idx_ipv6_prefixlen = 5;
- idx = idx_ipv6_prefixlen;
-
+ 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;
- return filter_set_zebra(vty, argv[idx_word]->arg,
- argv[idx_permit_deny]->arg, AFI_IP6,
- argv[idx_ipv6_prefixlen]->arg, exact, 0);
+ 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 <deny|permit> any",
+ "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_permit_deny = 4;
- return filter_set_zebra(vty, argv[idx_word]->arg,
- argv[idx_permit_deny]->arg, AFI_IP6, "::/0", 0,
- 0);
+ 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, 0);
}
@@ -1748,7 +2535,8 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
write = 0;
}
- vty_out(vty, " %s%s", filter_type_str(mfilter),
+ vty_out(vty, " seq %" PRId64, mfilter->seq);
+ vty_out(vty, " %s%s", filter_type_str(mfilter),
mfilter->type == FILTER_DENY ? " " : "");
if (!mfilter->cisco)
@@ -1795,7 +2583,8 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
write = 0;
}
- vty_out(vty, " %s%s", filter_type_str(mfilter),
+ vty_out(vty, " seq %" PRId64, mfilter->seq);
+ vty_out(vty, " %s%s", filter_type_str(mfilter),
mfilter->type == FILTER_DENY ? " " : "");
if (!mfilter->cisco)
@@ -1978,11 +2767,12 @@ static int config_write_access(struct vty *vty, afi_t afi)
}
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
- vty_out(vty, "%saccess-list %s %s",
+ vty_out(vty, "%saccess-list %s seq %" PRId64 " %s",
(afi == AFI_IP) ? ("")
: ((afi == AFI_IP6) ? ("ipv6 ")
: ("mac ")),
- access->name, filter_type_str(mfilter));
+ access->name, mfilter->seq,
+ filter_type_str(mfilter));
if (mfilter->cisco)
config_write_access_cisco(vty, mfilter);
@@ -2004,11 +2794,12 @@ static int config_write_access(struct vty *vty, afi_t afi)
}
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
- vty_out(vty, "%saccess-list %s %s",
+ vty_out(vty, "%saccess-list %s seq %" PRId64 " %s",
(afi == AFI_IP) ? ("")
: ((afi == AFI_IP6) ? ("ipv6 ")
: ("mac ")),
- access->name, filter_type_str(mfilter));
+ access->name, mfilter->seq,
+ filter_type_str(mfilter));
if (mfilter->cisco)
config_write_access_cisco(vty, mfilter);
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 3294a61295..0fc321d6e0 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -681,6 +681,7 @@ struct thread_master *frr_init(void)
log_filter_cmd_init();
log_ref_init();
+ log_ref_vty_init();
lib_error_init();
yang_init();
diff --git a/lib/prefix.c b/lib/prefix.c
index 7abeebcd09..1a4a914e05 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -628,8 +628,15 @@ int prefix_match_network_statement(const struct prefix *n,
return 1;
}
-void prefix_copy(struct prefix *dest, const struct prefix *src)
+#ifdef __clang_analyzer__
+#undef prefix_copy /* cf. prefix.h */
+#endif
+
+void prefix_copy(union prefixptr udest, union prefixconstptr usrc)
{
+ struct prefix *dest = udest.p;
+ const struct prefix *src = usrc.p;
+
dest->family = src->family;
dest->prefixlen = src->prefixlen;
@@ -674,8 +681,11 @@ void prefix_copy(struct prefix *dest, const struct prefix *src)
* the same. Note that this routine has the same return value sense
* as '==' (which is different from prefix_cmp).
*/
-int prefix_same(const struct prefix *p1, const struct prefix *p2)
+int prefix_same(union prefixconstptr up1, union prefixconstptr up2)
{
+ const struct prefix *p1 = up1.p;
+ const struct prefix *p2 = up2.p;
+
if ((p1 && !p2) || (!p1 && p2))
return 0;
@@ -712,57 +722,59 @@ int prefix_same(const struct prefix *p1, const struct prefix *p2)
}
/*
- * Return 0 if the network prefixes represented by the struct prefix
- * arguments are the same prefix, and 1 otherwise. Network prefixes
- * are considered the same if the prefix lengths are equal and the
- * network parts are the same. Host bits (which are considered masked
+ * Return -1/0/1 comparing the prefixes in a way that gives a full/linear
+ * order.
+ *
+ * Network prefixes are considered the same if the prefix lengths are equal
+ * and the network parts are the same. Host bits (which are considered masked
* by the prefix length) are not significant. Thus, 10.0.0.1/8 and
* 10.0.0.2/8 are considered equivalent by this routine. Note that
* this routine has the same return sense as strcmp (which is different
* from prefix_same).
*/
-int prefix_cmp(const struct prefix *p1, const struct prefix *p2)
+int prefix_cmp(union prefixconstptr up1, union prefixconstptr up2)
{
+ const struct prefix *p1 = up1.p;
+ const struct prefix *p2 = up2.p;
int offset;
int shift;
+ int i;
/* Set both prefix's head pointer. */
const uint8_t *pp1;
const uint8_t *pp2;
if (p1->family != p2->family)
- return 1;
+ return numcmp(p1->family, p2->family);
if (p1->family == AF_FLOWSPEC) {
pp1 = (const uint8_t *)p1->u.prefix_flowspec.ptr;
pp2 = (const uint8_t *)p2->u.prefix_flowspec.ptr;
if (p1->u.prefix_flowspec.prefixlen !=
p2->u.prefix_flowspec.prefixlen)
- return 1;
+ return numcmp(p1->u.prefix_flowspec.prefixlen,
+ p2->u.prefix_flowspec.prefixlen);
offset = p1->u.prefix_flowspec.prefixlen;
while (offset--)
if (pp1[offset] != pp2[offset])
- return 1;
+ return numcmp(pp1[offset], pp2[offset]);
return 0;
}
pp1 = p1->u.val;
pp2 = p2->u.val;
if (p1->prefixlen != p2->prefixlen)
- return 1;
+ return numcmp(p1->prefixlen, p2->prefixlen);
offset = p1->prefixlen / PNBBY;
shift = p1->prefixlen % PNBBY;
- if (shift)
- if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
- return 1;
-
- while (offset--)
- if (pp1[offset] != pp2[offset])
- return 1;
+ i = memcmp(pp1, pp2, offset);
+ if (i)
+ return i;
- return 0;
+ return numcmp(pp1[offset] & maskbit[shift],
+ pp2[offset] & maskbit[shift]);
}
/*
diff --git a/lib/prefix.h b/lib/prefix.h
index d57b43dac6..e338140f1a 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -410,12 +410,20 @@ extern const char *prefix2str(union prefixconstptr, char *, int);
extern int prefix_match(const struct prefix *, const struct prefix *);
extern int prefix_match_network_statement(const struct prefix *,
const struct prefix *);
-extern int prefix_same(const struct prefix *, const struct prefix *);
-extern int prefix_cmp(const struct prefix *, const struct prefix *);
+extern int prefix_same(union prefixconstptr, union prefixconstptr);
+extern int prefix_cmp(union prefixconstptr, union prefixconstptr);
extern int prefix_common_bits(const struct prefix *, const struct prefix *);
-extern void prefix_copy(struct prefix *dest, const struct prefix *src);
+extern void prefix_copy(union prefixptr, union prefixconstptr);
extern void apply_mask(struct prefix *);
+#ifdef __clang_analyzer__
+/* clang-SA doesn't understand transparent unions, making it think that the
+ * target of prefix_copy is uninitialized. So just memset the target.
+ * cf. https://bugs.llvm.org/show_bug.cgi?id=42811
+ */
+#define prefix_copy(a, b) ({ memset(a, 0, sizeof(*a)); prefix_copy(a, b); })
+#endif
+
extern struct prefix *sockunion2prefix(const union sockunion *dest,
const union sockunion *mask);
extern struct prefix *sockunion2hostprefix(const union sockunion *,
diff --git a/lib/routemap.c b/lib/routemap.c
index 2fee3a479e..eca02e8366 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -927,15 +927,15 @@ static const char *route_map_type_str(enum route_map_type type)
return "";
}
-static const char *route_map_result_str(route_map_result_t res)
+static const char *route_map_cmd_result_str(enum route_map_cmd_result_t res)
{
switch (res) {
case RMAP_MATCH:
return "match";
- case RMAP_DENYMATCH:
- return "deny";
case RMAP_NOMATCH:
return "no match";
+ case RMAP_NOOP:
+ return "noop";
case RMAP_ERROR:
return "error";
case RMAP_OKAY:
@@ -945,6 +945,18 @@ static const char *route_map_result_str(route_map_result_t res)
return "invalid";
}
+static const char *route_map_result_str(route_map_result_t res)
+{
+ switch (res) {
+ case RMAP_DENYMATCH:
+ return "deny";
+ case RMAP_PERMITMATCH:
+ return "permit";
+ }
+
+ return "invalid";
+}
+
static int route_map_empty(struct route_map *map)
{
if (map->head == NULL && map->tail == NULL)
@@ -1558,20 +1570,98 @@ int route_map_delete_set(struct route_map_index *index, const char *set_name,
return 1;
}
+static enum route_map_cmd_result_t
+route_map_apply_match(struct route_map_rule_list *match_list,
+ const struct prefix *prefix, route_map_object_t type,
+ void *object)
+{
+ enum route_map_cmd_result_t ret = RMAP_NOMATCH;
+ struct route_map_rule *match;
+ bool is_matched = false;
+
+
+ /* Check all match rule and if there is no match rule, go to the
+ set statement. */
+ if (!match_list->head)
+ ret = RMAP_MATCH;
+ else {
+ for (match = match_list->head; match; match = match->next) {
+ /*
+ * Try each match statement. If any match does not
+ * return RMAP_MATCH or RMAP_NOOP, return.
+ * Otherwise continue on to next match statement.
+ * All match statements must MATCH for
+ * end-result to be a match.
+ * (Exception:If match stmts result in a mix of
+ * MATCH/NOOP, then also end-result is a match)
+ * If all result in NOOP, end-result is NOOP.
+ */
+ ret = (*match->cmd->func_apply)(match->value, prefix,
+ type, object);
+
+ /*
+ * If the consolidated result of func_apply is:
+ * -----------------------------------------------
+ * | MATCH | NOMATCH | NOOP | Final Result |
+ * ------------------------------------------------
+ * | yes | yes | yes | NOMATCH |
+ * | no | no | yes | NOOP |
+ * | yes | no | yes | MATCH |
+ * | no | yes | yes | NOMATCH |
+ * |-----------------------------------------------
+ *
+ * Traditionally, all rules within route-map
+ * should match for it to MATCH.
+ * If there are noops within the route-map rules,
+ * it follows the above matrix.
+ *
+ * Eg: route-map rm1 permit 10
+ * match rule1
+ * match rule2
+ * match rule3
+ * ....
+ * route-map rm1 permit 20
+ * match ruleX
+ * match ruleY
+ * ...
+ */
+
+ switch (ret) {
+ case RMAP_MATCH:
+ is_matched = true;
+ break;
+
+ case RMAP_NOMATCH:
+ return ret;
+
+ case RMAP_NOOP:
+ if (is_matched)
+ ret = RMAP_MATCH;
+ break;
+
+ default:
+ break;
+ }
+
+ }
+ }
+ return ret;
+}
+
/* Apply route map's each index to the object.
The matrix for a route-map looks like this:
(note, this includes the description for the "NEXT"
and "GOTO" frobs now
- Match | No Match
- |
- permit action | cont
- |
- ------------------+---------------
- |
- deny deny | cont
- |
+ | Match | No Match | No op
+ |-----------|--------------|-------
+ permit | action | cont | cont.
+ | | default:deny | default:permit
+ -------------------+-----------------------
+ | deny | cont | cont.
+ deny | | default:deny | default:permit
+ |-----------|--------------|--------
action)
-Apply Set statements, accept route
@@ -1604,45 +1694,13 @@ int route_map_delete_set(struct route_map_index *index, const char *set_name,
We need to make sure our route-map processing matches the above
*/
-
-static route_map_result_t
-route_map_apply_match(struct route_map_rule_list *match_list,
- const struct prefix *prefix, route_map_object_t type,
- void *object)
-{
- route_map_result_t ret = RMAP_NOMATCH;
- struct route_map_rule *match;
-
-
- /* Check all match rule and if there is no match rule, go to the
- set statement. */
- if (!match_list->head)
- ret = RMAP_MATCH;
- else {
- for (match = match_list->head; match; match = match->next) {
- /* Try each match statement in turn, If any do not
- return
- RMAP_MATCH, return, otherwise continue on to next
- match
- statement. All match statements must match for
- end-result
- to be a match. */
- ret = (*match->cmd->func_apply)(match->value, prefix,
- type, object);
- if (ret != RMAP_MATCH)
- return ret;
- }
- }
- return ret;
-}
-
-/* Apply route map to the object. */
route_map_result_t route_map_apply(struct route_map *map,
const struct prefix *prefix,
route_map_object_t type, void *object)
{
static int recursion = 0;
- int ret = 0;
+ enum route_map_cmd_result_t match_ret = RMAP_NOMATCH;
+ route_map_result_t ret = RMAP_PERMITMATCH;
struct route_map_index *index;
struct route_map_rule *set;
char buf[PREFIX_STRLEN];
@@ -1656,7 +1714,7 @@ route_map_result_t route_map_apply(struct route_map *map,
return RMAP_DENYMATCH;
}
- if (map == NULL) {
+ if (map == NULL || map->head == NULL) {
ret = RMAP_DENYMATCH;
goto route_map_apply_end;
}
@@ -1665,29 +1723,64 @@ route_map_result_t route_map_apply(struct route_map *map,
for (index = map->head; index; index = index->next) {
/* Apply this index. */
index->applied++;
- ret = route_map_apply_match(&index->match_list, prefix, type,
- object);
+ match_ret = route_map_apply_match(&index->match_list, prefix,
+ type, object);
if (rmap_debug) {
zlog_debug("Route-map: %s, sequence: %d, prefix: %s, result: %s",
map->name, index->pref,
prefix2str(prefix, buf, sizeof(buf)),
- route_map_result_str(ret));
+ route_map_cmd_result_str(match_ret));
}
/* Now we apply the matrix from above */
- if (ret == RMAP_NOMATCH)
- /* 'cont' from matrix - continue to next route-map
- * sequence */
+ if (match_ret == RMAP_NOOP)
+ /*
+ * Do not change the return value. Retain the previous
+ * return value. Previous values can be:
+ * 1)permitmatch (if a nomatch was never
+ * seen before in this route-map.)
+ * 2)denymatch (if a nomatch was seen earlier in one
+ * of the previous sequences)
+ */
+
+ /*
+ * 'cont' from matrix - continue to next route-map
+ * sequence
+ */
continue;
- else if (ret == RMAP_MATCH) {
+ else if (match_ret == RMAP_NOMATCH) {
+
+ /*
+ * The return value is now changed to denymatch.
+ * So from here on out, even if we see more noops,
+ * we retain this return value and return this
+ * eventually if there are no matches.
+ */
+ ret = RMAP_DENYMATCH;
+
+ /*
+ * 'cont' from matrix - continue to next route-map
+ * sequence
+ */
+ continue;
+ } else if (match_ret == RMAP_MATCH) {
if (index->type == RMAP_PERMIT)
/* 'action' */
{
+ /* Match succeeded, rmap is of type permit */
+ ret = RMAP_PERMITMATCH;
+
/* permit+match must execute sets */
for (set = index->set_list.head; set;
set = set->next)
- ret = (*set->cmd->func_apply)(
+ /*
+ * set cmds return RMAP_OKAY or
+ * RMAP_ERROR. We do not care if
+ * set succeeded or not. So, ignore
+ * return code.
+ */
+ (void) (*set->cmd->func_apply)(
set->value, prefix, type,
object);
@@ -1741,8 +1834,6 @@ route_map_result_t route_map_apply(struct route_map *map,
}
}
}
- /* Finally route-map does not match at all. */
- ret = RMAP_DENYMATCH;
route_map_apply_end:
if (rmap_debug) {
diff --git a/lib/routemap.h b/lib/routemap.h
index 90df1048ed..f9ad0f64a9 100644
--- a/lib/routemap.h
+++ b/lib/routemap.h
@@ -38,13 +38,35 @@ DECLARE_MTYPE(ROUTE_MAP_COMPILED)
enum route_map_type { RMAP_PERMIT, RMAP_DENY, RMAP_ANY };
typedef enum {
- RMAP_MATCH,
RMAP_DENYMATCH,
- RMAP_NOMATCH,
- RMAP_ERROR,
- RMAP_OKAY
+ RMAP_PERMITMATCH
} route_map_result_t;
+/*
+ * Route-map match or set result "Eg: match evpn vni xx"
+ * route-map match cmd always returns match/nomatch/noop
+ * match--> found a match
+ * nomatch--> didnt find a match
+ * noop--> not applicable
+ * route-map set retuns okay/error
+ * okay --> set was successful
+ * error --> set was not successful
+ */
+enum route_map_cmd_result_t {
+ /*
+ * route-map match cmd results
+ */
+ RMAP_MATCH,
+ RMAP_NOMATCH,
+ RMAP_NOOP,
+ /*
+ * route-map set cmd results
+ */
+ RMAP_OKAY,
+ RMAP_ERROR
+};
+
+
typedef enum {
RMAP_RIP,
RMAP_RIPNG,
@@ -91,10 +113,10 @@ struct route_map_rule_cmd {
const char *str;
/* Function for value set or match. */
- route_map_result_t (*func_apply)(void *rule,
- const struct prefix *prefix,
- route_map_object_t type,
- void *object);
+ enum route_map_cmd_result_t (*func_apply)(void *rule,
+ const struct prefix *prefix,
+ route_map_object_t type,
+ void *object);
/* Compile argument and return result as void *. */
void *(*func_compile)(const char *);
diff --git a/lib/typerb.c b/lib/typerb.c
index 4c48d6434f..3886fc678e 100644
--- a/lib/typerb.c
+++ b/lib/typerb.c
@@ -333,9 +333,10 @@ color:
return (old);
}
-void typed_rb_remove(struct rbt_tree *rbt, struct rb_entry *rbe)
+struct typed_rb_entry *typed_rb_remove(struct rbt_tree *rbt,
+ struct rb_entry *rbe)
{
- rbe_remove(rbt, rbe);
+ return rbe_remove(rbt, rbe);
}
struct typed_rb_entry *typed_rb_insert(struct rbt_tree *rbt,
diff --git a/lib/typerb.h b/lib/typerb.h
index ce8446f853..2d7b0ba637 100644
--- a/lib/typerb.h
+++ b/lib/typerb.h
@@ -38,29 +38,30 @@ struct typed_rb_root {
size_t count;
};
-struct typed_rb_entry *typed_rb_insert(struct typed_rb_root *,
+struct typed_rb_entry *typed_rb_insert(struct typed_rb_root *rbt,
struct typed_rb_entry *rbe,
int (*cmpfn)(
const struct typed_rb_entry *a,
const struct typed_rb_entry *b));
-void typed_rb_remove(struct typed_rb_root *, struct typed_rb_entry *rbe);
-struct typed_rb_entry *typed_rb_find(struct typed_rb_root *,
+struct typed_rb_entry *typed_rb_remove(struct typed_rb_root *rbt,
+ struct typed_rb_entry *rbe);
+struct typed_rb_entry *typed_rb_find(struct typed_rb_root *rbt,
const struct typed_rb_entry *rbe,
int (*cmpfn)(
const struct typed_rb_entry *a,
const struct typed_rb_entry *b));
-struct typed_rb_entry *typed_rb_find_gteq(struct typed_rb_root *,
+struct typed_rb_entry *typed_rb_find_gteq(struct typed_rb_root *rbt,
const struct typed_rb_entry *rbe,
int (*cmpfn)(
const struct typed_rb_entry *a,
const struct typed_rb_entry *b));
-struct typed_rb_entry *typed_rb_find_lt(struct typed_rb_root *,
+struct typed_rb_entry *typed_rb_find_lt(struct typed_rb_root *rbt,
const struct typed_rb_entry *rbe,
int (*cmpfn)(
const struct typed_rb_entry *a,
const struct typed_rb_entry *b));
-struct typed_rb_entry *typed_rb_min(struct typed_rb_root *);
-struct typed_rb_entry *typed_rb_next(struct typed_rb_entry *);
+struct typed_rb_entry *typed_rb_min(struct typed_rb_root *rbt);
+struct typed_rb_entry *typed_rb_next(struct typed_rb_entry *rbe);
#define _PREDECL_RBTREE(prefix) \
struct prefix ## _head { struct typed_rb_root rr; }; \
@@ -99,9 +100,11 @@ macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \
re = typed_rb_find_lt(&h->rr, &item->field.re, cmpfn_nuq); \
return container_of_null(re, type, field.re); \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
- typed_rb_remove(&h->rr, &item->field.re); \
+ struct typed_rb_entry *re; \
+ re = typed_rb_remove(&h->rr, &item->field.re); \
+ return container_of_null(re, type, field.re); \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
@@ -130,7 +133,7 @@ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \
re = item ? typed_rb_next(&item->field.re) : NULL; \
return container_of_null(re, type, field.re); \
} \
-macro_pure size_t prefix ## _count(struct prefix##_head *h) \
+macro_pure size_t prefix ## _count(const struct prefix##_head *h) \
{ \
return h->rr.count; \
} \
diff --git a/lib/typesafe.c b/lib/typesafe.c
index f2ca67b7c6..7e5939d5b3 100644
--- a/lib/typesafe.c
+++ b/lib/typesafe.c
@@ -341,13 +341,14 @@ struct sskip_item *typesafe_skiplist_find_lt(struct sskip_head *head,
return best;
}
-void typesafe_skiplist_del(struct sskip_head *head, struct sskip_item *item,
- int (*cmpfn)(const struct sskip_item *a,
- const struct sskip_item *b))
+struct sskip_item *typesafe_skiplist_del(
+ struct sskip_head *head, struct sskip_item *item,
+ int (*cmpfn)(const struct sskip_item *a, const struct sskip_item *b))
{
size_t level = SKIPLIST_MAXDEPTH;
struct sskip_item *prev = &head->hitem, *next;
int cmpval;
+ bool found = false;
while (level) {
next = sl_level_get(prev, level - 1);
@@ -359,6 +360,7 @@ void typesafe_skiplist_del(struct sskip_head *head, struct sskip_item *item,
sl_level_set(prev, level - 1,
sl_level_get(item, level - 1));
level--;
+ found = true;
continue;
}
cmpval = cmpfn(next, item);
@@ -369,6 +371,9 @@ void typesafe_skiplist_del(struct sskip_head *head, struct sskip_item *item,
level--;
}
+ if (!found)
+ return NULL;
+
/* TBD: assert when trying to remove non-existing item? */
head->count--;
@@ -379,6 +384,8 @@ void typesafe_skiplist_del(struct sskip_head *head, struct sskip_item *item,
XFREE(MTYPE_SKIPLIST_OFLOW, oflow);
}
memset(item, 0, sizeof(*item));
+
+ return item;
}
struct sskip_item *typesafe_skiplist_pop(struct sskip_head *head)
diff --git a/lib/typesafe.h b/lib/typesafe.h
index 0a4ed69e4e..c30d73d1b3 100644
--- a/lib/typesafe.h
+++ b/lib/typesafe.h
@@ -109,17 +109,18 @@ macro_inline void prefix ## _add_after(struct prefix##_head *h, \
typesafe_list_add(&h->sh, nextp, &item->field.si); \
} \
/* TODO: del_hint */ \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
struct slist_item **iter = &h->sh.first; \
while (*iter && *iter != &item->field.si) \
iter = &(*iter)->next; \
if (!*iter) \
- return; \
+ return NULL; \
h->sh.count--; \
*iter = item->field.si.next; \
if (!item->field.si.next) \
h->sh.last_next = iter; \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
@@ -149,7 +150,7 @@ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \
sitem = &item->field.si; \
return container_of_null(sitem->next, type, field.si); \
} \
-macro_pure size_t prefix ## _count(struct prefix##_head *h) \
+macro_pure size_t prefix ## _count(const struct prefix##_head *h) \
{ \
return h->sh.count; \
} \
@@ -212,13 +213,14 @@ macro_inline void prefix ## _add_after(struct prefix##_head *h, \
prev = after ? &after->field.di : &h->dh.hitem; \
typesafe_dlist_add(&h->dh, prev, &item->field.di); \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
struct dlist_item *ditem = &item->field.di; \
ditem->prev->next = ditem->next; \
ditem->next->prev = ditem->prev; \
h->dh.count--; \
ditem->prev = ditem->next = NULL; \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
@@ -250,7 +252,7 @@ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \
return NULL; \
return prefix ## _next(h, item); \
} \
-macro_pure size_t prefix ## _count(struct prefix##_head *h) \
+macro_pure size_t prefix ## _count(const struct prefix##_head *h) \
{ \
return h->dh.count; \
} \
@@ -308,7 +310,7 @@ macro_inline type *prefix ## _add(struct prefix##_head *h, type *item) \
h->hh.count++; \
return NULL; \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
struct heap_item *other; \
uint32_t index = item->field.hi.index; \
@@ -321,6 +323,7 @@ macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
typesafe_heap_pushdown(&h->hh, index, other, prefix ## __cmp); \
if (HEAP_RESIZE_TRESH_DN(h)) \
typesafe_heap_resize(&h->hh, false); \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
@@ -354,7 +357,7 @@ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \
return NULL; \
return prefix ## _next(h, item); \
} \
-macro_pure size_t prefix ## _count(struct prefix##_head *h) \
+macro_pure size_t prefix ## _count(const struct prefix##_head *h) \
{ \
return h->hh.count; \
} \
@@ -434,7 +437,7 @@ macro_inline type *prefix ## _find_gteq(struct prefix##_head *h, \
struct ssort_item *sitem = h->sh.first; \
int cmpval = 0; \
while (sitem && (cmpval = cmpfn_nuq( \
- container_of(sitem, type, field.si), item) < 0)) \
+ container_of(sitem, type, field.si), item)) < 0) \
sitem = sitem->next; \
return container_of_null(sitem, type, field.si); \
} \
@@ -444,20 +447,21 @@ macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \
struct ssort_item *prev = NULL, *sitem = h->sh.first; \
int cmpval = 0; \
while (sitem && (cmpval = cmpfn_nuq( \
- container_of(sitem, type, field.si), item) < 0)) \
+ container_of(sitem, type, field.si), item)) < 0) \
sitem = (prev = sitem)->next; \
return container_of_null(prev, type, field.si); \
} \
/* TODO: del_hint */ \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
struct ssort_item **iter = &h->sh.first; \
while (*iter && *iter != &item->field.si) \
iter = &(*iter)->next; \
if (!*iter) \
- return; \
+ return NULL; \
h->sh.count--; \
*iter = item->field.si.next; \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
@@ -485,7 +489,7 @@ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \
sitem = &item->field.si; \
return container_of_null(sitem->next, type, field.si); \
} \
-macro_pure size_t prefix ## _count(struct prefix##_head *h) \
+macro_pure size_t prefix ## _count(const struct prefix##_head *h) \
{ \
return h->sh.count; \
} \
@@ -499,7 +503,7 @@ macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \
struct ssort_item *sitem = h->sh.first; \
int cmpval = 0; \
while (sitem && (cmpval = cmpfn( \
- container_of(sitem, type, field.si), item) < 0)) \
+ container_of(sitem, type, field.si), item)) < 0) \
sitem = sitem->next; \
if (!sitem || cmpval > 0) \
return NULL; \
@@ -617,10 +621,10 @@ macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \
} \
return NULL; \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
if (!h->hh.tabshift) \
- return; \
+ return NULL; \
uint32_t hval = item->field.hi.hashval, hbits = HASH_KEY(h->hh, hval); \
struct thash_item **np = &h->hh.entries[hbits]; \
while (*np && (*np)->hashval < hval) \
@@ -628,12 +632,13 @@ macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
while (*np && *np != &item->field.hi && (*np)->hashval == hval) \
np = &(*np)->next; \
if (*np != &item->field.hi) \
- return; \
+ return NULL; \
*np = item->field.hi.next; \
item->field.hi.next = NULL; \
h->hh.count--; \
if (HASH_SHRINK_THRESHOLD(h->hh)) \
typesafe_hash_shrink(&h->hh); \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
@@ -675,7 +680,7 @@ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \
return NULL; \
return prefix ## _next(h, item); \
} \
-macro_pure size_t prefix ## _count(struct prefix##_head *h) \
+macro_pure size_t prefix ## _count(const struct prefix##_head *h) \
{ \
return h->hh.count; \
} \
@@ -751,9 +756,11 @@ macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \
&item->field.si, cmpfn_nuq); \
return container_of_null(sitem, type, field.si); \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
- typesafe_skiplist_del(&h->sh, &item->field.si, cmpfn_uq); \
+ struct sskip_item *sitem = typesafe_skiplist_del(&h->sh, \
+ &item->field.si, cmpfn_uq); \
+ return container_of_null(sitem, type, field.si); \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
@@ -776,7 +783,7 @@ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \
next = item ? item->field.si.next[0] : NULL; \
return container_of_null(next, type, field.si); \
} \
-macro_pure size_t prefix ## _count(struct prefix##_head *h) \
+macro_pure size_t prefix ## _count(const struct prefix##_head *h) \
{ \
return h->sh.count; \
} \
@@ -848,8 +855,8 @@ extern struct sskip_item *typesafe_skiplist_find_lt(struct sskip_head *head,
const struct sskip_item *item, int (*cmpfn)(
const struct sskip_item *a,
const struct sskip_item *b));
-extern void typesafe_skiplist_del(struct sskip_head *head,
- struct sskip_item *item, int (*cmpfn)(
+extern struct sskip_item *typesafe_skiplist_del(
+ struct sskip_head *head, struct sskip_item *item, int (*cmpfn)(
const struct sskip_item *a,
const struct sskip_item *b));
extern struct sskip_item *typesafe_skiplist_pop(struct sskip_head *head);