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;
}
return write;
}
+/* ---------- */
+/* Northbound */
+/* ---------- */
+
+int group_distribute_list_create_helper(
+ struct nb_cb_create_args *args, struct distribute_ctx *ctx)
+{
+ /* The code currently doesn't require this as it uses a global */
+ /* 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 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;
+
+ /* The code currently doesn't require this as it uses a global */
+ /* 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(NULL, prefix, ipv4,
+ dir_node->schema->name,
+ lyd_get_value(dnode),
+ lyd_get_value(intf_key));
+ else
+ distribute_list_parser(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,
#include <zebra.h>
#include "if.h"
#include "filter.h"
+#include "northbound.h"
#ifdef __cplusplus
extern "C" {
extern int distribute_list_no_parser(struct vty *vty, bool prefix, bool v4,
const char *dir, const char *list,
const char *ifname);
+
+/*
+ * Northbound
+ */
+
+/*
+ * Define your own create callback and then call thes helper with your
+ * distribute list context when a list entry is created. Additionally, plug the
+ * destroy callback into the frr_module_yang_info struct, or call it if you have
+ * your own callback destroy function.
+ */
+extern int group_distribute_list_create_helper(struct nb_cb_create_args *args,
+ struct distribute_ctx *ctx);
+extern int group_distribute_list_destroy(struct nb_cb_destroy_args *args);
+
+/*
+ * Plug 3 of these handlers in for your distribute-list for all the northbound
+ * distribute_list leaf callbacks. If you need multi-protocol then use the
+ * grouping twice under 2 different containers.
+ */
+extern int group_distribute_list_ipv4_modify(struct nb_cb_modify_args *args);
+extern int group_distribute_list_ipv4_destroy(struct nb_cb_destroy_args *args);
+extern void group_distribute_list_ipv4_cli_show(struct vty *vty,
+ const struct lyd_node *dnode,
+ bool show_defaults);
+extern int group_distribute_list_ipv6_modify(struct nb_cb_modify_args *args);
+extern int group_distribute_list_ipv6_destroy(struct nb_cb_destroy_args *args);
+extern void group_distribute_list_ipv6_cli_show(struct vty *vty,
+ const struct lyd_node *dnode,
+ bool show_defaults);
#ifdef __cplusplus
}
#endif
import ietf-yang-types {
prefix yang;
}
+ import frr-interface {
+ prefix frr-interface;
+ }
organization "FRRouting";
contact
description "Access list return action on match";
}
+ typedef access-list-ref {
+ type leafref {
+ path "/frr-filter:lib/frr-filter:access-list/frr-filter:name";
+ require-instance false;
+ }
+ description "IPv4 or IPv6 access list reference";
+ }
+
+ typedef prefix-list-ref {
+ type leafref {
+ path "/frr-filter:lib/frr-filter:prefix-list/frr-filter:name";
+ require-instance false;
+ }
+ description "IPv4 or IPv6 prefix list reference";
+ }
+
+ /*
+ * Grouping.
+ */
+ grouping distribute-list-group {
+ description "Distribute list grouping";
+ list distribute-list {
+ key "interface";
+ description "Distribute list configuration";
+
+ leaf interface {
+ type union {
+ type frr-interface:interface-ref;
+ type empty;
+ }
+ description
+ "Interface to attach list to or empty for global.";
+ }
+
+ container in {
+ description "Inbound filter list";
+ leaf access-list {
+ type access-list-ref;
+ description "inbound access list";
+ }
+ leaf prefix-list {
+ type prefix-list-ref;
+ description "inbound prefix list";
+ }
+ }
+ container out {
+ description "Outbound filter list";
+ leaf access-list {
+ type access-list-ref;
+ description "outbound access list";
+ }
+ leaf prefix-list {
+ type prefix-list-ref;
+ description "outbound prefix list";
+ }
+ }
+ }
+ }
+
/*
* Configuration data.
*/
leaf type {
type enumeration {
enum ipv4 {
- value 0;
- description "Internet Protocol address version 4";
- }
- enum ipv6 {
- value 1;
- description "Internet Protocol address version 6";
+ value 0;
+ description "Internet Protocol address version 4";
+ }
+ enum ipv6 {
+ value 1;
+ description "Internet Protocol address version 6";
}
enum mac {
value 2;