diff options
Diffstat (limited to '')
-rw-r--r-- | zebra/zebra_vty.c | 386 |
1 files changed, 82 insertions, 304 deletions
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index d36c2f8..9a68d5a 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -20,6 +20,7 @@ #include "vxlan.h" #include "termtable.h" #include "affinitymap.h" +#include "frrdistance.h" #include "zebra/zebra_router.h" #include "zebra/zserv.h" @@ -50,6 +51,7 @@ #include "zebra/zebra_script.h" #include "zebra/rtadv.h" #include "zebra/zebra_neigh.h" +#include "zebra/zebra_ptm.h" /* context to manage dumps in multiple tables or vrfs */ struct route_show_ctx { @@ -58,8 +60,8 @@ struct route_show_ctx { }; static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, bool use_json, - route_tag_t tag, + safi_t safi, bool use_fib, json_object *vrf_json, + bool use_json, route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, unsigned short ospf_instance_id, uint32_t tableid, @@ -146,8 +148,8 @@ DEFPY (show_ip_rpf, }; return do_show_ip_route(vty, VRF_DEFAULT_NAME, ip ? AFI_IP : AFI_IP6, - SAFI_MULTICAST, false, uj, 0, NULL, false, 0, 0, - 0, false, &ctx); + SAFI_MULTICAST, false, NULL, uj, 0, NULL, false, + 0, 0, 0, false, &ctx); } DEFPY (show_ip_rpf_addr, @@ -764,9 +766,10 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, } /* Distance and metric display. */ - if (((re->type == ZEBRA_ROUTE_CONNECT) && + if (((re->type == ZEBRA_ROUTE_CONNECT || + re->type == ZEBRA_ROUTE_LOCAL) && (re->distance || re->metric)) || - (re->type != ZEBRA_ROUTE_CONNECT)) + (re->type != ZEBRA_ROUTE_CONNECT && re->type != ZEBRA_ROUTE_LOCAL)) len += vty_out(vty, " [%u/%u]", re->distance, re->metric); @@ -853,14 +856,13 @@ static void vty_show_ip_route_detail_json(struct vty *vty, vty_json(vty, json); } -static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, - struct route_table *table, afi_t afi, - bool use_fib, route_tag_t tag, - const struct prefix *longer_prefix_p, - bool supernets_only, int type, - unsigned short ospf_instance_id, bool use_json, - uint32_t tableid, bool show_ng, - struct route_show_ctx *ctx) +static void +do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, + struct route_table *table, afi_t afi, bool use_fib, + json_object *vrf_json, route_tag_t tag, + const struct prefix *longer_prefix_p, bool supernets_only, + int type, unsigned short ospf_instance_id, bool use_json, + uint32_t tableid, bool show_ng, struct route_show_ctx *ctx) { struct route_node *rn; struct route_entry *re; @@ -882,7 +884,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, * => display the VRF and table if specific */ - if (use_json) + if (use_json && !vrf_json) json = json_object_new_object(); /* Show all routes. */ @@ -957,7 +959,11 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, if (json_prefix) { prefix2str(&rn->p, buf, sizeof(buf)); - json_object_object_add(json, buf, json_prefix); + if (!vrf_json) + json_object_object_add(json, buf, json_prefix); + else + json_object_object_add(vrf_json, buf, + json_prefix); json_prefix = NULL; } } @@ -966,13 +972,15 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, * This is an extremely expensive operation at scale * and non-pretty reduces memory footprint significantly. */ - if (use_json) + if (use_json && !vrf_json) { vty_json_no_pretty(vty, json); + json = NULL; + } } static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf, - afi_t afi, bool use_fib, bool use_json, - route_tag_t tag, + afi_t afi, bool use_fib, json_object *vrf_json, + bool use_json, route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, unsigned short ospf_instance_id, bool show_ng, @@ -992,15 +1000,15 @@ static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf, continue; do_show_ip_route(vty, zvrf_name(zvrf), afi, SAFI_UNICAST, - use_fib, use_json, tag, longer_prefix_p, - supernets_only, type, ospf_instance_id, - zrt->tableid, show_ng, ctx); + use_fib, vrf_json, use_json, tag, + longer_prefix_p, supernets_only, type, + ospf_instance_id, zrt->tableid, show_ng, ctx); } } static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, bool use_json, - route_tag_t tag, + safi_t safi, bool use_fib, json_object *vrf_json, + bool use_json, route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, unsigned short ospf_instance_id, uint32_t tableid, @@ -1035,7 +1043,7 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, return CMD_SUCCESS; } - do_show_route_helper(vty, zvrf, table, afi, use_fib, tag, + do_show_route_helper(vty, zvrf, table, afi, use_fib, vrf_json, tag, longer_prefix_p, supernets_only, type, ospf_instance_id, use_json, tableid, show_ng, ctx); @@ -1161,27 +1169,6 @@ DEFPY (show_ip_nht, return CMD_SUCCESS; } -DEFUN (ip_nht_default_route, - ip_nht_default_route_cmd, - "ip nht resolve-via-default", - IP_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (zvrf->zebra_rnh_ip_default_route) - return CMD_SUCCESS; - - zvrf->zebra_rnh_ip_default_route = true; - - zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST); - return CMD_SUCCESS; -} - static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe, json_object *json_nhe_hdr) { @@ -1680,68 +1667,6 @@ DEFPY_HIDDEN(backup_nexthop_recursive_use_enable, return CMD_SUCCESS; } -DEFUN (no_ip_nht_default_route, - no_ip_nht_default_route_cmd, - "no ip nht resolve-via-default", - NO_STR - IP_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (!zvrf->zebra_rnh_ip_default_route) - return CMD_SUCCESS; - - zvrf->zebra_rnh_ip_default_route = false; - zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST); - return CMD_SUCCESS; -} - -DEFUN (ipv6_nht_default_route, - ipv6_nht_default_route_cmd, - "ipv6 nht resolve-via-default", - IP6_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (zvrf->zebra_rnh_ipv6_default_route) - return CMD_SUCCESS; - - zvrf->zebra_rnh_ipv6_default_route = true; - zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST); - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nht_default_route, - no_ipv6_nht_default_route_cmd, - "no ipv6 nht resolve-via-default", - NO_STR - IP6_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (!zvrf->zebra_rnh_ipv6_default_route) - return CMD_SUCCESS; - - zvrf->zebra_rnh_ipv6_default_route = false; - zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST); - return CMD_SUCCESS; -} - DEFPY_HIDDEN(rnh_hide_backups, rnh_hide_backups_cmd, "[no] ip nht hide-backup-events", NO_STR @@ -1815,6 +1740,7 @@ DEFPY (show_route, struct route_show_ctx ctx = { .multi = vrf_all || table_all, }; + json_object *root_json = NULL; if (!vrf_is_backend_netns()) { if ((vrf_all || vrf_name) && (table || table_all)) { @@ -1836,24 +1762,42 @@ DEFPY (show_route, } if (vrf_all) { + if (!!json) + root_json = json_object_new_object(); RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + json_object *vrf_json = NULL; + if ((zvrf = vrf->info) == NULL || (zvrf->table[afi][SAFI_UNICAST] == NULL)) continue; + if (!!json) + vrf_json = json_object_new_object(); + if (table_all) - do_show_ip_route_all( - vty, zvrf, afi, !!fib, !!json, tag, - prefix_str ? prefix : NULL, - !!supernets_only, type, - ospf_instance_id, !!ng, &ctx); + do_show_ip_route_all(vty, zvrf, afi, !!fib, + vrf_json, !!json, tag, + prefix_str ? prefix : NULL, + !!supernets_only, type, + ospf_instance_id, !!ng, + &ctx); else - do_show_ip_route( - vty, zvrf_name(zvrf), afi, SAFI_UNICAST, - !!fib, !!json, tag, - prefix_str ? prefix : NULL, - !!supernets_only, type, - ospf_instance_id, table, !!ng, &ctx); + do_show_ip_route(vty, zvrf_name(zvrf), afi, + SAFI_UNICAST, !!fib, vrf_json, + !!json, tag, + prefix_str ? prefix : NULL, + !!supernets_only, type, + ospf_instance_id, table, !!ng, + &ctx); + + if (!!json) + json_object_object_add(root_json, + zvrf_name(zvrf), + vrf_json); + } + if (!!json) { + vty_json_no_pretty(vty, root_json); + root_json = NULL; } } else { vrf_id_t vrf_id = VRF_DEFAULT; @@ -1869,13 +1813,13 @@ DEFPY (show_route, return CMD_SUCCESS; if (table_all) - do_show_ip_route_all(vty, zvrf, afi, !!fib, !!json, tag, - prefix_str ? prefix : NULL, + do_show_ip_route_all(vty, zvrf, afi, !!fib, NULL, !!json, + tag, prefix_str ? prefix : NULL, !!supernets_only, type, ospf_instance_id, !!ng, &ctx); else do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, - !!fib, !!json, tag, + !!fib, NULL, !!json, tag, prefix_str ? prefix : NULL, !!supernets_only, type, ospf_instance_id, table, !!ng, &ctx); @@ -2251,7 +2195,8 @@ static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table) vrf_id_to_name(re->vrf_id)); vty_out(vty, " flags: %u\n", re->flags); - if (re->type != ZEBRA_ROUTE_CONNECT) { + if (re->type != ZEBRA_ROUTE_CONNECT && + re->type != ZEBRA_ROUTE_LOCAL) { vty_out(vty, " distance: %u\n", re->distance); vty_out(vty, " metric: %u\n", re->metric); } @@ -2724,146 +2669,6 @@ DEFPY(evpn_mh_redirect_off, evpn_mh_redirect_off_cmd, return zebra_evpn_mh_redirect_off(vty, redirect_off); } -DEFUN (default_vrf_vni_mapping, - default_vrf_vni_mapping_cmd, - "vni " CMD_VNI_RANGE "[prefix-routes-only]", - "VNI corresponding to the DEFAULT VRF\n" - "VNI-ID\n" - "Prefix routes only \n") -{ - char xpath[XPATH_MAXLEN]; - int filter = 0; - - if (argc == 3) - filter = 1; - - snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - - snprintf(xpath, sizeof(xpath), - FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[1]->arg); - - if (filter) { - snprintf(xpath, sizeof(xpath), - FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "true"); - } - - return nb_cli_apply_changes(vty, NULL); -} - -DEFUN (no_default_vrf_vni_mapping, - no_default_vrf_vni_mapping_cmd, - "no vni " CMD_VNI_RANGE "[prefix-routes-only]", - NO_STR - "VNI corresponding to DEFAULT VRF\n" - "VNI-ID\n" - "Prefix routes only \n") -{ - char xpath[XPATH_MAXLEN]; - int filter = 0; - vni_t vni = strtoul(argv[2]->arg, NULL, 10); - struct zebra_vrf *zvrf = NULL; - - zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - - if (argc == 4) - filter = 1; - - if (zvrf->l3vni != vni) { - vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni, - zvrf->vrf->name); - return CMD_WARNING; - } - - snprintf(xpath, sizeof(xpath), - FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, argv[2]->arg); - - if (filter) { - snprintf(xpath, sizeof(xpath), - FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, "true"); - } - - snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFUN (vrf_vni_mapping, - vrf_vni_mapping_cmd, - "vni " CMD_VNI_RANGE "[prefix-routes-only]", - "VNI corresponding to tenant VRF\n" - "VNI-ID\n" - "prefix-routes-only\n") -{ - int filter = 0; - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - assert(vrf); - assert(zvrf); - - if (argc == 3) - filter = 1; - - 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"); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFUN (no_vrf_vni_mapping, - no_vrf_vni_mapping_cmd, - "no vni " CMD_VNI_RANGE "[prefix-routes-only]", - NO_STR - "VNI corresponding to tenant VRF\n" - "VNI-ID\n" - "prefix-routes-only\n") -{ - int filter = 0; - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - vni_t vni = strtoul(argv[2]->arg, NULL, 10); - - assert(vrf); - assert(zvrf); - - if (argc == 4) - filter = 1; - - if (zvrf->l3vni != vni) { - vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni, - zvrf->vrf->name); - return CMD_WARNING; - } - - 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); - - return nb_cli_apply_changes(vty, NULL); -} - /* show vrf */ DEFPY (show_vrf_vni, show_vrf_vni_cmd, @@ -4028,6 +3833,17 @@ static int config_write_protocol(struct vty *vty) return 1; } +static inline bool zebra_vty_v6_rr_semantics_used(void) +{ + if (zebra_nhg_kernel_nexthops_enabled()) + return true; + + if (zrouter.v6_rr_semantics) + return true; + + return false; +} + DEFUN (show_zebra, show_zebra_cmd, "show zebra", @@ -4047,7 +3863,9 @@ DEFUN (show_zebra, ttable_add_row(table, "MPLS|%s", mpls_enabled ? "On" : "Off"); ttable_add_row(table, "EVPN|%s", is_evpn_enabled() ? "On" : "Off"); ttable_add_row(table, "Kernel socket buffer size|%d", rcvbufsize); - + ttable_add_row(table, "v6 Route Replace Semantics|%s", + zebra_vty_v6_rr_semantics_used() ? "Replace" + : "Delete then Add"); #ifdef GNU_LINUX if (!vrf_is_backend_netns()) @@ -4482,31 +4300,6 @@ DEFPY (no_zebra_protodown_bit, #endif /* HAVE_NETLINK */ -DEFUN(ip_table_range, ip_table_range_cmd, - "[no] ip table range (1-4294967295) (1-4294967295)", - NO_STR IP_STR - "table configuration\n" - "Configure table range\n" - "Start Routing Table\n" - "End Routing Table\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (zvrf_id(zvrf) != VRF_DEFAULT && !vrf_is_backend_netns()) { - vty_out(vty, - "VRF subcommand does not make any sense in l3mdev based vrf's\n"); - return CMD_WARNING; - } - - if (strmatch(argv[0]->text, "no")) - return table_manager_range(vty, false, zvrf, NULL, NULL); - - return table_manager_range(vty, true, zvrf, argv[3]->arg, argv[4]->arg); -} - #ifdef HAVE_SCRIPTING DEFUN(zebra_on_rib_process_script, zebra_on_rib_process_script_cmd, @@ -4618,14 +4411,6 @@ void zebra_vty_init(void) install_element(VIEW_NODE, &show_ip_rpf_addr_cmd); install_element(VIEW_NODE, &show_ipv6_rpf_addr_cmd); - install_element(CONFIG_NODE, &ip_nht_default_route_cmd); - install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd); - install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd); - install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd); - install_element(VRF_NODE, &ip_nht_default_route_cmd); - install_element(VRF_NODE, &no_ip_nht_default_route_cmd); - install_element(VRF_NODE, &ipv6_nht_default_route_cmd); - install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd); install_element(CONFIG_NODE, &rnh_hide_backups_cmd); install_element(VIEW_NODE, &show_frr_cmd); @@ -4677,19 +4462,12 @@ void zebra_vty_init(void) install_element(CONFIG_NODE, &evpn_mh_neigh_holdtime_cmd); install_element(CONFIG_NODE, &evpn_mh_startup_delay_cmd); install_element(CONFIG_NODE, &evpn_mh_redirect_off_cmd); - install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd); - install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd); - install_element(VRF_NODE, &vrf_vni_mapping_cmd); - install_element(VRF_NODE, &no_vrf_vni_mapping_cmd); install_element(VIEW_NODE, &show_dataplane_cmd); install_element(VIEW_NODE, &show_dataplane_providers_cmd); install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd); install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd); - install_element(CONFIG_NODE, &ip_table_range_cmd); - install_element(VRF_NODE, &ip_table_range_cmd); - #ifdef HAVE_NETLINK install_element(CONFIG_NODE, &zebra_kernel_netlink_batch_tx_buf_cmd); install_element(CONFIG_NODE, &no_zebra_kernel_netlink_batch_tx_buf_cmd); |