diff options
Diffstat (limited to 'zebra/zebra_vty.c')
| -rw-r--r-- | zebra/zebra_vty.c | 824 |
1 files changed, 592 insertions, 232 deletions
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 269244f768..3285176103 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -29,6 +29,7 @@ #include "rib.h" #include "nexthop.h" #include "vrf.h" +#include "linklist.h" #include "mpls.h" #include "routemap.h" #include "srcdest_table.h" @@ -69,25 +70,207 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty, /* * 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; \ +#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; +}; + +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 = static_list_compare_helper(shr1->dest_str, shr2->dest_str); + if (ret) + return ret; + + ret = static_list_compare_helper(shr1->mask_str, shr2->mask_str); + 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; + + return static_list_compare_helper(shr1->label_str, shr2->label_str); +} + + /* General function for static route. */ -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) +static int zebra_static_route_holdem(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) +{ + struct static_hold_route *shr, *lookup; + struct listnode *node; + + 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_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); + + 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; + } + + XFREE(MTYPE_STATIC_ROUTE, shr->nhvrf_name); + XFREE(MTYPE_STATIC_ROUTE, shr->vrf_name); + XFREE(MTYPE_STATIC_ROUTE, shr); + /* + * If a person enters the same line again + * we need to silently accept it + */ + return CMD_SUCCESS; + } + + if (!negate) + listnode_add_sort(static_list, 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) { int ret; u_char distance; @@ -103,17 +286,34 @@ static int zebra_static_route_leak(struct vty *vty, ret = str2prefix(dest_str, &p); if (ret <= 0) { - vty_out(vty, "%% Malformed address\n"); + if (vty) + vty_out(vty, "%% Malformed address\n"); + else + zlog_warn("%s: Malformed address: %s", + __PRETTY_FUNCTION__, dest_str); return CMD_WARNING_CONFIG_FAILED; } + 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, dest_str, mask_str, + src_str, gate_str, ifname, flag_str, tag_str, + distance_str, label_str); + } switch (afi) { case AFI_IP: /* Cisco like mask notation. */ if (mask_str) { ret = inet_aton(mask_str, &mask); if (ret == 0) { - vty_out(vty, "%% Malformed address\n"); + 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); @@ -124,7 +324,13 @@ static int zebra_static_route_leak(struct vty *vty, if (src_str) { ret = str2prefix(src_str, &src); if (ret <= 0 || src.family != AF_INET6) { - vty_out(vty, "%% Malformed source address\n"); + 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; @@ -151,8 +357,13 @@ static int zebra_static_route_leak(struct vty *vty, memset(&snh_label, 0, sizeof(struct static_nh_label)); if (label_str) { if (!mpls_enabled) { - vty_out(vty, - "%% MPLS not turned on in kernel, ignoring command\n"); + 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, @@ -160,18 +371,37 @@ static int zebra_static_route_leak(struct vty *vty, if (rc < 0) { switch (rc) { case -1: - vty_out(vty, "%% Malformed label(s)\n"); + 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: - vty_out(vty, - "%% Cannot use reserved label(s) (%d-%d)\n", - MPLS_LABEL_RESERVED_MIN, - MPLS_LABEL_RESERVED_MAX); + 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: - vty_out(vty, - "%% Too many labels. Enter %d or fewer\n", - MPLS_MAX_LABELS); + 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; @@ -180,10 +410,16 @@ static int zebra_static_route_leak(struct vty *vty, /* 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) { - vty_out(vty, "%% Nexthop interface cannot be Null0, reject or blackhole\n"); + 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; } } @@ -201,15 +437,28 @@ static int zebra_static_route_leak(struct vty *vty, bh_type = STATIC_BLACKHOLE_NULL; break; default: - vty_out(vty, "%% Malformed flag %s \n", flag_str); + 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) { - vty_out(vty, "%% Malformed nexthop address %s\n", - gate_str); + 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; @@ -248,17 +497,44 @@ static int zebra_static_route_leak(struct vty *vty, return CMD_SUCCESS; } -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) +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) +{ + struct zebra_vrf *zvrf; + /* VRF id */ zvrf = zebra_vrf_lookup_by_name(vrf_name); @@ -272,27 +548,47 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi, * Note: The VRF isn't active until we hear about it from the kernel. */ if (!zvrf) { - vrf = vrf_get(VRF_UNKNOWN, vrf_name); - if (!vrf) { - vty_out(vty, "%% Could not create vrf %s\n", vrf_name); - return CMD_WARNING_CONFIG_FAILED; - } - zvrf = vrf->info; - if (!zvrf) { - vty_out(vty, "%% Could not create vrf-info %s\n", - vrf_name); + zvrf = zebra_vty_get_unknown_vrf(vty, vrf_name); + if (!zvrf) return CMD_WARNING_CONFIG_FAILED; - } - /* Mark as having FRR configuration */ - vrf_set_user_cfged(vrf); } - 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); + 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); } +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); + 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, @@ -429,8 +725,8 @@ DEFPY(ip_route_blackhole, MPLS_LABEL_HELPSTR) { return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix, - mask_str, NULL, NULL, NULL, flag, - tag_str, distance_str, vrf, label); + mask_str, NULL, NULL, NULL, flag, tag_str, + distance_str, vrf, label); } DEFPY(ip_route_blackhole_vrf, @@ -464,10 +760,9 @@ DEFPY(ip_route_blackhole_vrf, * 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); + 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); } DEFPY(ip_route_address_interface, @@ -507,28 +802,25 @@ DEFPY(ip_route_address_interface, ifname = NULL; } - zvrf = zebra_vrf_lookup_by_name(vrf); + zvrf = zebra_vty_get_unknown_vrf(vty, vrf); if (!zvrf) { - vty_out(vty, "%% vrf %s is not defined\n", - vrf); + vty_out(vty, "%% vrf %s is not defined\n", vrf); return CMD_WARNING_CONFIG_FAILED; } if (nexthop_vrf) - nh_zvrf = zebra_vrf_lookup_by_name(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); + 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); + 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); } DEFPY(ip_route_address_interface_vrf, @@ -568,20 +860,18 @@ DEFPY(ip_route_address_interface_vrf, } if (nexthop_vrf) - nh_zvrf = zebra_vrf_lookup_by_name(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); + 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); + 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); } DEFPY(ip_route, @@ -619,29 +909,26 @@ DEFPY(ip_route, ifname = NULL; } - zvrf = zebra_vrf_lookup_by_name(vrf); + zvrf = zebra_vty_get_unknown_vrf(vty, vrf); if (!zvrf) { - vty_out(vty, "%% vrf %s is not defined\n", - vrf); + vty_out(vty, "%% vrf %s is not defined\n", vrf); return CMD_WARNING_CONFIG_FAILED; } if (nexthop_vrf) - nh_zvrf = zebra_vrf_lookup_by_name(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); + 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); + 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); } DEFPY(ip_route_vrf, @@ -679,20 +966,18 @@ DEFPY(ip_route_vrf, } if (nexthop_vrf) - nh_zvrf = zebra_vrf_lookup_by_name(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); + 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); + 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); } /* New RIB. Detailed information for IPv4 route. */ @@ -748,24 +1033,26 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, vty_out(vty, " Last update "); if (uptime < ONE_DAY_SECOND) - vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, - tm->tm_min, tm->tm_sec); + vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, + tm->tm_sec); else if (uptime < ONE_WEEK_SECOND) - vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, - tm->tm_hour, tm->tm_min); + vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, + tm->tm_min); else vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7, tm->tm_yday - ((tm->tm_yday / 7) * 7), tm->tm_hour); vty_out(vty, " ago\n"); - for (ALL_NEXTHOPS(re->nexthop, nexthop)) { + for (ALL_NEXTHOPS(re->ng, nexthop)) { char addrstr[32]; vty_out(vty, " %c%s", CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) - ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE) - ? ' ' : '*' + ? CHECK_FLAG(nexthop->flags, + NEXTHOP_FLAG_DUPLICATE) + ? ' ' + : '*' : ' ', nexthop->rparent ? " " : ""); @@ -924,11 +1211,11 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, } if (uptime < ONE_DAY_SECOND) - sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, - tm->tm_min, tm->tm_sec); + sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, + tm->tm_sec); else if (uptime < ONE_WEEK_SECOND) - sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, - tm->tm_hour, tm->tm_min); + sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, + tm->tm_min); else sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7, tm->tm_yday - ((tm->tm_yday / 7) * 7), @@ -936,7 +1223,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object_string_add(json_route, "uptime", buf); - for (ALL_NEXTHOPS(re->nexthop, nexthop)) { + for (ALL_NEXTHOPS(re->ng, nexthop)) { json_nexthop = json_object_new_object(); if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) @@ -1028,8 +1315,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id); - json_object_string_add(json_nexthop, - "vrf", + json_object_string_add(json_nexthop, "vrf", vrf->name); } if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) @@ -1103,8 +1389,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, } /* Nexthop information. */ - for (ALL_NEXTHOPS(re->nexthop, nexthop)) { - if (nexthop == re->nexthop) { + for (ALL_NEXTHOPS(re->ng, nexthop)) { + if (nexthop == re->ng.nexthop) { /* Prefix information. */ len = vty_out(vty, "%c", zebra_route_char(re->type)); if (re->instance) @@ -1126,8 +1412,10 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, } else { vty_out(vty, " %c%*c", CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) - ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE) - ? ' ' : '*' + ? CHECK_FLAG(nexthop->flags, + NEXTHOP_FLAG_DUPLICATE) + ? ' ' + : '*' : ' ', len - 3 + (2 * nexthop_level(nexthop)), ' '); } @@ -1235,46 +1523,21 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, } } -static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, u_char use_json, - route_tag_t tag, - const struct prefix *longer_prefix_p, - bool supernets_only, int type, - u_short ospf_instance_id) +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, + u_short ospf_instance_id, u_char use_json) { - struct route_table *table; - rib_dest_t *dest; struct route_node *rn; struct route_entry *re; int first = 1; - struct zebra_vrf *zvrf = NULL; - char buf[BUFSIZ]; + rib_dest_t *dest; json_object *json = NULL; json_object *json_prefix = NULL; - u_int32_t addr; - - if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) { - if (use_json) - vty_out(vty, "{}\n"); - else - vty_out(vty, "vrf %s not defined\n", vrf_name); - return CMD_SUCCESS; - } - - if (zvrf_id(zvrf) == VRF_UNKNOWN) { - if (use_json) - vty_out(vty, "{}\n"); - else - vty_out(vty, "vrf %s inactive\n", vrf_name); - return CMD_SUCCESS; - } - - table = zebra_vrf_table(afi, safi, zvrf_id(zvrf)); - if (!table) { - if (use_json) - vty_out(vty, "{}\n"); - return CMD_SUCCESS; - } + uint32_t addr; + char buf[BUFSIZ]; if (use_json) json = json_object_new_object(); @@ -1284,8 +1547,7 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, dest = rib_dest_from_rnode(rn); RNODE_FOREACH_RE (rn, re) { - if (use_fib - && re != dest->selected_fib) + if (use_fib && re != dest->selected_fib) continue; if (tag && re->tag != tag) @@ -1352,6 +1614,67 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, 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, u_char use_json, + route_tag_t tag, + const struct prefix *longer_prefix_p, + bool supernets_only, int type, + u_short ospf_instance_id) +{ + struct route_table *table; + struct zebra_vrf *zvrf = NULL; + + if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) { + if (use_json) + vty_out(vty, "{}\n"); + else + vty_out(vty, "vrf %s not defined\n", vrf_name); + return CMD_SUCCESS; + } + + if (zvrf_id(zvrf) == VRF_UNKNOWN) { + if (use_json) + vty_out(vty, "{}\n"); + else + vty_out(vty, "vrf %s inactive\n", vrf_name); + return CMD_SUCCESS; + } + + table = zebra_vrf_table(afi, safi, zvrf_id(zvrf)); + if (!table) { + if (use_json) + vty_out(vty, "{}\n"); + return CMD_SUCCESS; + } + + do_show_route_helper(vty, zvrf, table, afi, use_fib, tag, + longer_prefix_p, supernets_only, type, + ospf_instance_id, use_json); + + return CMD_SUCCESS; +} + +DEFPY (show_route_table, + show_route_table_cmd, + "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]", + SHOW_STR + IP_STR + IP6_STR + "IP routing table\n" + "Table to display\n" + "The table number to display, if available\n" + JSON_STR) +{ + afi_t afi = ipv4 ? AFI_IP : AFI_IP6; + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + struct route_table *t; + + t = zebra_ns_find_table(zvrf->zns, table, afi); + if (t) + do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false, + 0, 0, !!json); return CMD_SUCCESS; } @@ -1627,7 +1950,7 @@ DEFPY (show_route_detail, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) { + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL) continue; @@ -1701,7 +2024,7 @@ DEFPY (show_route_summary, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) { + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL) continue; @@ -1820,7 +2143,7 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty, * In case of ECMP, count only once. */ cnt = 0; - for (nexthop = re->nexthop; (!cnt && nexthop); + for (nexthop = re->ng.nexthop; (!cnt && nexthop); nexthop = nexthop->next) { cnt++; rib_cnt[ZEBRA_ROUTE_TOTAL]++; @@ -1869,9 +2192,11 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty, } /* Write static route configuration. */ -int static_config(struct vty *vty, struct zebra_vrf *zvrf, - afi_t afi, safi_t safi, const char *cmd) +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; @@ -1882,10 +2207,43 @@ int static_config(struct vty *vty, struct zebra_vrf *zvrf, if ((stable = zvrf->stable[afi][safi]) == NULL) return write; - sprintf(spacing, "%s%s", - (zvrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", + 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; + + vty_out(vty, "%s ", spacing); + if (shr->dest_str) + vty_out(vty, "%s ", shr->dest_str); + if (shr->mask_str) + vty_out(vty, "%s ", shr->mask_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 (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, @@ -1893,13 +2251,11 @@ int static_config(struct vty *vty, struct zebra_vrf *zvrf, switch (si->type) { case STATIC_IPV4_GATEWAY: - vty_out(vty, " %s", - inet_ntoa(si->addr.ipv4)); + 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, + inet_ntop(AF_INET6, &si->addr.ipv6, buf, sizeof buf)); break; case STATIC_IFNAME: @@ -1920,26 +2276,22 @@ int static_config(struct vty *vty, struct zebra_vrf *zvrf, break; case STATIC_IPV4_GATEWAY_IFNAME: vty_out(vty, " %s %s", - inet_ntop(AF_INET, - &si->addr.ipv4, buf, + 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, + 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); + vty_out(vty, " tag %" ROUTE_TAG_PRI, si->tag); - if (si->distance - != ZEBRA_STATIC_DISTANCE_DEFAULT) + if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT) vty_out(vty, " %d", si->distance); if (si->nh_vrf_id != si->vrf_id) { @@ -1954,8 +2306,8 @@ int static_config(struct vty *vty, struct zebra_vrf *zvrf, 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)); + si->snh_label.label, buf, + sizeof buf, 0)); vty_out(vty, "\n"); @@ -1990,8 +2342,8 @@ DEFPY(ipv6_route_blackhole, MPLS_LABEL_HELPSTR) { return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str, - NULL, from_str, NULL, NULL, flag, - tag_str, distance_str, vrf, label); + NULL, from_str, NULL, NULL, flag, tag_str, + distance_str, vrf, label); } DEFPY(ipv6_route_blackhole_vrf, @@ -2026,10 +2378,9 @@ DEFPY(ipv6_route_blackhole_vrf, * 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); + 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); } DEFPY(ipv6_route_address_interface, @@ -2062,28 +2413,25 @@ DEFPY(ipv6_route_address_interface, struct zebra_vrf *zvrf; struct zebra_vrf *nh_zvrf; - zvrf = zebra_vrf_lookup_by_name(vrf); + zvrf = zebra_vty_get_unknown_vrf(vty, vrf); if (!zvrf) { - vty_out(vty, "%% vrf %s is not defined\n", - vrf); + vty_out(vty, "%% vrf %s is not defined\n", vrf); return CMD_WARNING_CONFIG_FAILED; } if (nexthop_vrf) - nh_zvrf = zebra_vrf_lookup_by_name(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); + 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); + 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); } DEFPY(ipv6_route_address_interface_vrf, @@ -2116,20 +2464,18 @@ DEFPY(ipv6_route_address_interface_vrf, struct zebra_vrf *nh_zvrf; if (nexthop_vrf) - nh_zvrf = zebra_vrf_lookup_by_name(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); + 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); + 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); } DEFPY(ipv6_route, @@ -2161,28 +2507,25 @@ DEFPY(ipv6_route, struct zebra_vrf *zvrf; struct zebra_vrf *nh_zvrf; - zvrf = zebra_vrf_lookup_by_name(vrf); + zvrf = zebra_vty_get_unknown_vrf(vty, vrf); if (!zvrf) { - vty_out(vty, "%% vrf %s is not defined\n", - vrf); + vty_out(vty, "%% vrf %s is not defined\n", vrf); return CMD_WARNING_CONFIG_FAILED; } if (nexthop_vrf) - nh_zvrf = zebra_vrf_lookup_by_name(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); + 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); + 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); } DEFPY(ipv6_route_vrf, @@ -2214,20 +2557,18 @@ DEFPY(ipv6_route_vrf, struct zebra_vrf *nh_zvrf; if (nexthop_vrf) - nh_zvrf = zebra_vrf_lookup_by_name(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); + 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); + 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); } /* @@ -2338,8 +2679,11 @@ DEFUN (show_vrf, continue; vty_out(vty, "vrf %s ", zvrf_name(zvrf)); - if (zvrf_id(zvrf) == VRF_UNKNOWN) + if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf)) vty_out(vty, "inactive"); + else if (zvrf_ns_name(zvrf)) + vty_out(vty, "id %u netns %s", zvrf_id(zvrf), + zvrf_ns_name(zvrf)); else vty_out(vty, "id %u table %u", zvrf_id(zvrf), zvrf->table_id); @@ -2353,20 +2697,26 @@ DEFUN (show_vrf, DEFUN (default_vrf_vni_mapping, default_vrf_vni_mapping_cmd, - "vni " CMD_VNI_RANGE, + "vni " CMD_VNI_RANGE "[prefix-routes-only]", "VNI corresponding to the DEFAULT VRF\n" - "VNI-ID\n") + "VNI-ID\n" + "Prefix routes only \n") { int ret = 0; char err[ERR_STR_SZ]; struct zebra_vrf *zvrf = NULL; vni_t vni = strtoul(argv[1]->arg, NULL, 10); + int filter = 0; zvrf = vrf_info_lookup(VRF_DEFAULT); if (!zvrf) return CMD_WARNING; - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 1); + if (argc == 3) + filter = 1; + + 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; @@ -2391,7 +2741,7 @@ DEFUN (no_default_vrf_vni_mapping, if (!zvrf) return CMD_WARNING; - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0); + ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0); if (ret != 0) { vty_out(vty, "%s\n", err); return CMD_WARNING; @@ -2402,11 +2752,13 @@ DEFUN (no_default_vrf_vni_mapping, DEFUN (vrf_vni_mapping, vrf_vni_mapping_cmd, - "vni " CMD_VNI_RANGE, + "vni " CMD_VNI_RANGE "[prefix-routes-only]", "VNI corresponding to tenant VRF\n" - "VNI-ID\n") + "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); @@ -2415,9 +2767,13 @@ DEFUN (vrf_vni_mapping, assert(vrf); assert(zvrf); + 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, 1); + 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; @@ -2442,7 +2798,7 @@ DEFUN (no_vrf_vni_mapping, assert(vrf); assert(zvrf); - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0); + ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0); if (ret != 0) { vty_out(vty, "%s\n", err); return CMD_WARNING; @@ -2476,10 +2832,10 @@ DEFUN (show_vrf_vni, } if (!uj) - vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", - "VRF", "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac"); + vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF", + "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac"); - RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) { + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (!zvrf) continue; @@ -2977,10 +3333,10 @@ DEFUN_HIDDEN (zebra_workqueue_timer, "Work Queue\n" "Time in milliseconds\n") { - uint32_t timer = strtoul(argv[2]->arg, NULL, 10); - zebrad.ribq->spec.hold = timer; + uint32_t timer = strtoul(argv[2]->arg, NULL, 10); + zebrad.ribq->spec.hold = timer; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (no_zebra_workqueue_timer, @@ -2991,9 +3347,9 @@ DEFUN_HIDDEN (no_zebra_workqueue_timer, "Work Queue\n" "Time in milliseconds\n") { - zebrad.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; + zebrad.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ip_zebra_import_table, @@ -3045,8 +3401,8 @@ static int config_write_protocol(struct vty *vty) vty_out(vty, "zebra work-queue %u\n", zebrad.ribq->spec.hold); if (zebrad.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS) - vty_out(vty, - "zebra zapi-packets %u\n", zebrad.packets_to_process); + vty_out(vty, "zebra zapi-packets %u\n", + zebrad.packets_to_process); enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get(); @@ -3116,7 +3472,7 @@ DEFUN (show_zebra, vty_out(vty, "VRF Installs Removals Updates Installs Removals\n"); - RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) { + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { struct zebra_vrf *zvrf = vrf->info; vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 @@ -3341,6 +3697,7 @@ void zebra_vty_init(void) install_element(VIEW_NODE, &show_vrf_cmd); install_element(VIEW_NODE, &show_vrf_vni_cmd); install_element(VIEW_NODE, &show_route_cmd); + install_element(VIEW_NODE, &show_route_table_cmd); install_element(VIEW_NODE, &show_route_detail_cmd); install_element(VIEW_NODE, &show_route_summary_cmd); install_element(VIEW_NODE, &show_ip_nht_cmd); @@ -3390,4 +3747,7 @@ 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; } |
