X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=zebra%2Fzebra_vty.c;h=8361dc61f60ad2af87d64a4c880c56102abc1954;hb=093e3f23f63ae90ce2a7407ecdec9a86b99dacd9;hp=bed3b7f77cd3d69821d002bc99069759a5602c87;hpb=7e9c59127876167d91520ddf8c5e1663ba5812f2;p=mirror_frr.git diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index bed3b7f77..8361dc61f 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -35,13 +35,13 @@ #include "srcdest_table.h" #include "vxlan.h" +#include "zebra/zebra_router.h" #include "zebra/zserv.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_mpls.h" #include "zebra/zebra_rnh.h" #include "zebra/redistribute.h" #include "zebra/zebra_routemap.h" -#include "zebra/zebra_static.h" #include "lib/json.h" #include "zebra/zebra_vxlan.h" #ifndef VTYSH_EXTRACT_PL @@ -56,7 +56,7 @@ extern int allow_delete; static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, uint8_t use_json, + safi_t safi, bool use_fib, bool use_json, route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, @@ -68,582 +68,6 @@ static void vty_show_ip_route_summary(struct vty *vty, static void vty_show_ip_route_summary_prefix(struct vty *vty, struct route_table *table); -/* - * special macro to allow us to get the correct zebra_vrf - */ -#define ZEBRA_DECLVAR_CONTEXT(A, B) \ - struct vrf *A = VTY_GET_CONTEXT(vrf); \ - struct zebra_vrf *B = (vrf) ? vrf->info : NULL; - -/* VNI range as per RFC 7432 */ -#define CMD_VNI_RANGE "(1-16777215)" - -struct static_hold_route { - char *vrf_name; - char *nhvrf_name; - afi_t afi; - safi_t safi; - char *dest_str; - char *mask_str; - char *src_str; - char *gate_str; - char *ifname; - char *flag_str; - char *tag_str; - char *distance_str; - char *label_str; - char *table_str; - - /* processed & masked destination, used for config display */ - struct prefix dest; -}; - -static struct list *static_list; - -static int static_list_compare_helper(const char *s1, const char *s2) -{ - /* Are Both NULL */ - if (s1 == s2) - return 0; - - if (!s1 && s2) - return -1; - - if (s1 && !s2) - return 1; - - return strcmp(s1, s2); -} - -static void static_list_delete(struct static_hold_route *shr) -{ - if (shr->vrf_name) - XFREE(MTYPE_STATIC_ROUTE, shr->vrf_name); - if (shr->nhvrf_name) - XFREE(MTYPE_STATIC_ROUTE, shr->nhvrf_name); - if (shr->dest_str) - XFREE(MTYPE_STATIC_ROUTE, shr->dest_str); - if (shr->mask_str) - XFREE(MTYPE_STATIC_ROUTE, shr->mask_str); - if (shr->src_str) - XFREE(MTYPE_STATIC_ROUTE, shr->src_str); - if (shr->gate_str) - XFREE(MTYPE_STATIC_ROUTE, shr->gate_str); - if (shr->ifname) - XFREE(MTYPE_STATIC_ROUTE, shr->ifname); - if (shr->flag_str) - XFREE(MTYPE_STATIC_ROUTE, shr->flag_str); - if (shr->tag_str) - XFREE(MTYPE_STATIC_ROUTE, shr->tag_str); - if (shr->distance_str) - XFREE(MTYPE_STATIC_ROUTE, shr->distance_str); - if (shr->label_str) - XFREE(MTYPE_STATIC_ROUTE, shr->label_str); - - XFREE(MTYPE_STATIC_ROUTE, shr); -} - -static int static_list_compare(void *arg1, void *arg2) -{ - struct static_hold_route *shr1 = arg1; - struct static_hold_route *shr2 = arg2; - int ret; - - ret = strcmp(shr1->vrf_name, shr2->vrf_name); - if (ret) - return ret; - - ret = strcmp(shr1->nhvrf_name, shr2->nhvrf_name); - if (ret) - return ret; - - ret = shr1->afi - shr2->afi; - if (ret) - return ret; - - ret = shr1->safi - shr2->safi; - if (ret) - return ret; - - ret = prefix_cmp(&shr1->dest, &shr2->dest); - if (ret) - return ret; - - ret = static_list_compare_helper(shr1->src_str, shr2->src_str); - if (ret) - return ret; - - ret = static_list_compare_helper(shr1->gate_str, shr2->gate_str); - if (ret) - return ret; - - ret = static_list_compare_helper(shr1->ifname, shr2->ifname); - if (ret) - return ret; - - ret = static_list_compare_helper(shr1->flag_str, shr2->flag_str); - if (ret) - return ret; - - ret = static_list_compare_helper(shr1->tag_str, shr2->tag_str); - if (ret) - return ret; - - ret = static_list_compare_helper(shr1->distance_str, - shr2->distance_str); - if (ret) - return ret; - - ret = static_list_compare_helper(shr1->table_str, - shr2->table_str); - if (ret) - return ret; - - return static_list_compare_helper(shr1->label_str, shr2->label_str); -} - - -/* General function for static route. */ -static int zebra_static_route_holdem( - struct zebra_vrf *zvrf, struct zebra_vrf *nh_zvrf, afi_t afi, - safi_t safi, const char *negate, struct prefix *dest, - const char *dest_str, const char *mask_str, const char *src_str, - const char *gate_str, const char *ifname, const char *flag_str, - const char *tag_str, const char *distance_str, const char *label_str, - const char *table_str) -{ - struct static_hold_route *shr, *lookup; - struct listnode *node; - - zlog_warn("Static Route to %s not installed currently because dependent config not fully available", - dest_str); - - shr = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(*shr)); - shr->vrf_name = XSTRDUP(MTYPE_STATIC_ROUTE, zvrf->vrf->name); - shr->nhvrf_name = XSTRDUP(MTYPE_STATIC_ROUTE, nh_zvrf->vrf->name); - shr->afi = afi; - shr->safi = safi; - if (dest) - prefix_copy(&shr->dest, dest); - if (dest_str) - shr->dest_str = XSTRDUP(MTYPE_STATIC_ROUTE, dest_str); - if (mask_str) - shr->mask_str = XSTRDUP(MTYPE_STATIC_ROUTE, mask_str); - if (src_str) - shr->src_str = XSTRDUP(MTYPE_STATIC_ROUTE, src_str); - if (gate_str) - shr->gate_str = XSTRDUP(MTYPE_STATIC_ROUTE, gate_str); - if (ifname) - shr->ifname = XSTRDUP(MTYPE_STATIC_ROUTE, ifname); - if (flag_str) - shr->flag_str = XSTRDUP(MTYPE_STATIC_ROUTE, flag_str); - if (tag_str) - shr->tag_str = XSTRDUP(MTYPE_STATIC_ROUTE, tag_str); - if (distance_str) - shr->distance_str = XSTRDUP(MTYPE_STATIC_ROUTE, distance_str); - if (label_str) - shr->label_str = XSTRDUP(MTYPE_STATIC_ROUTE, label_str); - if (table_str) - shr->table_str = XSTRDUP(MTYPE_STATIC_ROUTE, table_str); - - for (ALL_LIST_ELEMENTS_RO(static_list, node, lookup)) { - if (static_list_compare(shr, lookup) == 0) - break; - } - - if (lookup) { - if (negate) { - listnode_delete(static_list, lookup); - static_list_delete(shr); - static_list_delete(lookup); - - return CMD_SUCCESS; - } - - /* - * If a person enters the same line again - * we need to silently accept it - */ - goto shr_cleanup; - } - - if (!negate) { - listnode_add_sort(static_list, shr); - return CMD_SUCCESS; - } - -shr_cleanup: - XFREE(MTYPE_STATIC_ROUTE, shr->nhvrf_name); - XFREE(MTYPE_STATIC_ROUTE, shr->vrf_name); - XFREE(MTYPE_STATIC_ROUTE, shr); - - return CMD_SUCCESS; -} - -static int zebra_static_route_leak( - struct vty *vty, struct zebra_vrf *zvrf, struct zebra_vrf *nh_zvrf, - afi_t afi, safi_t safi, const char *negate, const char *dest_str, - const char *mask_str, const char *src_str, const char *gate_str, - const char *ifname, const char *flag_str, const char *tag_str, - const char *distance_str, const char *label_str, const char *table_str) -{ - int ret; - uint8_t distance; - struct prefix p, src; - struct prefix_ipv6 *src_p = NULL; - union g_addr gate; - union g_addr *gatep = NULL; - struct in_addr mask; - enum static_blackhole_type bh_type = 0; - route_tag_t tag = 0; - uint8_t type; - struct static_nh_label snh_label; - uint32_t table_id = 0; - - ret = str2prefix(dest_str, &p); - if (ret <= 0) { - if (vty) - vty_out(vty, "%% Malformed address\n"); - else - zlog_warn("%s: Malformed address: %s", - __PRETTY_FUNCTION__, dest_str); - return CMD_WARNING_CONFIG_FAILED; - } - - switch (afi) { - case AFI_IP: - /* Cisco like mask notation. */ - if (mask_str) { - ret = inet_aton(mask_str, &mask); - if (ret == 0) { - if (vty) - vty_out(vty, "%% Malformed address\n"); - else - zlog_warn("%s: Malformed address: %s", - __PRETTY_FUNCTION__, - mask_str); - return CMD_WARNING_CONFIG_FAILED; - } - p.prefixlen = ip_masklen(mask); - } - break; - case AFI_IP6: - /* srcdest routing */ - if (src_str) { - ret = str2prefix(src_str, &src); - if (ret <= 0 || src.family != AF_INET6) { - if (vty) - vty_out(vty, - "%% Malformed source address\n"); - else - zlog_warn( - "%s: Malformed Source address: %s", - __PRETTY_FUNCTION__, src_str); - return CMD_WARNING_CONFIG_FAILED; - } - src_p = (struct prefix_ipv6 *)&src; - } - break; - default: - break; - } - - /* Apply mask for given prefix. */ - apply_mask(&p); - - if (zvrf->vrf->vrf_id == VRF_UNKNOWN - || nh_zvrf->vrf->vrf_id == VRF_UNKNOWN) { - vrf_set_user_cfged(zvrf->vrf); - return zebra_static_route_holdem( - zvrf, nh_zvrf, afi, safi, negate, &p, dest_str, - mask_str, src_str, gate_str, ifname, flag_str, tag_str, - distance_str, label_str, table_str); - } - if (table_str) { - /* table configured. check consistent with vrf config - */ - if (zvrf->table_id != RT_TABLE_MAIN && - zvrf->table_id != zebrad.rtm_table_default) { - if (vty) - vty_out(vty, - "%% Table %s overlaps vrf table %u\n", - table_str, zvrf->table_id); - else - zlog_warn( - "%s: Table %s overlaps vrf table %u", - __PRETTY_FUNCTION__, - table_str, zvrf->table_id); - return CMD_WARNING_CONFIG_FAILED; - } - } - - /* Administrative distance. */ - if (distance_str) - distance = atoi(distance_str); - else - distance = ZEBRA_STATIC_DISTANCE_DEFAULT; - - /* tag */ - if (tag_str) - tag = strtoul(tag_str, NULL, 10); - - /* Labels */ - memset(&snh_label, 0, sizeof(struct static_nh_label)); - if (label_str) { - if (!mpls_enabled) { - if (vty) - vty_out(vty, - "%% MPLS not turned on in kernel, ignoring command\n"); - else - zlog_warn( - "%s: MPLS not turned on in kernel ignoring static route to %s", - __PRETTY_FUNCTION__, dest_str); - return CMD_WARNING_CONFIG_FAILED; - } - int rc = mpls_str2label(label_str, &snh_label.num_labels, - snh_label.label); - if (rc < 0) { - switch (rc) { - case -1: - if (vty) - vty_out(vty, "%% Malformed label(s)\n"); - else - zlog_warn( - "%s: Malformed labels specified for route %s", - __PRETTY_FUNCTION__, dest_str); - break; - case -2: - if (vty) - vty_out(vty, - "%% Cannot use reserved label(s) (%d-%d)\n", - MPLS_LABEL_RESERVED_MIN, - MPLS_LABEL_RESERVED_MAX); - else - zlog_warn( - "%s: Cannot use reserved labels (%d-%d) for %s", - __PRETTY_FUNCTION__, - MPLS_LABEL_RESERVED_MIN, - MPLS_LABEL_RESERVED_MAX, - dest_str); - break; - case -3: - if (vty) - vty_out(vty, - "%% Too many labels. Enter %d or fewer\n", - MPLS_MAX_LABELS); - else - zlog_warn( - "%s: Too many labels, Enter %d or fewer for %s", - __PRETTY_FUNCTION__, - MPLS_MAX_LABELS, dest_str); - break; - } - return CMD_WARNING_CONFIG_FAILED; - } - } - /* TableID */ - if (table_str) - table_id = atol(table_str); - - /* Null0 static route. */ - if (ifname != NULL) { - if (strncasecmp(ifname, "Null0", strlen(ifname)) == 0 - || strncasecmp(ifname, "reject", strlen(ifname)) == 0 - || strncasecmp(ifname, "blackhole", strlen(ifname)) == 0) { - if (vty) - vty_out(vty, - "%% Nexthop interface cannot be Null0, reject or blackhole\n"); - else - zlog_warn( - "%s: Nexthop interface cannot be Null0, reject or blackhole for %s", - __PRETTY_FUNCTION__, dest_str); - return CMD_WARNING_CONFIG_FAILED; - } - } - - /* Route flags */ - if (flag_str) { - switch (flag_str[0]) { - case 'r': - bh_type = STATIC_BLACKHOLE_REJECT; - break; - case 'b': - bh_type = STATIC_BLACKHOLE_DROP; - break; - case 'N': - bh_type = STATIC_BLACKHOLE_NULL; - break; - default: - if (vty) - vty_out(vty, "%% Malformed flag %s \n", - flag_str); - else - zlog_warn("%s: Malformed flag %s for %s", - __PRETTY_FUNCTION__, flag_str, - dest_str); - return CMD_WARNING_CONFIG_FAILED; - } - } - - if (gate_str) { - if (inet_pton(afi2family(afi), gate_str, &gate) != 1) { - if (vty) - vty_out(vty, - "%% Malformed nexthop address %s\n", - gate_str); - else - zlog_warn( - "%s: Malformed nexthop address %s for %s", - __PRETTY_FUNCTION__, gate_str, - dest_str); - return CMD_WARNING_CONFIG_FAILED; - } - gatep = &gate; - } - - if (gate_str == NULL && ifname == NULL) - type = STATIC_BLACKHOLE; - else if (gate_str && ifname) { - if (afi == AFI_IP) - type = STATIC_IPV4_GATEWAY_IFNAME; - else - type = STATIC_IPV6_GATEWAY_IFNAME; - } else if (ifname) - type = STATIC_IFNAME; - else { - if (afi == AFI_IP) - type = STATIC_IPV4_GATEWAY; - else - type = STATIC_IPV6_GATEWAY; - } - - if (!negate) { - static_add_route(afi, safi, type, &p, src_p, gatep, ifname, - bh_type, tag, distance, zvrf, nh_zvrf, - &snh_label, table_id); - /* Mark as having FRR configuration */ - vrf_set_user_cfged(zvrf->vrf); - } else { - static_delete_route(afi, safi, type, &p, src_p, gatep, ifname, - tag, distance, zvrf, &snh_label, table_id); - /* If no other FRR config for this VRF, mark accordingly. */ - if (!zebra_vrf_has_config(zvrf)) - vrf_reset_user_cfged(zvrf->vrf); - } - - return CMD_SUCCESS; -} - -static struct zebra_vrf *zebra_vty_get_unknown_vrf(struct vty *vty, - const char *vrf_name) -{ - struct zebra_vrf *zvrf; - struct vrf *vrf; - - zvrf = zebra_vrf_lookup_by_name(vrf_name); - - if (zvrf) - return zvrf; - - vrf = vrf_get(VRF_UNKNOWN, vrf_name); - if (!vrf) { - vty_out(vty, "%% Could not create vrf %s\n", vrf_name); - return NULL; - } - zvrf = vrf->info; - if (!zvrf) { - vty_out(vty, "%% Could not create vrf-info %s\n", - vrf_name); - return NULL; - } - /* Mark as having FRR configuration */ - vrf_set_user_cfged(vrf); - - return zvrf; -} - -static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi, - const char *negate, const char *dest_str, - const char *mask_str, const char *src_str, - const char *gate_str, const char *ifname, - const char *flag_str, const char *tag_str, - const char *distance_str, const char *vrf_name, - const char *label_str, const char *table_str) -{ - struct zebra_vrf *zvrf; - - /* VRF id */ - zvrf = zebra_vrf_lookup_by_name(vrf_name); - - /* When trying to delete, the VRF must exist. */ - if (negate && !zvrf) { - vty_out(vty, "%% vrf %s is not defined\n", vrf_name); - return CMD_WARNING_CONFIG_FAILED; - } - - /* When trying to create, create the VRF if it doesn't exist. - * Note: The VRF isn't active until we hear about it from the kernel. - */ - if (!zvrf) { - zvrf = zebra_vty_get_unknown_vrf(vty, vrf_name); - if (!zvrf) - return CMD_WARNING_CONFIG_FAILED; - } - return zebra_static_route_leak( - vty, zvrf, zvrf, afi, safi, negate, dest_str, mask_str, src_str, - gate_str, ifname, flag_str, tag_str, distance_str, label_str, - table_str); -} - -void static_config_install_delayed_routes(struct zebra_vrf *zvrf) -{ - struct listnode *node, *nnode; - struct static_hold_route *shr; - struct zebra_vrf *ozvrf, *nh_zvrf; - int installed; - - for (ALL_LIST_ELEMENTS(static_list, node, nnode, shr)) { - ozvrf = zebra_vrf_lookup_by_name(shr->vrf_name); - nh_zvrf = zebra_vrf_lookup_by_name(shr->nhvrf_name); - - if (ozvrf != zvrf && nh_zvrf != zvrf) - continue; - - if (ozvrf->vrf->vrf_id == VRF_UNKNOWN - || nh_zvrf->vrf->vrf_id == VRF_UNKNOWN) - continue; - - installed = zebra_static_route_leak( - NULL, ozvrf, nh_zvrf, shr->afi, shr->safi, NULL, - shr->dest_str, shr->mask_str, shr->src_str, - shr->gate_str, shr->ifname, shr->flag_str, shr->tag_str, - shr->distance_str, shr->label_str, shr->table_str); - - if (installed != CMD_SUCCESS) - zlog_debug( - "%s: Attempt to install %s as a route and it was rejected", - __PRETTY_FUNCTION__, shr->dest_str); - listnode_delete(static_list, shr); - static_list_delete(shr); - } -} -/* Static unicast routes for multicast RPF lookup. */ -DEFPY (ip_mroute_dist, - ip_mroute_dist_cmd, - "[no] ip mroute A.B.C.D/M$prefix [(1-255)$distance]", - NO_STR - IP_STR - "Configure static unicast route into MRIB for multicast RPF lookup\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Nexthop address\n" - "Nexthop interface name\n" - "Distance\n") -{ - return zebra_static_route(vty, AFI_IP, SAFI_MULTICAST, no, prefix_str, - NULL, NULL, gate_str, ifname, NULL, NULL, - distance_str, NULL, NULL, NULL); -} - DEFUN (ip_multicast_mode, ip_multicast_mode_cmd, "ip multicast rpf-lookup-mode ", @@ -702,7 +126,7 @@ DEFUN (show_ip_rpf, "Display RPF information for multicast source\n" JSON_STR) { - int uj = use_json(argc, argv); + bool uj = use_json(argc, argv); return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST, false, uj, 0, NULL, false, 0, 0); } @@ -737,343 +161,6 @@ DEFUN (show_ip_rpf_addr, return CMD_SUCCESS; } -/* Static route configuration. */ -DEFPY(ip_route_blackhole, - ip_route_blackhole_cmd, - "[no] ip route\ - \ - $flag \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |vrf NAME \ - |label WORD \ - |table (1-4294967295) \ - }]", - NO_STR IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n") -{ - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix, - mask_str, NULL, NULL, NULL, flag, tag_str, - distance_str, vrf, label, table_str); -} - -DEFPY(ip_route_blackhole_vrf, - ip_route_blackhole_vrf_cmd, - "[no] ip route\ - \ - $flag \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |label WORD \ - |table (1-4294967295) \ - }]", - NO_STR IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n") -{ - VTY_DECLVAR_CONTEXT(vrf, vrf); - struct zebra_vrf *zvrf = vrf->info; - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - /* - * Coverity is complaining that prefix could - * be dereferenced, but we know that prefix will - * valid. Add an assert to make it happy - */ - assert(prefix); - return zebra_static_route_leak(vty, zvrf, zvrf, AFI_IP, SAFI_UNICAST, - no, prefix, mask_str, NULL, NULL, NULL, - flag, tag_str, distance_str, label, table_str); -} - -DEFPY(ip_route_address_interface, - ip_route_address_interface_cmd, - "[no] ip route\ - \ - A.B.C.D$gate \ - INTERFACE$ifname \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |vrf NAME \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - }]", - NO_STR IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \ - null route.\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR) -{ - struct zebra_vrf *zvrf; - struct zebra_vrf *nh_zvrf; - - const char *flag = NULL; - if (ifname && !strncasecmp(ifname, "Null0", 5)) { - flag = "Null0"; - ifname = NULL; - } - - zvrf = zebra_vty_get_unknown_vrf(vty, vrf); - if (!zvrf) { - vty_out(vty, "%% vrf %s is not defined\n", vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (nexthop_vrf) - nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf); - else - nh_zvrf = zvrf; - - if (!nh_zvrf) { - vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - return zebra_static_route_leak( - vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, - NULL, gate_str, ifname, flag, tag_str, distance_str, label, - table_str); -} - -DEFPY(ip_route_address_interface_vrf, - ip_route_address_interface_vrf_cmd, - "[no] ip route\ - \ - A.B.C.D$gate \ - INTERFACE$ifname \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - }]", - NO_STR IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \ - null route.\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR) -{ - VTY_DECLVAR_CONTEXT(vrf, vrf); - const char *flag = NULL; - struct zebra_vrf *zvrf = vrf->info; - struct zebra_vrf *nh_zvrf; - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (ifname && !strncasecmp(ifname, "Null0", 5)) { - flag = "Null0"; - ifname = NULL; - } - - if (nexthop_vrf) - nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf); - else - nh_zvrf = zvrf; - - if (!nh_zvrf) { - vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - return zebra_static_route_leak( - vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, - NULL, gate_str, ifname, flag, tag_str, distance_str, label, - table_str); -} - -DEFPY(ip_route, - ip_route_cmd, - "[no] ip route\ - \ - \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |vrf NAME \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - }]", - NO_STR IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR) -{ - struct zebra_vrf *zvrf; - struct zebra_vrf *nh_zvrf; - const char *flag = NULL; - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (ifname && !strncasecmp(ifname, "Null0", 5)) { - flag = "Null0"; - ifname = NULL; - } - - zvrf = zebra_vty_get_unknown_vrf(vty, vrf); - if (!zvrf) { - vty_out(vty, "%% vrf %s is not defined\n", vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - if (nexthop_vrf) - nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf); - else - nh_zvrf = zvrf; - - if (!nh_zvrf) { - vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - - return zebra_static_route_leak( - vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, - NULL, gate_str, ifname, flag, tag_str, distance_str, label, - table_str); -} - -DEFPY(ip_route_vrf, - ip_route_vrf_cmd, - "[no] ip route\ - \ - \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - }]", - NO_STR IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR) -{ - VTY_DECLVAR_CONTEXT(vrf, vrf); - struct zebra_vrf *zvrf = vrf->info; - struct zebra_vrf *nh_zvrf; - const char *flag = NULL; - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (ifname && !strncasecmp(ifname, "Null0", 5)) { - flag = "Null0"; - ifname = NULL; - } - - if (nexthop_vrf) - nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf); - else - nh_zvrf = zvrf; - - if (!nh_zvrf) { - vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - return zebra_static_route_leak( - vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, - NULL, gate_str, ifname, flag, tag_str, distance_str, label, - NULL); -} - /* New RIB. Detailed information for IPv4 route. */ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, int mcast) @@ -1206,7 +293,7 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, if (vrf) vty_out(vty, "(vrf %s)", vrf->name); else - vty_out(vty, "(vrf UKNOWN)"); + vty_out(vty, "(vrf UNKNOWN)"); } if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) @@ -1308,6 +395,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object_int_add(json_route, "metric", re->metric); } + if (re->tag) + json_object_int_add(json_route, "tag", re->tag); + json_object_int_add(json_route, "internalStatus", re->status); json_object_int_add(json_route, "internalFlags", @@ -1578,7 +668,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, if (vrf) vty_out(vty, "(vrf %s)", vrf->name); else - vty_out(vty, "(vrf UKNOWN)"); + vty_out(vty, "(vrf UNKNOWN)"); } if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) @@ -1633,13 +723,35 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, } } +static void vty_show_ip_route_detail_json(struct vty *vty, + struct route_node *rn) +{ + json_object *json = NULL; + json_object *json_prefix = NULL; + struct route_entry *re; + char buf[BUFSIZ]; + + json = json_object_new_object(); + + RNODE_FOREACH_RE (rn, re) { + json_prefix = json_object_new_array(); + vty_show_ip_route(vty, rn, re, json_prefix); + prefix2str(&rn->p, buf, sizeof buf); + json_object_object_add(json, buf, json_prefix); + json_prefix = NULL; + } + + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(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, - uint8_t use_json) + unsigned short ospf_instance_id, bool use_json) { struct route_node *rn; struct route_entry *re; @@ -1714,21 +826,21 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, } if (json_prefix) { - prefix2str(&rn->p, buf, sizeof buf); + prefix2str(&rn->p, buf, sizeof(buf)); json_object_object_add(json, buf, json_prefix); json_prefix = NULL; } } if (use_json) { - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", json_object_to_json_string_ext(json, + JSON_C_TO_STRING_PRETTY)); json_object_free(json); } } static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, uint8_t use_json, + safi_t safi, bool use_fib, bool use_json, route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, @@ -1782,7 +894,7 @@ DEFPY (show_route_table, struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); struct route_table *t; - t = zebra_ns_find_table(zvrf->zns, table, afi); + t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST); if (t) do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false, 0, 0, !!json); @@ -1808,10 +920,10 @@ DEFPY (show_route_table_vrf, vrf_id_t vrf_id = VRF_DEFAULT; if (vrf_name) - VRF_GET_ID(vrf_id, vrf_name); + VRF_GET_ID(vrf_id, vrf_name, !!json); zvrf = zebra_vrf_lookup_by_id(vrf_id); - t = zebra_ns_find_table(zvrf->zns, table, afi); + t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST); if (t) do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false, 0, 0, !!json); @@ -1831,7 +943,7 @@ DEFUN (show_ip_nht, vrf_id_t vrf_id = VRF_DEFAULT; if (argc == 5) - VRF_GET_ID(vrf_id, argv[idx_vrf]->arg); + VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false); zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); return CMD_SUCCESS; @@ -1871,7 +983,7 @@ DEFUN (show_ipv6_nht, vrf_id_t vrf_id = VRF_DEFAULT; if (argc == 5) - VRF_GET_ID(vrf_id, argv[idx_vrf]->arg); + VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false); zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); return CMD_SUCCESS; @@ -1906,11 +1018,17 @@ DEFUN (ip_nht_default_route, "Filter Next Hop tracking route resolution\n" "Resolve via default route\n") { + ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); + + if (!zvrf) + return CMD_WARNING; + if (zebra_rnh_ip_default_route) return CMD_SUCCESS; zebra_rnh_ip_default_route = 1; - zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); + + zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); return CMD_SUCCESS; } @@ -1922,11 +1040,16 @@ DEFUN (no_ip_nht_default_route, "Filter Next Hop tracking route resolution\n" "Resolve via default route\n") { + ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); + + if (!zvrf) + return CMD_WARNING; + if (!zebra_rnh_ip_default_route) return CMD_SUCCESS; zebra_rnh_ip_default_route = 0; - zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); return CMD_SUCCESS; } @@ -1937,11 +1060,16 @@ DEFUN (ipv6_nht_default_route, "Filter Next Hop tracking route resolution\n" "Resolve via default route\n") { + ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); + + if (!zvrf) + return CMD_WARNING; + if (zebra_rnh_ipv6_default_route) return CMD_SUCCESS; zebra_rnh_ipv6_default_route = 1; - zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); return CMD_SUCCESS; } @@ -1953,11 +1081,17 @@ DEFUN (no_ipv6_nht_default_route, "Filter Next Hop tracking route resolution\n" "Resolve via default route\n") { + + ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); + + if (!zvrf) + return CMD_WARNING; + if (!zebra_rnh_ipv6_default_route) return CMD_SUCCESS; zebra_rnh_ipv6_default_route = 0; - zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); return CMD_SUCCESS; } @@ -2037,7 +1171,7 @@ DEFPY (show_route, vrf_id_t vrf_id = VRF_DEFAULT; if (vrf_name) - VRF_GET_ID(vrf_id, vrf_name); + VRF_GET_ID(vrf_id, vrf_name, !!json); vrf = vrf_lookup_by_id(vrf_id); do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib, !!json, tag, prefix_str ? prefix : NULL, @@ -2061,7 +1195,8 @@ DEFPY (show_route_detail, X:X::X:X$address\ |X:X::X:X/M$prefix\ >\ - >", + >\ + [json$json]", SHOW_STR IP_STR "IP routing table\n" @@ -2072,7 +1207,8 @@ DEFPY (show_route_detail, "IP routing table\n" VRF_FULL_CMD_HELP_STR "IPv6 Address\n" - "IPv6 prefix\n") + "IPv6 prefix\n" + JSON_STR) { afi_t afi = ipv4 ? AFI_IP : AFI_IP6; struct route_table *table; @@ -2103,7 +1239,10 @@ DEFPY (show_route_detail, continue; } - vty_show_ip_route_detail(vty, rn, 0); + if (json) + vty_show_ip_route_detail_json(vty, rn); + else + vty_show_ip_route_detail(vty, rn, 0); route_unlock_node(rn); } @@ -2111,7 +1250,7 @@ DEFPY (show_route_detail, vrf_id_t vrf_id = VRF_DEFAULT; if (vrf_name) - VRF_GET_ID(vrf_id, vrf_name); + VRF_GET_ID(vrf_id, vrf_name, false); table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id); if (!table) @@ -2128,7 +1267,10 @@ DEFPY (show_route_detail, return CMD_WARNING; } - vty_show_ip_route_detail(vty, rn, 0); + if (json) + vty_show_ip_route_detail_json(vty, rn); + else + vty_show_ip_route_detail(vty, rn, 0); route_unlock_node(rn); } @@ -2178,7 +1320,7 @@ DEFPY (show_route_summary, vrf_id_t vrf_id = VRF_DEFAULT; if (vrf_name) - VRF_GET_ID(vrf_id, vrf_name); + VRF_GET_ID(vrf_id, vrf_name, false); table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id); if (!table) @@ -2229,7 +1371,7 @@ static void vty_show_ip_route_summary(struct vty *vty, } vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes", - "FIB", zvrf_name(((rib_table_info_t *)table->info)->zvrf)); + "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf)); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP @@ -2305,7 +1447,7 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty, vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Prefix Routes", "FIB", - zvrf_name(((rib_table_info_t *)table->info)->zvrf)); + zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf)); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { if (rib_cnt[i] > 0) { @@ -2331,449 +1473,6 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty, vty_out(vty, "\n"); } -/* Write static route configuration. */ -int static_config(struct vty *vty, struct zebra_vrf *zvrf, afi_t afi, - safi_t safi, const char *cmd) -{ - struct static_hold_route *shr; - struct listnode *node; - char spacing[100]; - struct route_node *rn; - struct static_route *si; - struct route_table *stable; - char buf[SRCDEST2STR_BUFFER]; - int write = 0; - - if ((stable = zvrf->stable[afi][safi]) == NULL) - return write; - - sprintf(spacing, "%s%s", (zvrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", - cmd); - - /* - * Static routes for vrfs not fully inited - */ - for (ALL_LIST_ELEMENTS_RO(static_list, node, shr)) { - if (shr->afi != afi || shr->safi != safi) - continue; - - if (strcmp(zvrf->vrf->name, shr->vrf_name) != 0) - continue; - - char dest_str[PREFIX_STRLEN]; - - prefix2str(&shr->dest, dest_str, sizeof(dest_str)); - - vty_out(vty, "%s ", spacing); - if (shr->dest_str) - vty_out(vty, "%s ", dest_str); - if (shr->src_str) - vty_out(vty, "from %s ", shr->src_str); - if (shr->gate_str) - vty_out(vty, "%s ", shr->gate_str); - if (shr->ifname) - vty_out(vty, "%s ", shr->ifname); - if (shr->flag_str) - vty_out(vty, "%s ", shr->flag_str); - if (shr->tag_str) - vty_out(vty, "tag %s ", shr->tag_str); - if (shr->distance_str) - vty_out(vty, "%s ", shr->distance_str); - if (shr->label_str) - vty_out(vty, "label %s ", shr->label_str); - if (shr->table_str) - vty_out(vty, "table %s ", shr->table_str); - if (strcmp(shr->vrf_name, shr->nhvrf_name) != 0) - vty_out(vty, "nexthop-vrf %s", shr->nhvrf_name); - vty_out(vty, "\n"); - } - - for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) - for (si = rn->info; si; si = si->next) { - vty_out(vty, "%s %s", spacing, - srcdest_rnode2str(rn, buf, sizeof buf)); - - switch (si->type) { - case STATIC_IPV4_GATEWAY: - vty_out(vty, " %s", inet_ntoa(si->addr.ipv4)); - break; - case STATIC_IPV6_GATEWAY: - vty_out(vty, " %s", - inet_ntop(AF_INET6, &si->addr.ipv6, buf, - sizeof buf)); - break; - case STATIC_IFNAME: - vty_out(vty, " %s", si->ifname); - break; - case STATIC_BLACKHOLE: - switch (si->bh_type) { - case STATIC_BLACKHOLE_DROP: - vty_out(vty, " blackhole"); - break; - case STATIC_BLACKHOLE_NULL: - vty_out(vty, " Null0"); - break; - case STATIC_BLACKHOLE_REJECT: - vty_out(vty, " reject"); - break; - } - break; - case STATIC_IPV4_GATEWAY_IFNAME: - vty_out(vty, " %s %s", - inet_ntop(AF_INET, &si->addr.ipv4, buf, - sizeof buf), - si->ifname); - break; - case STATIC_IPV6_GATEWAY_IFNAME: - vty_out(vty, " %s %s", - inet_ntop(AF_INET6, &si->addr.ipv6, buf, - sizeof buf), - si->ifname); - break; - } - - if (si->tag) - vty_out(vty, " tag %" ROUTE_TAG_PRI, si->tag); - - if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT) - vty_out(vty, " %d", si->distance); - - /* Label information */ - if (si->snh_label.num_labels) - vty_out(vty, " label %s", - mpls_label2str(si->snh_label.num_labels, - si->snh_label.label, buf, - sizeof buf, 0)); - - if (si->nh_vrf_id != si->vrf_id) { - vty_out(vty, " nexthop-vrf %s", si->nh_vrfname); - } - - /* table ID from VRF overrides configured - */ - if (si->table_id && zvrf->table_id == RT_TABLE_MAIN) - vty_out(vty, " table %u", si->table_id); - - vty_out(vty, "\n"); - - write = 1; - } - return write; -} - -DEFPY(ipv6_route_blackhole, - ipv6_route_blackhole_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ - $flag \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |vrf NAME \ - |label WORD \ - |table (1-4294967295) \ - }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "Null interface\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n") -{ - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str, - NULL, from_str, NULL, NULL, flag, tag_str, - distance_str, vrf, label, table_str); -} - -DEFPY(ipv6_route_blackhole_vrf, - ipv6_route_blackhole_vrf_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ - $flag \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |label WORD \ - |table (1-4294967295) \ - }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "Null interface\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n") -{ - VTY_DECLVAR_CONTEXT(vrf, vrf); - struct zebra_vrf *zvrf = vrf->info; - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - /* - * Coverity is complaining that prefix could - * be dereferenced, but we know that prefix will - * valid. Add an assert to make it happy - */ - assert(prefix); - return zebra_static_route_leak( - vty, zvrf, zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, - from_str, NULL, NULL, flag, tag_str, distance_str, label, - table_str); -} - -DEFPY(ipv6_route_address_interface, - ipv6_route_address_interface_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ - X:X::X:X$gate \ - INTERFACE$ifname \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |vrf NAME \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR) -{ - struct zebra_vrf *zvrf; - struct zebra_vrf *nh_zvrf; - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - zvrf = zebra_vty_get_unknown_vrf(vty, vrf); - if (!zvrf) { - vty_out(vty, "%% vrf %s is not defined\n", vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - if (nexthop_vrf) - nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf); - else - nh_zvrf = zvrf; - - if (!nh_zvrf) { - vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - return zebra_static_route_leak( - vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, - from_str, gate_str, ifname, NULL, tag_str, distance_str, label, - table_str); -} - -DEFPY(ipv6_route_address_interface_vrf, - ipv6_route_address_interface_vrf_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ - X:X::X:X$gate \ - INTERFACE$ifname \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR) -{ - VTY_DECLVAR_CONTEXT(vrf, vrf); - struct zebra_vrf *zvrf = vrf->info; - struct zebra_vrf *nh_zvrf; - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (nexthop_vrf) - nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf); - else - nh_zvrf = zvrf; - - if (!nh_zvrf) { - vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - return zebra_static_route_leak( - vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, - from_str, gate_str, ifname, NULL, tag_str, distance_str, label, - table_str); -} - -DEFPY(ipv6_route, - ipv6_route_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ - \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |vrf NAME \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR) -{ - struct zebra_vrf *zvrf; - struct zebra_vrf *nh_zvrf; - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - zvrf = zebra_vty_get_unknown_vrf(vty, vrf); - if (!zvrf) { - vty_out(vty, "%% vrf %s is not defined\n", vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - if (nexthop_vrf) - nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf); - else - nh_zvrf = zvrf; - - if (!nh_zvrf) { - vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - return zebra_static_route_leak( - vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, - from_str, gate_str, ifname, NULL, tag_str, distance_str, label, - table_str); -} - -DEFPY(ipv6_route_vrf, - ipv6_route_vrf_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ - \ - [{ \ - tag (1-4294967295) \ - |(1-255)$distance \ - |label WORD \ - |table (1-4294967295) \ - |nexthop-vrf NAME \ - }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR) -{ - VTY_DECLVAR_CONTEXT(vrf, vrf); - struct zebra_vrf *zvrf = vrf->info; - struct zebra_vrf *nh_zvrf; - - if (table_str && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (nexthop_vrf) - nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf); - else - nh_zvrf = zvrf; - - if (!nh_zvrf) { - vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - - return zebra_static_route_leak( - vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, - from_str, gate_str, ifname, NULL, tag_str, distance_str, label, - table_str); -} - /* * Show IPv6 mroute command.Used to dump * the Multicast routing table. @@ -2793,7 +1492,7 @@ DEFUN (show_ipv6_mroute, vrf_id_t vrf_id = VRF_DEFAULT; if (argc == 5) - VRF_GET_ID(vrf_id, argv[4]->arg); + VRF_GET_ID(vrf_id, argv[4]->arg, false); table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id); if (!table) @@ -3036,7 +1735,7 @@ DEFUN (show_vrf_vni, struct zebra_vrf *zvrf; json_object *json = NULL; json_object *json_vrfs = NULL; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (uj) { json = json_object_new_object(); @@ -3072,7 +1771,7 @@ DEFUN (show_evpn_global, "EVPN\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zebra_vxlan_print_evpn(vty, uj); return CMD_SUCCESS; @@ -3087,7 +1786,7 @@ DEFUN (show_evpn_vni, JSON_STR) { struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); zebra_vxlan_print_vnis(vty, zvrf, uj); @@ -3105,7 +1804,7 @@ DEFUN (show_evpn_vni_vni, { struct zebra_vrf *zvrf; vni_t vni; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[3]->arg, NULL, 10); zvrf = vrf_info_lookup(VRF_DEFAULT); @@ -3127,7 +1826,7 @@ DEFUN (show_evpn_rmac_vni_mac, { vni_t l3vni = 0; struct ethaddr mac; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); l3vni = strtoul(argv[4]->arg, NULL, 10); if (!prefix_str2mac(argv[6]->arg, &mac)) { @@ -3149,7 +1848,7 @@ DEFUN (show_evpn_rmac_vni, JSON_STR) { vni_t l3vni = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); l3vni = strtoul(argv[4]->arg, NULL, 10); zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj); @@ -3167,7 +1866,7 @@ DEFUN (show_evpn_rmac_vni_all, "All VNIs\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zebra_vxlan_print_rmacs_all_l3vni(vty, uj); @@ -3188,7 +1887,7 @@ DEFUN (show_evpn_nh_vni_ip, { vni_t l3vni; struct ipaddr ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); l3vni = strtoul(argv[4]->arg, NULL, 10); if (str2ipaddr(argv[6]->arg, &ip) != 0) { @@ -3212,7 +1911,7 @@ DEFUN (show_evpn_nh_vni, JSON_STR) { vni_t l3vni; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); l3vni = strtoul(argv[4]->arg, NULL, 10); zebra_vxlan_print_nh_l3vni(vty, l3vni, uj); @@ -3230,7 +1929,7 @@ DEFUN (show_evpn_nh_vni_all, "All VNIs\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zebra_vxlan_print_nh_all_l3vni(vty, uj); @@ -3249,7 +1948,7 @@ DEFUN (show_evpn_mac_vni, { struct zebra_vrf *zvrf; vni_t vni; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); zvrf = vrf_info_lookup(VRF_DEFAULT); @@ -3268,7 +1967,7 @@ DEFUN (show_evpn_mac_vni_all, JSON_STR) { struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); zebra_vxlan_print_macs_all_vni(vty, zvrf, uj); @@ -3289,7 +1988,7 @@ DEFUN (show_evpn_mac_vni_all_vtep, { struct zebra_vrf *zvrf; struct in_addr vtep_ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!inet_aton(argv[6]->arg, &vtep_ip)) { if (!uj) @@ -3343,7 +2042,7 @@ DEFUN (show_evpn_mac_vni_vtep, struct zebra_vrf *zvrf; vni_t vni; struct in_addr vtep_ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); if (!inet_aton(argv[6]->arg, &vtep_ip)) { @@ -3369,7 +2068,7 @@ DEFUN (show_evpn_neigh_vni, { struct zebra_vrf *zvrf; vni_t vni; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); zvrf = vrf_info_lookup(VRF_DEFAULT); @@ -3388,7 +2087,7 @@ DEFUN (show_evpn_neigh_vni_all, JSON_STR) { struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj); @@ -3410,7 +2109,7 @@ DEFUN (show_evpn_neigh_vni_neigh, struct zebra_vrf *zvrf; vni_t vni; struct ipaddr ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); if (str2ipaddr(argv[6]->arg, &ip) != 0) { @@ -3438,7 +2137,7 @@ DEFUN (show_evpn_neigh_vni_vtep, struct zebra_vrf *zvrf; vni_t vni; struct in_addr vtep_ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); if (!inet_aton(argv[6]->arg, &vtep_ip)) { @@ -3673,9 +2372,6 @@ static int config_write_protocol(struct vty *vty) == MCAST_MIX_DISTANCE ? "lower-distance" : "longer-prefix"); - - zebra_routemap_config_write_protocol(vty); - return 1; } @@ -3869,6 +2565,76 @@ DEFUN (no_ipv6_forwarding, return CMD_SUCCESS; } +/* Display dataplane info */ +DEFUN (show_dataplane, + show_dataplane_cmd, + "show zebra dplane [detailed]", + SHOW_STR + ZEBRA_STR + "Zebra dataplane information\n" + "Detailed output\n") +{ + int idx = 0; + bool detailed = false; + + if (argv_find(argv, argc, "detailed", &idx)) + detailed = true; + + return dplane_show_helper(vty, detailed); +} + +/* Display dataplane providers info */ +DEFUN (show_dataplane_providers, + show_dataplane_providers_cmd, + "show zebra dplane providers [detailed]", + SHOW_STR + ZEBRA_STR + "Zebra dataplane information\n" + "Zebra dataplane provider information\n" + "Detailed output\n") +{ + int idx = 0; + bool detailed = false; + + if (argv_find(argv, argc, "detailed", &idx)) + detailed = true; + + return dplane_show_provs_helper(vty, detailed); +} + +/* Configure dataplane incoming queue limit */ +DEFUN (zebra_dplane_queue_limit, + zebra_dplane_queue_limit_cmd, + "zebra dplane limit (0-10000)", + ZEBRA_STR + "Zebra dataplane\n" + "Limit incoming queued updates\n" + "Number of queued updates\n") +{ + uint32_t limit = 0; + + limit = strtoul(argv[3]->arg, NULL, 10); + + dplane_set_in_queue_limit(limit, true); + + return CMD_SUCCESS; +} + +/* Reset dataplane queue limit to default value */ +DEFUN (no_zebra_dplane_queue_limit, + no_zebra_dplane_queue_limit_cmd, + "no zebra dplane limit [(0-10000)]", + NO_STR + ZEBRA_STR + "Zebra dataplane\n" + "Limit incoming queued updates\n" + "Number of queued updates\n") +{ + dplane_set_in_queue_limit(0, false); + + return CMD_SUCCESS; +} + /* Table configuration write function. */ static int config_write_table(struct vty *vty) { @@ -3932,16 +2698,9 @@ void zebra_vty_init(void) install_element(CONFIG_NODE, &allow_external_route_update_cmd); install_element(CONFIG_NODE, &no_allow_external_route_update_cmd); - install_element(CONFIG_NODE, &ip_mroute_dist_cmd); + install_element(CONFIG_NODE, &ip_multicast_mode_cmd); install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd); - install_element(CONFIG_NODE, &ip_route_blackhole_cmd); - install_element(CONFIG_NODE, - &ip_route_address_interface_cmd); - install_element(CONFIG_NODE, &ip_route_cmd); - install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd); - install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd); - install_element(VRF_NODE, &ip_route_vrf_cmd); install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd); install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd); @@ -3966,19 +2725,14 @@ void zebra_vty_init(void) install_element(VIEW_NODE, &show_ip_rpf_cmd); install_element(VIEW_NODE, &show_ip_rpf_addr_cmd); - install_element(CONFIG_NODE, - &ipv6_route_blackhole_cmd); - install_element(CONFIG_NODE, - &ipv6_route_address_interface_cmd); - install_element(CONFIG_NODE, &ipv6_route_cmd); - install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd); - install_element(VRF_NODE, - &ipv6_route_address_interface_vrf_cmd); - install_element(VRF_NODE, &ipv6_route_vrf_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(VIEW_NODE, &show_ipv6_mroute_cmd); /* Commands for VRF */ @@ -4011,7 +2765,8 @@ void zebra_vty_init(void) install_element(VRF_NODE, &vrf_vni_mapping_cmd); install_element(VRF_NODE, &no_vrf_vni_mapping_cmd); - static_list = list_new(); - static_list->cmp = (int (*)(void *, void *))static_list_compare; - static_list->del = (void (*)(void *))static_list_delete; + 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); }