From e2bcfa3946aadc62af53cf53ff8d2f9fe7e5bab1 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Tue, 14 Jul 2020 14:23:48 -0700 Subject: [PATCH] zebra: evpn l3vni map to vrf nb changes The set of northbound changes for l3vni configuration command under vrf. vrf x vni 1000 prefix-routes-only { "frr-vrf:lib": { "vrf": [ { "name": "vrf1", "frr-zebra:zebra": { "l3vni-id": 4001 } }, { "name": "vrf2", "frr-zebra:zebra": { "l3vni-id": 4002, "prefix-only": true } } ] } } Signed-off-by: Chirag Shah --- zebra/zebra_nb.c | 34 ++--- zebra/zebra_nb.h | 9 +- zebra/zebra_nb_config.c | 239 ++++++++++++++++++++++-------------- zebra/zebra_vty.c | 45 +++---- zebra/zebra_vxlan.c | 3 +- zebra/zebra_vxlan_private.h | 1 + 6 files changed, 188 insertions(+), 143 deletions(-) diff --git a/zebra/zebra_nb.c b/zebra/zebra_nb.c index 6f01c41d7..a25d08f26 100644 --- a/zebra/zebra_nb.c +++ b/zebra/zebra_nb.c @@ -91,27 +91,6 @@ const struct frr_yang_module_info frr_zebra_info = { .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 = { @@ -635,6 +614,19 @@ const struct frr_yang_module_info frr_zebra_info = { .get_elem = lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_weight_get_elem, } }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id", + .cbs = { + .modify = lib_vrf_zebra_l3vni_id_modify, + .destroy = lib_vrf_zebra_l3vni_id_destroy, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/prefix-only", + .cbs = { + .modify = lib_vrf_zebra_prefix_only_modify, + } + }, { .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv4-prefix-length", .cbs = { diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h index defa206d5..80aeb02d2 100644 --- a/zebra/zebra_nb.h +++ b/zebra/zebra_nb.h @@ -57,12 +57,6 @@ int zebra_import_kernel_table_route_map_destroy( int zebra_allow_external_route_update_create(struct nb_cb_create_args *args); int zebra_allow_external_route_update_destroy(struct nb_cb_destroy_args *args); int zebra_dplane_queue_limit_modify(struct nb_cb_modify_args *args); -int zebra_vrf_vni_mapping_create(struct nb_cb_create_args *args); -int zebra_vrf_vni_mapping_destroy(struct nb_cb_destroy_args *args); -int zebra_vrf_vni_mapping_vni_id_modify(struct nb_cb_modify_args *args); -int zebra_vrf_vni_mapping_vni_id_destroy(struct nb_cb_destroy_args *args); -int zebra_vrf_vni_mapping_prefix_only_create(struct nb_cb_create_args *args); -int zebra_vrf_vni_mapping_prefix_only_destroy(struct nb_cb_destroy_args *args); int zebra_debugs_debug_events_modify(struct nb_cb_modify_args *args); int zebra_debugs_debug_events_destroy(struct nb_cb_destroy_args *args); int zebra_debugs_debug_zapi_send_modify(struct nb_cb_modify_args *args); @@ -316,6 +310,9 @@ lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_fib_get_elem( struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_weight_get_elem( struct nb_cb_get_elem_args *args); +int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args); +int lib_vrf_zebra_l3vni_id_destroy(struct nb_cb_destroy_args *args); +int lib_vrf_zebra_prefix_only_modify(struct nb_cb_modify_args *args); #ifdef __cplusplus } diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index 259b5f1eb..e4501273b 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -31,6 +31,8 @@ #include "zebra/connected.h" #include "zebra/zebra_router.h" #include "zebra/debug.h" +#include "zebra/zebra_vxlan_private.h" +#include "zebra/zebra_vxlan.h" /* * XPath: /frr-zebra:zebra/mcast-rpf-lookup @@ -272,99 +274,6 @@ int zebra_dplane_queue_limit_modify(struct nb_cb_modify_args *args) return NB_OK; } -/* - * XPath: /frr-zebra:zebra/vrf-vni-mapping - */ -int zebra_vrf_vni_mapping_create(struct nb_cb_create_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -int zebra_vrf_vni_mapping_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -/* - * XPath: /frr-zebra:zebra/vrf-vni-mapping/vni-id - */ -int zebra_vrf_vni_mapping_vni_id_modify(struct nb_cb_modify_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -int zebra_vrf_vni_mapping_vni_id_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -/* - * XPath: /frr-zebra:zebra/vrf-vni-mapping/prefix-only - */ -int zebra_vrf_vni_mapping_prefix_only_create(struct nb_cb_create_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -int zebra_vrf_vni_mapping_prefix_only_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - /* * XPath: /frr-zebra:zebra/debugs/debug-events */ @@ -1277,6 +1186,150 @@ int lib_vrf_zebra_ribs_rib_destroy(struct nb_cb_destroy_args *args) return NB_OK; } +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id + */ +int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct zebra_vrf *zvrf; + vni_t vni = 0; + zebra_l3vni_t *zl3vni = NULL; + struct zebra_vrf *zvrf_evpn = NULL; + char err[ERR_STR_SZ]; + bool pfx_only = false; + const struct lyd_node *pn_dnode; + const char *vrfname; + + switch (args->event) { + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_VALIDATE: + zvrf_evpn = zebra_vrf_get_evpn(); + if (!zvrf_evpn) + return NB_ERR_VALIDATION; + + vni = yang_dnode_get_uint32(args->dnode, NULL); + /* Get vrf info from parent node, reject configuration + * if zebra vrf already mapped to different vni id. + */ + pn_dnode = yang_dnode_get_parent(args->dnode, "vrf"); + if (pn_dnode) { + vrfname = yang_dnode_get_string(pn_dnode, "./name"); + vrf = vrf_lookup_by_name(vrfname); + zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id); + if (zvrf->l3vni && zvrf->l3vni != vni) { + zlog_debug( + "vni %u cannot be configured as vni %u is already configured under the vrf", + vni, zvrf->l3vni); + return NB_ERR_VALIDATION; + } + } + + /* Check if this VNI is already present in the system */ + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "VNI %u is already configured as L3-VNI", + vni); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_APPLY: + + vrf = nb_running_get_entry(args->dnode, NULL, true); + zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id); + vni = yang_dnode_get_uint32(args->dnode, NULL); + /* Note: This covers lib_vrf_zebra_prefix_only_modify() config + * along with l3vni config + */ + pfx_only = yang_dnode_get_bool(args->dnode, "../prefix-only"); + + if (zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, + pfx_only ? 1 : 0, 1) + != 0) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "vrf vni %u mapping failed with error: %s", + vni, err); + return NB_ERR; + } + + /* Mark as having FRR configuration */ + vrf_set_user_cfged(vrf); + + break; + } + + return NB_OK; +} + +int lib_vrf_zebra_l3vni_id_destroy(struct nb_cb_destroy_args *args) +{ + struct vrf *vrf; + struct zebra_vrf *zvrf; + vni_t vni = 0; + char err[ERR_STR_SZ]; + uint8_t filter = 0; + + switch (args->event) { + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_VALIDATE: + break; + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id); + vni = yang_dnode_get_uint32(args->dnode, NULL); + + if (!zl3vni_lookup(vni)) + return NB_OK; + + if (zvrf->l3vni != vni) + return NB_ERR; + + if (is_l3vni_for_prefix_routes_only(zvrf->l3vni)) + filter = 1; + + if (zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, + filter, 0) + != 0) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "vrf vni %u unmapping failed with error: %s", + vni, err); + return NB_ERR; + } + + /* If no other FRR config for this VRF, mark accordingly. */ + if (!zebra_vrf_has_config(zvrf)) + vrf_reset_user_cfged(vrf); + + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/prefix-only + */ +int lib_vrf_zebra_prefix_only_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} /* * XPath: diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index b18871dd2..6aba263d7 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -55,6 +55,7 @@ #include "zebra/zebra_nhg.h" #include "zebra/interface.h" #include "northbound_cli.h" +#include "zebra/zebra_nb.h" extern int allow_delete; @@ -2304,12 +2305,9 @@ DEFUN (vrf_vni_mapping, "VNI-ID\n" "prefix-routes-only\n") { - int ret = 0; int filter = 0; ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); - vni_t vni = strtoul(argv[1]->arg, NULL, 10); - char err[ERR_STR_SZ]; assert(vrf); assert(zvrf); @@ -2317,14 +2315,15 @@ DEFUN (vrf_vni_mapping, if (argc == 3) filter = 1; - /* Mark as having FRR configuration */ - vrf_set_user_cfged(vrf); - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, - filter, 1); - if (ret != 0) { - vty_out(vty, "%s\n", err); - return CMD_WARNING; - } + nb_cli_enqueue_change(vty, "./frr-zebra:zebra", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_MODIFY, + argv[1]->arg); + + if (filter) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only", + NB_OP_MODIFY, "true"); + + nb_cli_apply_changes(vty, NULL); return CMD_SUCCESS; } @@ -2337,12 +2336,10 @@ DEFUN (no_vrf_vni_mapping, "VNI-ID\n" "prefix-routes-only\n") { - int ret = 0; int filter = 0; - char err[ERR_STR_SZ]; - vni_t vni = strtoul(argv[2]->arg, NULL, 10); ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); + vni_t vni = strtoul(argv[1]->arg, NULL, 10); assert(vrf); assert(zvrf); @@ -2350,16 +2347,22 @@ DEFUN (no_vrf_vni_mapping, if (argc == 4) filter = 1; - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, - ERR_STR_SZ, filter, 0); - if (ret != 0) { - vty_out(vty, "%s\n", err); + if (zvrf->l3vni != vni) { + vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni, + zvrf->vrf->name); return CMD_WARNING; } - /* If no other FRR config for this VRF, mark accordingly. */ - if (!zebra_vrf_has_config(zvrf)) - vrf_reset_user_cfged(vrf); + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_DESTROY, + argv[2]->arg); + + if (filter) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only", + NB_OP_DESTROY, "true"); + + nb_cli_enqueue_change(vty, "./frr-zebra:zebra", NB_OP_DESTROY, NULL); + + nb_cli_apply_changes(vty, NULL); return CMD_SUCCESS; } diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 66441e175..e0cf4859c 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -142,7 +142,6 @@ static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac); static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac); /* l3-vni related APIs*/ -static zebra_l3vni_t *zl3vni_lookup(vni_t vni); static void *zl3vni_alloc(void *p); static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id); static int zl3vni_del(zebra_l3vni_t *zl3vni); @@ -5110,7 +5109,7 @@ static void *zl3vni_alloc(void *p) /* * Look up L3 VNI hash entry. */ -static zebra_l3vni_t *zl3vni_lookup(vni_t vni) +zebra_l3vni_t *zl3vni_lookup(vni_t vni) { zebra_l3vni_t tmp_l3vni; zebra_l3vni_t *zl3vni = NULL; diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h index d2b02df2a..e4b06054b 100644 --- a/zebra/zebra_vxlan_private.h +++ b/zebra/zebra_vxlan_private.h @@ -476,6 +476,7 @@ extern zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t vrf_id); extern struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni); extern struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni); extern struct interface *zl3vni_map_to_mac_vlan_if(zebra_l3vni_t *zl3vni); +extern zebra_l3vni_t *zl3vni_lookup(vni_t vni); DECLARE_HOOK(zebra_rmac_update, (zebra_mac_t *rmac, zebra_l3vni_t *zl3vni, bool delete, const char *reason), (rmac, zl3vni, delete, reason)) -- 2.39.5