diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index 5b03b5266f..41e8cacd81 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -148,6 +148,12 @@ void route_map_instance_show(struct vty *vty, struct lyd_node *dnode, SKIP_RULE("ipv6 next-hop type"); SKIP_RULE("metric"); SKIP_RULE("tag"); + /* Zebra specific match conditions. */ + SKIP_RULE("ip address prefix-len"); + SKIP_RULE("ipv6 address prefix-len"); + SKIP_RULE("ip next-hop prefix-len"); + SKIP_RULE("source-protocol"); + SKIP_RULE("source-instance"); vty_out(vty, " match %s %s\n", rmr->cmd->str, rmr->rule_str ? rmr->rule_str : ""); @@ -158,6 +164,8 @@ void route_map_instance_show(struct vty *vty, struct lyd_node *dnode, /* Skip all sets implemented by northbound. */ SKIP_RULE("metric"); SKIP_RULE("tag"); + /* Zebra specific set actions. */ + SKIP_RULE("src"); vty_out(vty, " set %s %s\n", rmr->cmd->str, rmr->rule_str ? rmr->rule_str : ""); @@ -666,8 +674,25 @@ void route_map_condition_show(struct vty *vty, struct lyd_node *dnode, vty_out(vty, " match tag %s\n", yang_dnode_get_string(dnode, "./tag")); break; - case 100: - /* NOTHING: custom field, should be handled by daemon. */ + case 100: /* ipv4-prefix-length */ + vty_out(vty, " match ip address prefix-len %s\n", + yang_dnode_get_string(dnode,"./frr-zebra:ipv4-prefix-length")); + break; + case 101: /* ipv6-prefix-length */ + vty_out(vty, " match ipv6 address prefix-len %s\n", + yang_dnode_get_string(dnode, "./frr-zebra:ipv6-prefix-length")); + break; + case 102: /* ipv4-next-hop-prefix-length */ + vty_out(vty, " match ip next-hop prefix-len %s\n", + yang_dnode_get_string(dnode, "./frr-zebra:ipv4-prefix-length")); + break; + case 103: /* source-protocol */ + vty_out(vty, " match source-protocol %s\n", + yang_dnode_get_string(dnode, "./frr-zebra:source-protocol")); + break; + case 104: /* source-instance */ + vty_out(vty, " match source-instance %s\n", + yang_dnode_get_string(dnode, "./frr-zebra:source-instance")); break; } } @@ -868,8 +893,13 @@ void route_map_action_show(struct vty *vty, struct lyd_node *dnode, vty_out(vty, " set tag %s\n", yang_dnode_get_string(dnode, "./tag")); break; - case 100: - /* NOTHING: custom field, should be handled by daemon. */ + case 100: /* source */ + if (yang_dnode_exists(dnode, "./frr-zebra:source-v4")) + vty_out(vty, " set src %s\n", + yang_dnode_get_string(dnode, "./frr-zebra:source-v4")); + else + vty_out(vty, " set src %s\n", + yang_dnode_get_string(dnode, "./frr-zebra:source-v6")); break; } } diff --git a/yang/frr-route-map.yang b/yang/frr-route-map.yang index 6e6a193c28..eea29733a3 100644 --- a/yang/frr-route-map.yang +++ b/yang/frr-route-map.yang @@ -179,17 +179,27 @@ module frr-route-map { description "Match a route tag"; value 10; } - - /* - * Protocol YANG models should augment the parent node to - * contain the routing protocol specific value. The protocol - * must also augment `condition-value` to include its specific - * values or expand the `when` statement on the existing cases. - */ - enum routing-protocol-specific { - description "Match a routing protocol specific type"; + /* zebra specific conditions. */ + enum ipv4-prefix-length { + description "Match IPv4 prefix length"; value 100; } + enum ipv6-prefix-length { + description "Match IPv6 prefix length"; + value 101; + } + enum ipv4-next-hop-prefix-length { + description "Match next-hop prefix length"; + value 102; + } + enum source-protocol { + description "Match source protocol"; + value 103; + } + enum source-instance { + description "Match source protocol instance"; + value 104; + } } } @@ -291,15 +301,9 @@ module frr-route-map { description "Set tag"; value 3; } - - /* - * Protocol YANG models should augment the parent node to - * contain the routing protocol specific value. The protocol - * must also augment `action-value` to include its specific - * values or expand the `when` statement on the existing cases. - */ - enum routing-protocol-specific { - description "Set a routing protocol specific action"; + /* zebra specific conditions. */ + enum source { + description "Set source address for route"; value 100; } } diff --git a/yang/frr-route-types.yang b/yang/frr-route-types.yang index 5b60081b2f..8fdd10121e 100644 --- a/yang/frr-route-types.yang +++ b/yang/frr-route-types.yang @@ -106,4 +106,12 @@ module frr-route-types { } } } + + typedef frr-route-types { + description "Route types as enumerated in `lib/route_types.txt`"; + type union { + type frr-route-types-v4; + type frr-route-types-v6; + } + } } diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang index 0e52f9254d..736bbc2c81 100644 --- a/yang/frr-zebra.yang +++ b/yang/frr-zebra.yang @@ -11,6 +11,10 @@ module frr-zebra { prefix inet; } + import frr-route-map { + prefix frr-route-map; + } + import frr-route-types { prefix frr-route-types; } @@ -1985,4 +1989,63 @@ module frr-zebra { } // End interface model augmentation + + augment "/frr-route-map:lib" + + "/frr-route-map:route-map" + + "/frr-route-map:entry" + + "/frr-route-map:match-condition" + + "/frr-route-map:condition-value" { + case ipv4-prefix-length { + when "./condition = 'ipv4-prefix-length' or + ./condition = 'ipv4-next-hop-prefix-length'"; + leaf ipv4-prefix-length { + type uint8 { + range "0..32"; + } + } + } + case ipv6-prefix-length { + when "./condition = 'ipv6-prefix-length'"; + leaf ipv6-prefix-length { + type uint8 { + range "0..128"; + } + } + } + case source-protocol { + when "./condition = 'source-protocol'"; + leaf source-protocol { + type frr-route-types:frr-route-types; + } + } + case source-instance { + when "./condition = 'source-instance'"; + leaf source-instance { + type uint8 { + range "0..255"; + } + } + } + } + + augment "/frr-route-map:lib" + + "/frr-route-map:route-map" + + "/frr-route-map:entry" + + "/frr-route-map:set-action" + + "/frr-route-map:action-value" { + case source-v4 { + when "./action = 'source'"; + leaf source-v4 { + description "IPv4 address"; + type inet:ipv4-address; + } + } + case source-v6 { + when "./action = 'source'"; + leaf source-v6 { + description "IPv6 address"; + type inet:ipv6-address; + } + } + } } diff --git a/yang/subdir.am b/yang/subdir.am index c1297dafd5..0e124c5ab0 100644 --- a/yang/subdir.am +++ b/yang/subdir.am @@ -21,10 +21,12 @@ EXTRA_DIST += yang/embedmodel.py dist_yangmodels_DATA += yang/frr-filter.yang dist_yangmodels_DATA += yang/frr-module-translator.yang +dist_yangmodels_DATA += yang/frr-nexthop.yang dist_yangmodels_DATA += yang/frr-test-module.yang dist_yangmodels_DATA += yang/frr-interface.yang dist_yangmodels_DATA += yang/frr-route-map.yang dist_yangmodels_DATA += yang/frr-route-types.yang +dist_yangmodels_DATA += yang/frr-zebra.yang dist_yangmodels_DATA += yang/ietf/ietf-routing-types.yang if BFDD diff --git a/zebra/main.c b/zebra/main.c index dab1449194..4673ec53e4 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -245,6 +245,7 @@ struct quagga_signal_t zebra_signals[] = { static const struct frr_yang_module_info *const zebra_yang_modules[] = { &frr_interface_info, &frr_route_map_info, + &frr_zebra_info, }; FRR_DAEMON_INFO( diff --git a/zebra/subdir.am b/zebra/subdir.am index 1d49de5410..f281afce94 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -75,6 +75,7 @@ zebra_zebra_SOURCES = \ zebra/zebra_mlag.c \ zebra/zebra_mlag_vty.c \ zebra/zebra_l2.c \ + zebra/zebra_northbound.c \ zebra/zebra_memory.c \ zebra/zebra_dplane.c \ zebra/zebra_mpls.c \ @@ -191,5 +192,10 @@ zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_dt.c endif endif +nodist_zebra_zebra_SOURCES = \ + yang/frr-nexthop.yang.c \ + yang/frr-zebra.yang.c \ + # end + zebra_zebra_cumulus_mlag_la_SOURCES = zebra/zebra_mlag_private.c zebra_zebra_cumulus_mlag_la_LDFLAGS = -avoid-version -module -shared -export-dynamic diff --git a/zebra/zebra_northbound.c b/zebra/zebra_northbound.c new file mode 100644 index 0000000000..9f6514e12f --- /dev/null +++ b/zebra/zebra_northbound.c @@ -0,0 +1,2212 @@ +/* + * Zebra northbound implementation. + * + * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF") + * Rafael Zalamena + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + */ + +#include + +#include "lib/command.h" +#include "lib/log.h" +#include "lib/northbound.h" +#include "lib/routemap.h" + +#include "zebra/rib.h" + +/* + * XPath: /frr-zebra:zebra/mcast-rpf-lookup + */ +static int zebra_mcast_rpf_lookup_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/ip-forwarding + */ +static int zebra_ip_forwarding_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_ip_forwarding_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/ipv6-forwarding + */ +static int zebra_ipv6_forwarding_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_ipv6_forwarding_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/workqueue-hold-timer + */ +static int zebra_workqueue_hold_timer_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/zapi-packets + */ +static int zebra_zapi_packets_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/import-kernel-table/table-id + */ +static int +zebra_import_kernel_table_table_id_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +zebra_import_kernel_table_table_id_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/import-kernel-table/distance + */ +static int +zebra_import_kernel_table_distance_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/import-kernel-table/route-map + */ +static int +zebra_import_kernel_table_route_map_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +zebra_import_kernel_table_route_map_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/allow-external-route-update + */ +static int +zebra_allow_external_route_update_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +zebra_allow_external_route_update_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/dplane-queue-limit + */ +static int zebra_dplane_queue_limit_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/vrf-vni-mapping + */ +static int zebra_vrf_vni_mapping_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_vrf_vni_mapping_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/vrf-vni-mapping/vni-id + */ +static int zebra_vrf_vni_mapping_vni_id_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_vrf_vni_mapping_vni_id_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/vrf-vni-mapping/prefix-only + */ +static int +zebra_vrf_vni_mapping_prefix_only_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +zebra_vrf_vni_mapping_prefix_only_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-events + */ +static int zebra_debugs_debug_events_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_events_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-zapi-send + */ +static int zebra_debugs_debug_zapi_send_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_zapi_send_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-zapi-recv + */ +static int zebra_debugs_debug_zapi_recv_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_zapi_recv_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-zapi-detail + */ +static int zebra_debugs_debug_zapi_detail_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_zapi_detail_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-kernel + */ +static int zebra_debugs_debug_kernel_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_kernel_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-send + */ +static int +zebra_debugs_debug_kernel_msg_send_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +zebra_debugs_debug_kernel_msg_send_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-recv + */ +static int +zebra_debugs_debug_kernel_msg_recv_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +zebra_debugs_debug_kernel_msg_recv_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-rib + */ +static int zebra_debugs_debug_rib_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_rib_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-rib-detail + */ +static int zebra_debugs_debug_rib_detail_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_rib_detail_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-fpm + */ +static int zebra_debugs_debug_fpm_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_fpm_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-nht + */ +static int zebra_debugs_debug_nht_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_nht_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-nht-detail + */ +static int zebra_debugs_debug_nht_detail_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_nht_detail_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-mpls + */ +static int zebra_debugs_debug_mpls_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_mpls_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-vxlan + */ +static int zebra_debugs_debug_vxlan_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_vxlan_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-pw + */ +static int zebra_debugs_debug_pw_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_pw_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-dplane + */ +static int zebra_debugs_debug_dplane_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_dplane_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-dplane-detail + */ +static int zebra_debugs_debug_dplane_detail_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +zebra_debugs_debug_dplane_detail_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-mlag + */ +static int zebra_debugs_debug_mlag_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int zebra_debugs_debug_mlag_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-route-information + */ +static int get_route_information_rpc(const char *xpath, + const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-v6-mroute-info + */ +static int get_v6_mroute_info_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-vrf-info + */ +static int get_vrf_info_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-vrf-vni-info + */ +static int get_vrf_vni_info_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-info + */ +static int get_evpn_info_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-vni-info + */ +static int get_vni_info_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-vni-rmac + */ +static int get_evpn_vni_rmac_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-vni-nexthops + */ +static int get_evpn_vni_nexthops_rpc(const char *xpath, + const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:clear-evpn-dup-addr + */ +static int clear_evpn_dup_addr_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-macs + */ +static int get_evpn_macs_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-arp-cache + */ +static int get_evpn_arp_cache_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-pbr-ipset + */ +static int get_pbr_ipset_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-pbr-iptable + */ +static int get_pbr_iptable_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-debugs + */ +static int get_debugs_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list + */ +static int +lib_interface_zebra_ip4_addr_list_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +lib_interface_zebra_ip4_addr_list_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list/ip4-peer + */ +static int +lib_interface_zebra_ip4_addr_list_ip4_peer_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +lib_interface_zebra_ip4_addr_list_ip4_peer_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list/label + */ +static int +lib_interface_zebra_ip4_addr_list_label_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +lib_interface_zebra_ip4_addr_list_label_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip6-addr-list + */ +static int +lib_interface_zebra_ip6_addr_list_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +lib_interface_zebra_ip6_addr_list_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip6-addr-list/label + */ +static int +lib_interface_zebra_ip6_addr_list_label_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int +lib_interface_zebra_ip6_addr_list_label_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/multicast + */ +static int lib_interface_zebra_multicast_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int lib_interface_zebra_multicast_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-detect + */ +static int lib_interface_zebra_link_detect_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int lib_interface_zebra_link_detect_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/shutdown + */ +static int lib_interface_zebra_shutdown_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int lib_interface_zebra_shutdown_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/bandwidth + */ +static int lib_interface_zebra_bandwidth_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +static int lib_interface_zebra_bandwidth_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + switch (event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: + * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv4-prefix-length + */ +static int lib_route_map_entry_match_condition_ipv4_prefix_length_modify( + enum nb_event event, const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct routemap_hook_context *rhc; + const char *length; + int condition, rv; + + if (event != NB_EV_APPLY) + return NB_OK; + + /* Add configuration. */ + rhc = nb_running_get_entry(dnode, NULL, true); + length = yang_dnode_get_string(dnode, NULL); + condition = yang_dnode_get_enum(dnode, "../frr-route-map:condition"); + + /* Set destroy information. */ + switch (condition) { + case 100: /* ipv4-prefix-length */ + rhc->rhc_rule = "ip address prefix-len"; + break; + + case 102: /* ipv4-next-hop-prefix-length */ + rhc->rhc_rule = "ip next-hop prefix-len"; + break; + } + rhc->rhc_mhook = generic_match_delete; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + rv = generic_match_add(NULL, rhc->rhc_rmi, rhc->rhc_rule, length, + RMAP_EVENT_MATCH_ADDED); + if (rv != CMD_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +static int lib_route_map_entry_match_condition_ipv4_prefix_length_destroy( + enum nb_event event, const struct lyd_node *dnode) +{ + return lib_route_map_entry_match_destroy(event, dnode); +} + +/* + * XPath: + * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv6-prefix-length + */ +static int lib_route_map_entry_match_condition_ipv6_prefix_length_modify( + enum nb_event event, const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct routemap_hook_context *rhc; + const char *length; + int rv; + + if (event != NB_EV_APPLY) + return NB_OK; + + /* Add configuration. */ + rhc = nb_running_get_entry(dnode, NULL, true); + length = yang_dnode_get_string(dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_mhook = generic_match_delete; + rhc->rhc_rule = "ipv6 address prefix-len"; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + rv = generic_match_add(NULL, rhc->rhc_rmi, "ipv6 address prefix-len", + length, RMAP_EVENT_MATCH_ADDED); + if (rv != CMD_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +static int lib_route_map_entry_match_condition_ipv6_prefix_length_destroy( + enum nb_event event, const struct lyd_node *dnode) +{ + return lib_route_map_entry_match_destroy(event, dnode); +} + +/* + * XPath: + * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-protocol + */ +static int lib_route_map_entry_match_condition_source_protocol_modify( + enum nb_event event, const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct routemap_hook_context *rhc; + const char *type; + int rv; + + switch (event) { + case NB_EV_VALIDATE: + type = yang_dnode_get_string(dnode, NULL); + if (proto_name2num(type) == -1) { + zlog_warn("%s: invalid protocol: %s", __func__, type); + return NB_ERR_VALIDATION; + } + return NB_OK; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + /* NOTHING */ + break; + } + + /* Add configuration. */ + rhc = nb_running_get_entry(dnode, NULL, true); + type = yang_dnode_get_string(dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_mhook = generic_match_delete; + rhc->rhc_rule = "source-protocol"; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + rv = generic_match_add(NULL, rhc->rhc_rmi, "source-protocol", type, + RMAP_EVENT_MATCH_ADDED); + if (rv != CMD_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +static int lib_route_map_entry_match_condition_source_protocol_destroy( + enum nb_event event, const struct lyd_node *dnode) +{ + return lib_route_map_entry_match_destroy(event, dnode); +} + +/* + * XPath: + * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-instance + */ +static int lib_route_map_entry_match_condition_source_instance_modify( + enum nb_event event, const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct routemap_hook_context *rhc; + const char *type; + int rv; + + if (event != NB_EV_APPLY) + return NB_OK; + + /* Add configuration. */ + rhc = nb_running_get_entry(dnode, NULL, true); + type = yang_dnode_get_string(dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_mhook = generic_match_delete; + rhc->rhc_rule = "source-instance"; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + rv = generic_match_add(NULL, rhc->rhc_rmi, "source-instance", type, + RMAP_EVENT_MATCH_ADDED); + if (rv != CMD_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +static int lib_route_map_entry_match_condition_source_instance_destroy( + enum nb_event event, const struct lyd_node *dnode) +{ + return lib_route_map_entry_match_destroy(event, dnode); +} + +/* + * XPath: /frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v4 + */ +static int +lib_route_map_entry_set_action_source_v4_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct routemap_hook_context *rhc; + struct interface *pif = NULL; + const char *source; + struct vrf *vrf; + struct prefix p; + int rv; + + switch (event) { + case NB_EV_VALIDATE: + memset(&p, 0, sizeof(p)); + yang_dnode_get_ipv4p(&p, dnode, NULL); + if (zebra_check_addr(&p) == 0) { + zlog_warn("%s: invalid IPv4 address: %s", __func__, + yang_dnode_get_string(dnode, NULL)); + return NB_ERR_VALIDATION; + } + + RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) { + pif = if_lookup_exact_address(&p.u.prefix4, AF_INET, + vrf->vrf_id); + if (pif != NULL) + break; + } + if (pif == NULL) { + zlog_warn("%s: is not a local adddress: %s", __func__, + yang_dnode_get_string(dnode, NULL)); + return NB_ERR_VALIDATION; + } + return NB_OK; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + /* NOTHING */ + break; + } + + /* Add configuration. */ + rhc = nb_running_get_entry(dnode, NULL, true); + source = yang_dnode_get_string(dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_shook = generic_set_delete; + rhc->rhc_rule = "src"; + + rv = generic_set_add(NULL, rhc->rhc_rmi, "src", source); + if (rv != CMD_SUCCESS) { + rhc->rhc_shook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +static int +lib_route_map_entry_set_action_source_v4_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + return lib_route_map_entry_set_destroy(event, dnode); +} + +/* + * XPath: /frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v6 + */ +static int +lib_route_map_entry_set_action_source_v6_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct routemap_hook_context *rhc; + struct interface *pif = NULL; + const char *source; + struct vrf *vrf; + struct prefix p; + int rv; + + switch (event) { + case NB_EV_VALIDATE: + memset(&p, 0, sizeof(p)); + yang_dnode_get_ipv6p(&p, dnode, NULL); + if (zebra_check_addr(&p) == 0) { + zlog_warn("%s: invalid IPv6 address: %s", __func__, + yang_dnode_get_string(dnode, NULL)); + return NB_ERR_VALIDATION; + } + + RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) { + pif = if_lookup_exact_address(&p.u.prefix6, AF_INET6, + vrf->vrf_id); + if (pif != NULL) + break; + } + if (pif == NULL) { + zlog_warn("%s: is not a local adddress: %s", __func__, + yang_dnode_get_string(dnode, NULL)); + return NB_ERR_VALIDATION; + } + return NB_OK; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + /* NOTHING */ + break; + } + + /* Add configuration. */ + rhc = nb_running_get_entry(dnode, NULL, true); + source = yang_dnode_get_string(dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_shook = generic_set_delete; + rhc->rhc_rule = "src"; + + rv = generic_set_add(NULL, rhc->rhc_rmi, "src", source); + if (rv != CMD_SUCCESS) { + rhc->rhc_shook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +static int +lib_route_map_entry_set_action_source_v6_destroy(enum nb_event event, + const struct lyd_node *dnode) +{ + return lib_route_map_entry_set_destroy(event, dnode); +} + +/* clang-format off */ +const struct frr_yang_module_info frr_zebra_info = { + .name = "frr-zebra", + .nodes = { + { + .xpath = "/frr-zebra:zebra/mcast-rpf-lookup", + .cbs = { + .modify = zebra_mcast_rpf_lookup_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/ip-forwarding", + .cbs = { + .modify = zebra_ip_forwarding_modify, + .destroy = zebra_ip_forwarding_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/ipv6-forwarding", + .cbs = { + .modify = zebra_ipv6_forwarding_modify, + .destroy = zebra_ipv6_forwarding_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/workqueue-hold-timer", + .cbs = { + .modify = zebra_workqueue_hold_timer_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/zapi-packets", + .cbs = { + .modify = zebra_zapi_packets_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/import-kernel-table/table-id", + .cbs = { + .modify = zebra_import_kernel_table_table_id_modify, + .destroy = zebra_import_kernel_table_table_id_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/import-kernel-table/distance", + .cbs = { + .modify = zebra_import_kernel_table_distance_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/import-kernel-table/route-map", + .cbs = { + .modify = zebra_import_kernel_table_route_map_modify, + .destroy = zebra_import_kernel_table_route_map_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/allow-external-route-update", + .cbs = { + .create = zebra_allow_external_route_update_create, + .destroy = zebra_allow_external_route_update_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/dplane-queue-limit", + .cbs = { + .modify = zebra_dplane_queue_limit_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/vrf-vni-mapping", + .cbs = { + .create = zebra_vrf_vni_mapping_create, + .destroy = zebra_vrf_vni_mapping_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/vrf-vni-mapping/vni-id", + .cbs = { + .modify = zebra_vrf_vni_mapping_vni_id_modify, + .destroy = zebra_vrf_vni_mapping_vni_id_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/vrf-vni-mapping/prefix-only", + .cbs = { + .create = zebra_vrf_vni_mapping_prefix_only_create, + .destroy = zebra_vrf_vni_mapping_prefix_only_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-events", + .cbs = { + .modify = zebra_debugs_debug_events_modify, + .destroy = zebra_debugs_debug_events_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-zapi-send", + .cbs = { + .modify = zebra_debugs_debug_zapi_send_modify, + .destroy = zebra_debugs_debug_zapi_send_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-zapi-recv", + .cbs = { + .modify = zebra_debugs_debug_zapi_recv_modify, + .destroy = zebra_debugs_debug_zapi_recv_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-zapi-detail", + .cbs = { + .modify = zebra_debugs_debug_zapi_detail_modify, + .destroy = zebra_debugs_debug_zapi_detail_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-kernel", + .cbs = { + .modify = zebra_debugs_debug_kernel_modify, + .destroy = zebra_debugs_debug_kernel_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-kernel-msg-send", + .cbs = { + .modify = zebra_debugs_debug_kernel_msg_send_modify, + .destroy = zebra_debugs_debug_kernel_msg_send_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-kernel-msg-recv", + .cbs = { + .modify = zebra_debugs_debug_kernel_msg_recv_modify, + .destroy = zebra_debugs_debug_kernel_msg_recv_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-rib", + .cbs = { + .modify = zebra_debugs_debug_rib_modify, + .destroy = zebra_debugs_debug_rib_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-rib-detail", + .cbs = { + .modify = zebra_debugs_debug_rib_detail_modify, + .destroy = zebra_debugs_debug_rib_detail_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-fpm", + .cbs = { + .modify = zebra_debugs_debug_fpm_modify, + .destroy = zebra_debugs_debug_fpm_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-nht", + .cbs = { + .modify = zebra_debugs_debug_nht_modify, + .destroy = zebra_debugs_debug_nht_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-nht-detail", + .cbs = { + .modify = zebra_debugs_debug_nht_detail_modify, + .destroy = zebra_debugs_debug_nht_detail_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-mpls", + .cbs = { + .modify = zebra_debugs_debug_mpls_modify, + .destroy = zebra_debugs_debug_mpls_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-vxlan", + .cbs = { + .modify = zebra_debugs_debug_vxlan_modify, + .destroy = zebra_debugs_debug_vxlan_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-pw", + .cbs = { + .modify = zebra_debugs_debug_pw_modify, + .destroy = zebra_debugs_debug_pw_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-dplane", + .cbs = { + .modify = zebra_debugs_debug_dplane_modify, + .destroy = zebra_debugs_debug_dplane_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-dplane-detail", + .cbs = { + .modify = zebra_debugs_debug_dplane_detail_modify, + .destroy = zebra_debugs_debug_dplane_detail_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-mlag", + .cbs = { + .modify = zebra_debugs_debug_mlag_modify, + .destroy = zebra_debugs_debug_mlag_destroy, + } + }, + { + .xpath = "/frr-zebra:get-route-information", + .cbs = { + .rpc = get_route_information_rpc, + } + }, + { + .xpath = "/frr-zebra:get-v6-mroute-info", + .cbs = { + .rpc = get_v6_mroute_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-vrf-info", + .cbs = { + .rpc = get_vrf_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-vrf-vni-info", + .cbs = { + .rpc = get_vrf_vni_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-info", + .cbs = { + .rpc = get_evpn_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-vni-info", + .cbs = { + .rpc = get_vni_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-vni-rmac", + .cbs = { + .rpc = get_evpn_vni_rmac_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-vni-nexthops", + .cbs = { + .rpc = get_evpn_vni_nexthops_rpc, + } + }, + { + .xpath = "/frr-zebra:clear-evpn-dup-addr", + .cbs = { + .rpc = clear_evpn_dup_addr_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-macs", + .cbs = { + .rpc = get_evpn_macs_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-arp-cache", + .cbs = { + .rpc = get_evpn_arp_cache_rpc, + } + }, + { + .xpath = "/frr-zebra:get-pbr-ipset", + .cbs = { + .rpc = get_pbr_ipset_rpc, + } + }, + { + .xpath = "/frr-zebra:get-pbr-iptable", + .cbs = { + .rpc = get_pbr_iptable_rpc, + } + }, + { + .xpath = "/frr-zebra:get-debugs", + .cbs = { + .rpc = get_debugs_rpc, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list", + .cbs = { + .create = lib_interface_zebra_ip4_addr_list_create, + .destroy = lib_interface_zebra_ip4_addr_list_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list/ip4-peer", + .cbs = { + .modify = lib_interface_zebra_ip4_addr_list_ip4_peer_modify, + .destroy = lib_interface_zebra_ip4_addr_list_ip4_peer_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list/label", + .cbs = { + .modify = lib_interface_zebra_ip4_addr_list_label_modify, + .destroy = lib_interface_zebra_ip4_addr_list_label_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip6-addr-list", + .cbs = { + .create = lib_interface_zebra_ip6_addr_list_create, + .destroy = lib_interface_zebra_ip6_addr_list_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip6-addr-list/label", + .cbs = { + .modify = lib_interface_zebra_ip6_addr_list_label_modify, + .destroy = lib_interface_zebra_ip6_addr_list_label_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/multicast", + .cbs = { + .modify = lib_interface_zebra_multicast_modify, + .destroy = lib_interface_zebra_multicast_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-detect", + .cbs = { + .modify = lib_interface_zebra_link_detect_modify, + .destroy = lib_interface_zebra_link_detect_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/shutdown", + .cbs = { + .modify = lib_interface_zebra_shutdown_modify, + .destroy = lib_interface_zebra_shutdown_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/bandwidth", + .cbs = { + .modify = lib_interface_zebra_bandwidth_modify, + .destroy = lib_interface_zebra_bandwidth_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv4-prefix-length", + .cbs = { + .modify = lib_route_map_entry_match_condition_ipv4_prefix_length_modify, + .destroy = lib_route_map_entry_match_condition_ipv4_prefix_length_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv6-prefix-length", + .cbs = { + .modify = lib_route_map_entry_match_condition_ipv6_prefix_length_modify, + .destroy = lib_route_map_entry_match_condition_ipv6_prefix_length_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-protocol", + .cbs = { + .modify = lib_route_map_entry_match_condition_source_protocol_modify, + .destroy = lib_route_map_entry_match_condition_source_protocol_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-instance", + .cbs = { + .modify = lib_route_map_entry_match_condition_source_instance_modify, + .destroy = lib_route_map_entry_match_condition_source_instance_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v4", + .cbs = { + .modify = lib_route_map_entry_set_action_source_v4_modify, + .destroy = lib_route_map_entry_set_action_source_v4_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v6", + .cbs = { + .modify = lib_route_map_entry_set_action_source_v6_modify, + .destroy = lib_route_map_entry_set_action_source_v6_destroy, + } + }, + { + .xpath = NULL, + }, + } +}; diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 500c2c84a1..2b3b3afbb5 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -30,6 +30,8 @@ #include "filter.h" #include "plist.h" #include "nexthop.h" +#include "northbound_cli.h" +#include "route_types.h" #include "vrf.h" #include "frrstr.h" @@ -58,82 +60,6 @@ struct nh_rmap_obj { static void zebra_route_map_set_delay_timer(uint32_t value); - -/* Add zebra route map rule */ -static int zebra_route_match_add(struct vty *vty, const char *command, - const char *arg, route_map_event_t type) -{ - VTY_DECLVAR_CONTEXT(route_map_index, index); - enum rmap_compile_rets ret; - int retval = CMD_SUCCESS; - - ret = route_map_add_match(index, command, arg, type); - switch (ret) { - case RMAP_RULE_MISSING: - vty_out(vty, "%% Zebra Can't find rule.\n"); - retval = CMD_WARNING_CONFIG_FAILED; - break; - case RMAP_COMPILE_ERROR: - vty_out(vty, "%% Zebra Argument is malformed.\n"); - retval = CMD_WARNING_CONFIG_FAILED; - break; - case RMAP_COMPILE_SUCCESS: - /* - * Nothing to do here - */ - break; - } - - return retval; -} - -/* Delete zebra route map rule. */ -static int zebra_route_match_delete(struct vty *vty, const char *command, - const char *arg, route_map_event_t type) -{ - VTY_DECLVAR_CONTEXT(route_map_index, index); - enum rmap_compile_rets ret; - int retval = CMD_SUCCESS; - char *dep_name = NULL; - const char *tmpstr; - char *rmap_name = NULL; - - if (type != RMAP_EVENT_MATCH_DELETED) { - /* ignore the mundane, the types without any dependency */ - if (arg == NULL) { - if ((tmpstr = route_map_get_match_arg(index, command)) - != NULL) - dep_name = - XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr); - } else { - dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg); - } - rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name); - } - - ret = route_map_delete_match(index, command, arg, type); - switch (ret) { - case RMAP_RULE_MISSING: - vty_out(vty, "%% Zebra Can't find rule.\n"); - retval = CMD_WARNING_CONFIG_FAILED; - break; - case RMAP_COMPILE_ERROR: - vty_out(vty, "%% Zebra Argument is malformed.\n"); - retval = CMD_WARNING_CONFIG_FAILED; - break; - case RMAP_COMPILE_SUCCESS: - /* - * Nothing to do here - */ - break; - } - - XFREE(MTYPE_ROUTE_MAP_RULE, dep_name); - XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name); - - return retval; -} - /* 'match tag TAG' * Match function return 1 if match is success else return 0 */ @@ -425,246 +351,227 @@ static int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype, return CMD_SUCCESS; } -DEFUN (match_ip_address_prefix_len, - match_ip_address_prefix_len_cmd, - "match ip address prefix-len (0-32)", - MATCH_STR - IP_STR - "Match prefix length of ip address\n" - "Match prefix length of ip address\n" - "Prefix length\n") +DEFPY( + match_ip_address_prefix_len, match_ip_address_prefix_len_cmd, + "match ip address prefix-len (0-32)$length", + MATCH_STR + IP_STR + "Match prefix length of IP address\n" + "Match prefix length of IP address\n" + "Prefix length\n") { - return zebra_route_match_add(vty, "ip address prefix-len", argv[4]->arg, - RMAP_EVENT_MATCH_ADDED); + const char *xpath = "./match-condition[condition='ipv4-prefix-length']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_value, sizeof(xpath_value), + "%s/frr-zebra:ipv4-prefix-length", xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_match_ip_address_prefix_len, - no_match_ip_address_prefix_len_cmd, - "no match ip address prefix-len [(0-32)]", - NO_STR - MATCH_STR - IP_STR - "Match prefix length of ip address\n" - "Match prefix length of ip address\n" - "Prefix length\n") +DEFPY( + no_match_ip_address_prefix_len, no_match_ip_address_prefix_len_cmd, + "no match ip address prefix-len [(0-32)]", + NO_STR + MATCH_STR + IP_STR + "Match prefix length of IP address\n" + "Match prefix length of IP address\n" + "Prefix length\n") { - char *plen = (argc == 6) ? argv[5]->arg : NULL; - return zebra_route_match_delete(vty, "ip address prefix-len", plen, - RMAP_EVENT_MATCH_DELETED); + const char *xpath = "./match-condition[condition='ipv4-prefix-length']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (match_ipv6_address_prefix_len, - match_ipv6_address_prefix_len_cmd, - "match ipv6 address prefix-len (0-128)", - MATCH_STR - IPV6_STR - "Match prefix length of ipv6 address\n" - "Match prefix length of ipv6 address\n" - "Prefix length\n") +DEFPY( + match_ipv6_address_prefix_len, match_ipv6_address_prefix_len_cmd, + "match ipv6 address prefix-len (0-128)$length", + MATCH_STR + IPV6_STR + "Match prefix length of IPv6 address\n" + "Match prefix length of IPv6 address\n" + "Prefix length\n") { - return zebra_route_match_add(vty, "ipv6 address prefix-len", - argv[4]->arg, RMAP_EVENT_MATCH_ADDED); + const char *xpath = "./match-condition[condition='ipv6-prefix-length']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_value, sizeof(xpath_value), + "%s/frr-zebra:ipv6-prefix-length", xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_match_ipv6_address_prefix_len, - no_match_ipv6_address_prefix_len_cmd, - "no match ipv6 address prefix-len [(0-128)]", - NO_STR - MATCH_STR - IPV6_STR - "Match prefix length of ip address\n" - "Match prefix length of ip address\n" - "Prefix length\n") +DEFPY( + no_match_ipv6_address_prefix_len, no_match_ipv6_address_prefix_len_cmd, + "no match ipv6 address prefix-len [(0-128)]", + NO_STR + MATCH_STR + IPV6_STR + "Match prefix length of IPv6 address\n" + "Match prefix length of IPv6 address\n" + "Prefix length\n") { - char *plen = (argc == 6) ? argv[5]->arg : NULL; - return zebra_route_match_delete(vty, "ipv6 address prefix-len", plen, - RMAP_EVENT_MATCH_DELETED); + const char *xpath = "./match-condition[condition='ipv6-prefix-length']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (match_ip_nexthop_prefix_len, - match_ip_nexthop_prefix_len_cmd, - "match ip next-hop prefix-len (0-32)", - MATCH_STR - IP_STR - "Match prefixlen of nexthop ip address\n" - "Match prefixlen of given nexthop\n" - "Prefix length\n") +DEFPY( + match_ip_nexthop_prefix_len, match_ip_nexthop_prefix_len_cmd, + "match ip next-hop prefix-len (0-32)$length", + MATCH_STR + IP_STR + "Match prefixlen of nexthop IP address\n" + "Match prefixlen of given nexthop\n" + "Prefix length\n") { - return zebra_route_match_add(vty, "ip next-hop prefix-len", - argv[4]->arg, RMAP_EVENT_MATCH_ADDED); + const char *xpath = + "./match-condition[condition='ipv4-next-hop-prefix-length']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_value, sizeof(xpath_value), + "%s/frr-zebra:ipv4-prefix-length", xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_match_ip_nexthop_prefix_len, - no_match_ip_nexthop_prefix_len_cmd, - "no match ip next-hop prefix-len [(0-32)]", - NO_STR - MATCH_STR - IP_STR - "Match prefixlen of nexthop ip address\n" - "Match prefix length of nexthop\n" - "Prefix length\n") +DEFPY( + no_match_ip_nexthop_prefix_len, no_match_ip_nexthop_prefix_len_cmd, + "no match ip next-hop prefix-len [(0-32)]", + NO_STR + MATCH_STR + IP_STR + "Match prefixlen of nexthop IP address\n" + "Match prefix length of nexthop\n" + "Prefix length\n") { - char *plen = (argc == 6) ? argv[5]->arg : NULL; - return zebra_route_match_delete(vty, "ip next-hop prefix-len", plen, - RMAP_EVENT_MATCH_DELETED); + const char *xpath = + "./match-condition[condition='ipv4-next-hop-prefix-length']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (match_source_protocol, - match_source_protocol_cmd, - "match source-protocol ", - MATCH_STR - "Match protocol via which the route was learnt\n" - "BGP protocol\n" - "OSPF protocol\n" - "RIP protocol\n" - "RIPNG protocol\n" - "ISIS protocol\n" - "OSPF6 protocol\n" - "PIM protocol\n" - "NHRP protocol\n" - "EIGRP protocol\n" - "BABEL protocol\n" - "Routes from directly connected peer\n" - "Routes from system configuration\n" - "Routes from kernel\n" - "Statically configured routes\n" - "SHARP process\n") +DEFPY( + match_source_protocol, match_source_protocol_cmd, + "match source-protocol " FRR_REDIST_STR_ZEBRA "$proto", + MATCH_STR + "Match protocol via which the route was learnt\n" + FRR_REDIST_HELP_STR_ZEBRA) { - char *proto = argv[2]->text; - int i; + const char *xpath = "./match-condition[condition='source-protocol']"; + char xpath_value[XPATH_MAXLEN]; - i = proto_name2num(proto); - if (i < 0) { - vty_out(vty, "invalid protocol name \"%s\"\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - return zebra_route_match_add(vty, "source-protocol", proto, - RMAP_EVENT_MATCH_ADDED); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_value, sizeof(xpath_value), + "%s/frr-zebra:source-protocol", xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, proto); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_match_source_protocol, - no_match_source_protocol_cmd, - "no match source-protocol []", - NO_STR - MATCH_STR - "No match protocol via which the route was learnt\n" - "BGP protocol\n" - "OSPF protocol\n" - "RIP protocol\n" - "RIPNG protocol\n" - "ISIS protocol\n" - "OSPF6 protocol\n" - "PIM protocol\n" - "NHRP protocol\n" - "EIGRP protocol\n" - "BABEL protocol\n" - "Routes from directly connected peer\n" - "Routes from system configuration\n" - "Routes from kernel\n" - "Statically configured routes\n" - "SHARP process\n") +DEFPY( + no_match_source_protocol, no_match_source_protocol_cmd, + "no match source-protocol [" FRR_REDIST_STR_ZEBRA "]", + NO_STR + MATCH_STR + "Match protocol via which the route was learnt\n" + FRR_REDIST_HELP_STR_ZEBRA) { - char *proto = (argc == 4) ? argv[3]->text : NULL; - return zebra_route_match_delete(vty, "source-protocol", proto, - RMAP_EVENT_MATCH_DELETED); + const char *xpath = "./match-condition[condition='source-protocol']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (match_source_instance, - match_source_instance_cmd, - "match source-instance (0-255)", - MATCH_STR - "Match the protocol's instance number\n" - "The instance number\n") +DEFPY( + match_source_instance, match_source_instance_cmd, + "match source-instance (0-255)$instance", + MATCH_STR + "Match the protocol's instance number\n" + "The instance number\n") { - char *instance = argv[2]->arg; + const char *xpath = "./match-condition[condition='source-instance']"; + char xpath_value[XPATH_MAXLEN]; - return zebra_route_match_add(vty, "source-instance", instance, - RMAP_EVENT_MATCH_ADDED); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_value, sizeof(xpath_value), + "%s/frr-zebra:source-instance", xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, instance_str); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_match_source_instance, - no_match_source_instance_cmd, - "no match source-instance [(0-255)]", - NO_STR MATCH_STR - "Match the protocol's instance number\n" - "The instance number\n") +DEFPY( + no_match_source_instance, no_match_source_instance_cmd, + "no match source-instance [(0-255)]", + NO_STR MATCH_STR + "Match the protocol's instance number\n" + "The instance number\n") { - char *instance = (argc == 4) ? argv[3]->arg : NULL; + const char *xpath = "./match-condition[condition='source-instance']"; - return zebra_route_match_delete(vty, "source-instance", instance, - RMAP_EVENT_MATCH_ADDED); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } /* set functions */ -DEFUN (set_src, - set_src_cmd, - "set src ", - SET_STR - "src address for route\n" - "IPv4 src address\n" - "IPv6 src address\n") +DEFPY( + set_src, set_src_cmd, + "set src ", + SET_STR + "src address for route\n" + "IPv4 src address\n" + "IPv6 src address\n") { - int idx_ip = 2; - union g_addr src; - struct interface *pif = NULL; - int family; - struct prefix p; - struct vrf *vrf; + const char *xpath = "./set-action[action='source']"; + char xpath_value[XPATH_MAXLEN]; - if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1) { - if (inet_pton(AF_INET6, argv[idx_ip]->arg, &src.ipv6) != 1) { - vty_out(vty, "%% not a valid IPv4/v6 address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - p.family = family = AF_INET6; - p.u.prefix6 = src.ipv6; - p.prefixlen = IPV6_MAX_BITLEN; + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (addrv4_str) { + snprintf(xpath_value, sizeof(xpath_value), + "%s/frr-zebra:source-v4", xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + addrv4_str); } else { - p.family = family = AF_INET; - p.u.prefix4 = src.ipv4; - p.prefixlen = IPV4_MAX_BITLEN; + snprintf(xpath_value, sizeof(xpath_value), + "%s/frr-zebra:source-v6", xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + addrv6_str); } - if (!zebra_check_addr(&p)) { - vty_out(vty, "%% not a valid source IPv4/v6 address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if (family == AF_INET) - pif = if_lookup_exact_address((void *)&src.ipv4, - AF_INET, vrf->vrf_id); - else if (family == AF_INET6) - pif = if_lookup_exact_address((void *)&src.ipv6, - AF_INET6, vrf->vrf_id); - - if (pif != NULL) - break; - } - - if (!pif) { - vty_out(vty, "%% not a local address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - VTY_DECLVAR_CONTEXT(route_map_index, index); - return generic_set_add(vty, index, "src", argv[idx_ip]->arg); + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_set_src, - no_set_src_cmd, - "no set src []", - NO_STR - SET_STR - "Source address for route\n" - "IPv4 address\n" - "IPv6 address\n") +DEFPY( + no_set_src, no_set_src_cmd, + "no set src []", + NO_STR + SET_STR + "Source address for route\n" + "IPv4 address\n" + "IPv6 address\n") { - char *ip = (argc == 4) ? argv[3]->arg : NULL; - VTY_DECLVAR_CONTEXT(route_map_index, index); - return generic_set_delete(vty, index, "src", ip); + const char *xpath = "./set-action[action='source']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } DEFUN (zebra_route_map_timer, diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index 59bd0e55f0..773e5a6415 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -218,6 +218,9 @@ extern void multicast_mode_ipv4_set(enum multicast_mode mode); extern enum multicast_mode multicast_mode_ipv4_get(void); +/* zebra_northbound.c */ +extern const struct frr_yang_module_info frr_zebra_info; + #ifdef __cplusplus } #endif