summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2021-03-30 10:21:37 -0400
committerGitHub <noreply@github.com>2021-03-30 10:21:37 -0400
commit1c5168bd0b4fe45f31d22fadd294ad018eca14a2 (patch)
tree3f6db329d460d25de71ed42c3397a97e6bc2107a
parent5c9254bd52ae69d957c08dd396948e29ae016c16 (diff)
parent4179f151fe80584167dbeeb260144d0cfa171f16 (diff)
Merge pull request #8369 from idryzhov/filter-fixes
access-list and prefix-list fixes
-rw-r--r--lib/filter.h6
-rw-r--r--lib/filter_cli.c7
-rw-r--r--lib/filter_nb.c182
3 files changed, 153 insertions, 42 deletions
diff --git a/lib/filter.h b/lib/filter.h
index 091a5197f6..b1bf1d67ba 100644
--- a/lib/filter.h
+++ b/lib/filter.h
@@ -182,6 +182,9 @@ struct acl_dup_args {
/** Access list name. */
const char *ada_name;
+ /** Entry action. */
+ const char *ada_action;
+
#define ADA_MAX_VALUES 4
/** Entry XPath for value. */
const char *ada_xpath[ADA_MAX_VALUES];
@@ -209,6 +212,9 @@ struct plist_dup_args {
/** Access list name. */
const char *pda_name;
+ /** Entry action. */
+ const char *pda_action;
+
#define PDA_MAX_VALUES 4
/** Entry XPath for value. */
const char *pda_xpath[PDA_MAX_VALUES];
diff --git a/lib/filter_cli.c b/lib/filter_cli.c
index 5d66a9fc73..24980f7858 100644
--- a/lib/filter_cli.c
+++ b/lib/filter_cli.c
@@ -173,6 +173,7 @@ DEFPY_YANG(
if (seq_str == NULL) {
ada.ada_type = "ipv4";
ada.ada_name = name;
+ ada.ada_action = action;
if (host_str && mask_str == NULL) {
ada.ada_xpath[0] = "./host";
ada.ada_value[0] = host_str;
@@ -309,6 +310,7 @@ DEFPY_YANG(
if (seq_str == NULL) {
ada.ada_type = "ipv4";
ada.ada_name = name;
+ ada.ada_action = action;
if (src_str && src_mask_str == NULL) {
ada.ada_xpath[idx] = "./host";
ada.ada_value[idx] = src_str;
@@ -504,6 +506,7 @@ DEFPY_YANG(
if (seq_str == NULL) {
ada.ada_type = "ipv4";
ada.ada_name = name;
+ ada.ada_action = action;
if (prefix_str) {
ada.ada_xpath[0] = "./ipv4-prefix";
@@ -701,6 +704,7 @@ DEFPY_YANG(
if (seq_str == NULL) {
ada.ada_type = "ipv6";
ada.ada_name = name;
+ ada.ada_action = action;
if (prefix_str) {
ada.ada_xpath[0] = "./ipv6-prefix";
@@ -902,6 +906,7 @@ DEFPY_YANG(
if (seq_str == NULL) {
ada.ada_type = "mac";
ada.ada_name = name;
+ ada.ada_action = action;
if (mac_str) {
ada.ada_xpath[0] = "./mac";
@@ -1331,6 +1336,7 @@ DEFPY_YANG(
if (seq_str == NULL) {
pda.pda_type = "ipv4";
pda.pda_name = name;
+ pda.pda_action = action;
if (prefix_str) {
pda.pda_xpath[arg_idx] = "./ipv4-prefix";
pda.pda_value[arg_idx] = prefix_str;
@@ -1526,6 +1532,7 @@ DEFPY_YANG(
if (seq_str == NULL) {
pda.pda_type = "ipv6";
pda.pda_name = name;
+ pda.pda_action = action;
if (prefix_str) {
pda.pda_xpath[arg_idx] = "./ipv6-prefix";
pda.pda_value[arg_idx] = prefix_str;
diff --git a/lib/filter_nb.c b/lib/filter_nb.c
index c83738e729..3b650742f3 100644
--- a/lib/filter_nb.c
+++ b/lib/filter_nb.c
@@ -152,6 +152,27 @@ prefix_list_nb_validate_v6_af_type(const struct lyd_node *plist_dnode,
return NB_OK;
}
+static int lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct prefix_list_entry *ple;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ple = nb_running_get_entry(args->dnode, NULL, true);
+
+ /* Start prefix entry update procedure. */
+ prefix_list_entry_update_start(ple);
+
+ ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
+
+ /* Finish prefix entry update procedure. */
+ prefix_list_entry_update_finish(ple);
+
+ return NB_OK;
+}
+
static int lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
struct nb_cb_modify_args *args)
{
@@ -238,6 +259,9 @@ static int _acl_is_dup(const struct lyd_node *dnode, void *arg)
&& ada->ada_entry_dnode == dnode)
return YANG_ITER_CONTINUE;
+ if (strcmp(yang_dnode_get_string(dnode, "action"), ada->ada_action))
+ return YANG_ITER_CONTINUE;
+
/* Check if all values match. */
for (idx = 0; idx < ADA_MAX_VALUES; idx++) {
/* No more values. */
@@ -292,6 +316,7 @@ static bool acl_cisco_is_dup(const struct lyd_node *dnode)
/* Initialize. */
ada.ada_type = "ipv4";
ada.ada_name = yang_dnode_get_string(entry_dnode, "../name");
+ ada.ada_action = yang_dnode_get_string(entry_dnode, "action");
ada.ada_entry_dnode = entry_dnode;
/* Load all values/XPaths. */
@@ -341,6 +366,7 @@ static bool acl_zebra_is_dup(const struct lyd_node *dnode,
break;
}
ada.ada_name = yang_dnode_get_string(entry_dnode, "../name");
+ ada.ada_action = yang_dnode_get_string(entry_dnode, "action");
ada.ada_entry_dnode = entry_dnode;
/* Load all values/XPaths. */
@@ -370,6 +396,9 @@ static int _plist_is_dup(const struct lyd_node *dnode, void *arg)
&& pda->pda_entry_dnode == dnode)
return YANG_ITER_CONTINUE;
+ if (strcmp(yang_dnode_get_string(dnode, "action"), pda->pda_action))
+ return YANG_ITER_CONTINUE;
+
/* Check if all values match. */
for (idx = 0; idx < PDA_MAX_VALUES; idx++) {
/* No more values. */
@@ -403,6 +432,46 @@ bool plist_is_dup(const struct lyd_node *dnode, struct plist_dup_args *pda)
return pda->pda_found;
}
+static bool plist_is_dup_nb(const struct lyd_node *dnode)
+{
+ const struct lyd_node *entry_dnode =
+ yang_dnode_get_parent(dnode, "entry");
+ struct plist_dup_args pda = {};
+ int idx = 0, arg_idx = 0;
+ static const char *entries[] = {
+ "./ipv4-prefix",
+ "./ipv4-prefix-length-greater-or-equal",
+ "./ipv4-prefix-length-lesser-or-equal",
+ "./ipv6-prefix",
+ "./ipv6-prefix-length-greater-or-equal",
+ "./ipv6-prefix-length-lesser-or-equal",
+ "./any",
+ NULL
+ };
+
+ /* Initialize. */
+ pda.pda_type = yang_dnode_get_string(entry_dnode, "../type");
+ pda.pda_name = yang_dnode_get_string(entry_dnode, "../name");
+ pda.pda_action = yang_dnode_get_string(entry_dnode, "action");
+ pda.pda_entry_dnode = entry_dnode;
+
+ /* Load all values/XPaths. */
+ while (entries[idx] != NULL) {
+ if (!yang_dnode_exists(entry_dnode, entries[idx])) {
+ idx++;
+ continue;
+ }
+
+ pda.pda_xpath[arg_idx] = entries[idx];
+ pda.pda_value[arg_idx] =
+ yang_dnode_get_string(entry_dnode, entries[idx]);
+ arg_idx++;
+ idx++;
+ }
+
+ return plist_is_dup(entry_dnode, &pda);
+}
+
/*
* XPath: /frr-filter:lib/access-list
*/
@@ -1265,6 +1334,13 @@ lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
const struct lyd_node *plist_dnode =
yang_dnode_get_parent(args->dnode, "prefix-list");
+ if (plist_is_dup_nb(args->dnode)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "duplicated prefix list value: %s",
+ yang_dnode_get_string(args->dnode, NULL));
+ return NB_ERR_VALIDATION;
+ }
+
return prefix_list_nb_validate_v4_af_type(
plist_dnode, args->errmsg, args->errmsg_len);
}
@@ -1293,6 +1369,13 @@ lib_prefix_list_entry_ipv6_prefix_modify(struct nb_cb_modify_args *args)
const struct lyd_node *plist_dnode =
yang_dnode_get_parent(args->dnode, "prefix-list");
+ if (plist_is_dup_nb(args->dnode)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "duplicated prefix list value: %s",
+ yang_dnode_get_string(args->dnode, NULL));
+ return NB_ERR_VALIDATION;
+ }
+
return prefix_list_nb_validate_v6_af_type(
plist_dnode, args->errmsg, args->errmsg_len);
}
@@ -1316,26 +1399,27 @@ lib_prefix_list_entry_ipv6_prefix_destroy(struct nb_cb_destroy_args *args)
static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
struct nb_cb_modify_args *args)
{
- struct prefix_list_entry *ple;
-
- if (args->event == NB_EV_VALIDATE &&
- prefix_list_length_validate(args) != NB_OK)
+ if (args->event == NB_EV_VALIDATE
+ && prefix_list_length_validate(args) != NB_OK)
return NB_ERR_VALIDATION;
- if (args->event != NB_EV_APPLY)
- return NB_OK;
-
- ple = nb_running_get_entry(args->dnode, NULL, true);
-
- /* Start prefix entry update procedure. */
- prefix_list_entry_update_start(ple);
+ if (args->event == NB_EV_VALIDATE) {
+ const struct lyd_node *plist_dnode =
+ yang_dnode_get_parent(args->dnode, "prefix-list");
- ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
+ if (plist_is_dup_nb(args->dnode)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "duplicated prefix list value: %s",
+ yang_dnode_get_string(args->dnode, NULL));
+ return NB_ERR_VALIDATION;
+ }
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
+ return prefix_list_nb_validate_v4_af_type(
+ plist_dnode, args->errmsg, args->errmsg_len);
+ }
- return NB_OK;
+ return lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
+ args);
}
static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
@@ -1367,11 +1451,19 @@ static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
const struct lyd_node *plist_dnode =
yang_dnode_get_parent(args->dnode, "prefix-list");
+ if (plist_is_dup_nb(args->dnode)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "duplicated prefix list value: %s",
+ yang_dnode_get_string(args->dnode, NULL));
+ return NB_ERR_VALIDATION;
+ }
+
return prefix_list_nb_validate_v4_af_type(
plist_dnode, args->errmsg, args->errmsg_len);
}
- return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(args);
+ return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
+ args);
}
static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
@@ -1395,8 +1487,6 @@ static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
static int lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_modify(
struct nb_cb_modify_args *args)
{
- struct prefix_list_entry *ple;
-
if (args->event == NB_EV_VALIDATE
&& prefix_list_length_validate(args) != NB_OK)
return NB_ERR_VALIDATION;
@@ -1405,24 +1495,19 @@ static int lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_modify(
const struct lyd_node *plist_dnode =
yang_dnode_get_parent(args->dnode, "prefix-list");
+ if (plist_is_dup_nb(args->dnode)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "duplicated prefix list value: %s",
+ yang_dnode_get_string(args->dnode, NULL));
+ return NB_ERR_VALIDATION;
+ }
+
return prefix_list_nb_validate_v6_af_type(
plist_dnode, args->errmsg, args->errmsg_len);
}
- if (args->event != NB_EV_APPLY)
- return NB_OK;
-
- ple = nb_running_get_entry(args->dnode, NULL, true);
-
- /* Start prefix entry update procedure. */
- prefix_list_entry_update_start(ple);
-
- ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
-
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
- return NB_OK;
+ return lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
+ args);
}
static int lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_destroy(
@@ -1454,28 +1539,30 @@ static int lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_modify(
const struct lyd_node *plist_dnode =
yang_dnode_get_parent(args->dnode, "prefix-list");
+ if (plist_is_dup_nb(args->dnode)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "duplicated prefix list value: %s",
+ yang_dnode_get_string(args->dnode, NULL));
+ return NB_ERR_VALIDATION;
+ }
+
return prefix_list_nb_validate_v6_af_type(
plist_dnode, args->errmsg, args->errmsg_len);
}
- return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(args);
+ return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
+ args);
}
static int lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_destroy(
struct nb_cb_destroy_args *args)
{
- int af_type;
-
if (args->event == NB_EV_VALIDATE) {
const struct lyd_node *plist_dnode =
yang_dnode_get_parent(args->dnode, "prefix-list");
- af_type = yang_dnode_get_enum(plist_dnode, "./type");
- if (af_type != YPLT_IPV6) {
- snprintf(args->errmsg, args->errmsg_len,
- "prefix-list type %u is mismatched.", af_type);
- return NB_ERR_VALIDATION;
- }
- return NB_OK;
+
+ return prefix_list_nb_validate_v6_af_type(
+ plist_dnode, args->errmsg, args->errmsg_len);
}
return lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
@@ -1490,6 +1577,17 @@ static int lib_prefix_list_entry_any_create(struct nb_cb_create_args *args)
struct prefix_list_entry *ple;
int type;
+ if (args->event == NB_EV_VALIDATE) {
+ if (plist_is_dup_nb(args->dnode)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "duplicated prefix list value: %s",
+ yang_dnode_get_string(args->dnode, NULL));
+ return NB_ERR_VALIDATION;
+ }
+
+ return NB_OK;
+ }
+
if (args->event != NB_EV_APPLY)
return NB_OK;