diff options
Diffstat (limited to '')
-rw-r--r-- | lib/distribute.c | 153 |
1 files changed, 131 insertions, 22 deletions
diff --git a/lib/distribute.c b/lib/distribute.c index 6548767..ccd1f13 100644 --- a/lib/distribute.c +++ b/lib/distribute.c @@ -17,8 +17,6 @@ DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list"); DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname"); DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name"); -static struct list *dist_ctx_list; - static struct distribute *distribute_new(void) { return XCALLOC(MTYPE_DISTRIBUTE, sizeof(struct distribute)); @@ -244,11 +242,10 @@ static enum distribute_type distribute_direction(const char *dir, bool v4) __builtin_unreachable(); } -int distribute_list_parser(bool prefix, bool v4, const char *dir, - const char *list, const char *ifname) +int distribute_list_parser(struct distribute_ctx *ctx, bool prefix, bool v4, + const char *dir, const char *list, const char *ifname) { enum distribute_type type = distribute_direction(dir, v4); - struct distribute_ctx *ctx = listnode_head(dist_ctx_list); void (*distfn)(struct distribute_ctx *, const char *, enum distribute_type, const char *) = @@ -259,12 +256,12 @@ int distribute_list_parser(bool prefix, bool v4, const char *dir, return CMD_SUCCESS; } -int distribute_list_no_parser(struct vty *vty, bool prefix, bool v4, - const char *dir, const char *list, - const char *ifname) + +int distribute_list_no_parser(struct distribute_ctx *ctx, struct vty *vty, + bool prefix, bool v4, const char *dir, + const char *list, const char *ifname) { enum distribute_type type = distribute_direction(dir, v4); - struct distribute_ctx *ctx = listnode_head(dist_ctx_list); int ret; int (*distfn)(struct distribute_ctx *, const char *, @@ -274,7 +271,8 @@ int distribute_list_no_parser(struct vty *vty, bool prefix, bool v4, ret = distfn(ctx, ifname, type, list); if (!ret) { - vty_out(vty, "distribute list doesn't exist\n"); + if (vty) + vty_out(vty, "distribute list doesn't exist\n"); return CMD_WARNING_CONFIG_FAILED; } @@ -443,17 +441,130 @@ int config_write_distribute(struct vty *vty, return write; } +/* ---------- */ +/* 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 + */ + +int group_distribute_list_destroy(struct nb_cb_destroy_args *args) +{ + 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 */ +/* ------------- */ + void distribute_list_delete(struct distribute_ctx **ctx) { hash_clean_and_free(&(*ctx)->disthash, (void (*)(void *))distribute_free); - if (dist_ctx_list) { - listnode_delete(dist_ctx_list, *ctx); - if (list_isempty(dist_ctx_list)) - list_delete(&dist_ctx_list); - } - XFREE(MTYPE_DISTRIBUTE_CTX, (*ctx)); } @@ -464,11 +575,9 @@ struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf) ctx = XCALLOC(MTYPE_DISTRIBUTE_CTX, sizeof(struct distribute_ctx)); ctx->vrf = vrf; - ctx->disthash = hash_create( - distribute_hash_make, - (bool (*)(const void *, const void *))distribute_cmp, NULL); - if (!dist_ctx_list) - dist_ctx_list = list_new(); - listnode_add(dist_ctx_list, ctx); + ctx->disthash = + hash_create(distribute_hash_make, + (bool (*)(const void *, const void *))distribute_cmp, + NULL); return ctx; } |