Skip to content

Commit

Permalink
lib: fix distribute-list deletion
Browse files Browse the repository at this point in the history
When a whole distribute-list is deleted (can be done only using API),
all its children must be cleaned up manually.

Fixes #16538

Signed-off-by: Igor Ryzhov <[email protected]>
(cherry picked from commit 8fad4f3)

# Conflicts:
#	lib/distribute.c
  • Loading branch information
idryzhov authored and mergify[bot] committed Aug 12, 2024
1 parent 3f6b028 commit 3b6a11e
Showing 1 changed file with 157 additions and 0 deletions.
157 changes: 157 additions & 0 deletions lib/distribute.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,163 @@ int config_write_distribute(struct vty *vty,
return write;
}

<<<<<<< HEAD
=======
/* ---------- */
/* Northbound */
/* ---------- */

int group_distribute_list_create_helper(
struct nb_cb_create_args *args, struct distribute_ctx *ctx)
{
nb_running_set_entry(args->dnode, ctx);
return NB_OK;
}

/*
* XPath: /frr-ripd:ripd/instance/distribute-lists/distribute-list/{in,out}/{access,prefix}-list
*/

static int distribute_list_leaf_update(const struct lyd_node *dnode,
int ip_version, bool no);

int group_distribute_list_destroy(struct nb_cb_destroy_args *args)
{
struct lyd_node *dnode;

if (args->event != NB_EV_APPLY)
return NB_OK;

/*
* We don't keep the IP version of distribute-list anywhere, so we're
* trying to remove both. If one doesn't exist, it's simply skipped by
* the remove function.
*/

dnode = yang_dnode_get(args->dnode, "in/access-list");
if (dnode) {
distribute_list_leaf_update(dnode, 4, true);
distribute_list_leaf_update(dnode, 6, true);
}
dnode = yang_dnode_get(args->dnode, "in/prefix-list");
if (dnode) {
distribute_list_leaf_update(dnode, 4, true);
distribute_list_leaf_update(dnode, 6, true);
}
dnode = yang_dnode_get(args->dnode, "out/access-list");
if (dnode) {
distribute_list_leaf_update(dnode, 4, true);
distribute_list_leaf_update(dnode, 6, true);
}
dnode = yang_dnode_get(args->dnode, "out/prefix-list");
if (dnode) {
distribute_list_leaf_update(dnode, 4, true);
distribute_list_leaf_update(dnode, 6, true);
}

nb_running_unset_entry(args->dnode);
return NB_OK;
}

static int distribute_list_leaf_update(const struct lyd_node *dnode,
int ip_version, bool no)
{
struct distribute_ctx *ctx;
struct lyd_node *dir_node = lyd_parent(dnode);
struct lyd_node_inner *list_node = dir_node->parent;
struct lyd_node *intf_key = list_node->child;
bool ipv4 = ip_version == 4 ? true : false;
bool prefix;

ctx = nb_running_get_entry_non_rec(&list_node->node, NULL, false);

prefix = dnode->schema->name[0] == 'p' ? true : false;
if (no)
distribute_list_no_parser(ctx, NULL, prefix, ipv4,
dir_node->schema->name,
lyd_get_value(dnode),
lyd_get_value(intf_key));
else
distribute_list_parser(ctx, prefix, ipv4,
dir_node->schema->name,
lyd_get_value(dnode),
lyd_get_value(intf_key));
return NB_OK;
}

static int distribute_list_leaf_modify(struct nb_cb_modify_args *args,
int ip_version)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
return distribute_list_leaf_update(args->dnode, ip_version, false);
}

static int distribute_list_leaf_destroy(struct nb_cb_destroy_args *args,
int ip_version)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
return distribute_list_leaf_update(args->dnode, ip_version, true);
}

int group_distribute_list_ipv4_modify(struct nb_cb_modify_args *args)
{
return distribute_list_leaf_modify(args, 4);
}
int group_distribute_list_ipv4_destroy(struct nb_cb_destroy_args *args)
{
return distribute_list_leaf_destroy(args, 4);
}
int group_distribute_list_ipv6_modify(struct nb_cb_modify_args *args)
{
return distribute_list_leaf_modify(args, 6);
}
int group_distribute_list_ipv6_destroy(struct nb_cb_destroy_args *args)
{
return distribute_list_leaf_destroy(args, 6);
}

static int distribute_list_leaf_cli_show(struct vty *vty,
const struct lyd_node *dnode,
int ip_version)
{
struct lyd_node *dir_node = lyd_parent(dnode);
struct lyd_node_inner *list_node = dir_node->parent;
struct lyd_node *intf_key = list_node->child;
bool ipv6 = ip_version == 6 ? true : false;
bool prefix;

prefix = dnode->schema->name[0] == 'p' ? true : false;
vty_out(vty,
" %sdistribute-list %s%s %s %s\n",
ipv6 ? "ipv6 " : "",
prefix ? "prefix " : "",
lyd_get_value(dnode),
dir_node->schema->name,
lyd_get_value(intf_key));

return NB_OK;
}

void group_distribute_list_ipv4_cli_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
distribute_list_leaf_cli_show(vty, dnode, 4);
}
void group_distribute_list_ipv6_cli_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
distribute_list_leaf_cli_show(vty, dnode, 6);
}

/* ------------- */
/* Setup/Cleanup */
/* ------------- */

>>>>>>> 8fad4f317e (lib: fix distribute-list deletion)
void distribute_list_delete(struct distribute_ctx **ctx)
{
hash_clean_and_free(&(*ctx)->disthash,
Expand Down

0 comments on commit 3b6a11e

Please sign in to comment.