diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 4a15b7400496..5c582995f2a1 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2369,6 +2369,14 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx break; setsrc = nexthop_set_src(nexthop, p->family, &src); + if (setsrc && IS_ZEBRA_DEBUG_KERNEL) { + if (p->family == AF_INET) + zlog_debug("%s: %pFX set src %pI4", + __func__, p, &src.ipv4); + else if (p->family == AF_INET6) + zlog_debug("%s: %pFX set src %pI6", + __func__, p, &src.ipv6); + } } if (setsrc) { @@ -2411,6 +2419,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx setsrc = nexthop_set_src(nexthop, p->family, &src); + if (setsrc && IS_ZEBRA_DEBUG_KERNEL) { + if (p->family == AF_INET) + zlog_debug("%s: %pFX set src %pI4", + __func__, p, + &src.ipv4); + else if (p->family == AF_INET6) + zlog_debug("%s: %pFX set src %pI6", + __func__, p, + &src.ipv6); + } continue; } @@ -2472,6 +2490,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx setsrc = nexthop_set_src(nexthop, p->family, &src); + if (setsrc && IS_ZEBRA_DEBUG_KERNEL) { + if (p->family == AF_INET) + zlog_debug("%s: %pFX set src %pI4", + __func__, p, + &src.ipv4); + else if (p->family == AF_INET6) + zlog_debug("%s: %pFX set src %pI6", + __func__, p, + &src.ipv6); + } continue; } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index b387e9949bb0..06fb5b099b0b 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -1266,6 +1266,7 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client, */ void show_nexthop_json_helper(json_object *json_nexthop, const struct nexthop *nexthop, + const struct route_node *rn, const struct route_entry *re) { json_object *json_labels = NULL; @@ -1381,13 +1382,24 @@ void show_nexthop_json_helper(json_object *json_nexthop, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->src.ipv4.s_addr) + if (nexthop->rmap_src.ipv4.s_addr) + json_object_string_addf(json_nexthop, "rmapSource", + "%pI4", &nexthop->rmap_src.ipv4); + else if (nexthop->src.ipv4.s_addr) json_object_string_addf(json_nexthop, "source", "%pI4", &nexthop->src.ipv4); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn && rn->p.family == AF_INET && + nexthop->rmap_src.ipv4.s_addr) + json_object_string_addf(json_nexthop, "rmapSource", + "%pI4", &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + json_object_string_addf(json_nexthop, "rmapSource", + "%pI6", &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) json_object_string_addf(json_nexthop, "source", "%pI6", &nexthop->src.ipv6); break; @@ -1461,13 +1473,15 @@ void show_nexthop_json_helper(json_object *json_nexthop, /* * Helper for nexthop output, used in the 'show ip route' path */ -void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re, +void show_route_nexthop_helper(struct vty *vty, const struct route_node *rn, + const struct route_entry *re, const struct nexthop *nexthop) { char buf[MPLS_LABEL_STRLEN]; char seg_buf[SRV6_SEG_STRLEN]; struct seg6_segs segs; uint8_t i; + bool src_p = false; switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: @@ -1529,8 +1543,14 @@ void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->src.ipv4.s_addr) { + if (nexthop->rmap_src.ipv4.s_addr) { + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + src_p = true; + } else if (nexthop->src.ipv4.s_addr) { vty_out(vty, ", src %pI4", &nexthop->src.ipv4); + src_p = true; + } + if (src_p) { /* SR-TE information */ if (nexthop->srte_color) vty_out(vty, ", SR-TE color %u", @@ -1539,7 +1559,13 @@ void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re, break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn && rn->p.family == AF_INET && + nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + vty_out(vty, ", rmapsrc %pI6", &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) vty_out(vty, ", src %pI6", &nexthop->src.ipv6); break; case NEXTHOP_TYPE_IFINDEX: @@ -1644,9 +1670,10 @@ static void print_rnh(struct route_node *rn, struct vty *vty, json_object *json) json_object_array_add(json_nexthop_array, json_nexthop); show_nexthop_json_helper(json_nexthop, nexthop, - NULL); + rn, NULL); } else { - show_route_nexthop_helper(vty, NULL, nexthop); + show_route_nexthop_helper(vty, rn, NULL, + nexthop); vty_out(vty, "\n"); } } diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 07db7bbd7a10..f0b10d825c84 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -45,8 +45,10 @@ bool rnh_get_hide_backups(void); void show_nexthop_json_helper(json_object *json_nexthop, const struct nexthop *nexthop, + const struct route_node *rn, const struct route_entry *re); -void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re, +void show_route_nexthop_helper(struct vty *vty, const struct route_node *rn, + const struct route_entry *re, const struct nexthop *nexthop); #ifdef __cplusplus diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index bdbb059e5619..44720754ba8b 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -76,13 +76,17 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty, bool use_json); /* Helper api to format a nexthop in the 'detailed' output path. */ static void show_nexthop_detail_helper(struct vty *vty, + const struct route_node *rn, const struct route_entry *re, const struct nexthop *nexthop, bool is_backup); static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table); -static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop, - struct route_entry *re, unsigned int num); +static void show_ip_route_nht_dump(struct vty *vty, + const struct nexthop *nexthop, + const struct route_node *rn, + const struct route_entry *re, + unsigned int num); DEFUN (ip_multicast_mode, ip_multicast_mode_cmd, @@ -252,7 +256,7 @@ static char re_status_output_char(const struct route_entry *re, /* * Show backup nexthop info, in the 'detailed' output path */ -static void show_nh_backup_helper(struct vty *vty, +static void show_nh_backup_helper(struct vty *vty, const struct route_node *rn, const struct route_entry *re, const struct nexthop *nexthop) { @@ -282,7 +286,7 @@ static void show_nh_backup_helper(struct vty *vty, temp = backup; while (backup) { vty_out(vty, " "); - show_nexthop_detail_helper(vty, re, backup, + show_nexthop_detail_helper(vty, rn, re, backup, true /*backup*/); vty_out(vty, "\n"); @@ -303,11 +307,11 @@ static void show_nh_backup_helper(struct vty *vty, * output path. */ static void show_nexthop_detail_helper(struct vty *vty, + const struct route_node *rn, const struct route_entry *re, const struct nexthop *nexthop, bool is_backup) { - char addrstr[32]; char buf[MPLS_LABEL_STRLEN]; int i; @@ -391,23 +395,21 @@ static void show_nexthop_detail_helper(struct vty *vty, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->src.ipv4.s_addr) { - if (inet_ntop(AF_INET, &nexthop->src.ipv4, - addrstr, sizeof(addrstr))) - vty_out(vty, ", src %s", - addrstr); - } + if (nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + else if (nexthop->src.ipv4.s_addr) + vty_out(vty, ", src %pI4", &nexthop->src.ipv4); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, - &in6addr_any)) { - if (inet_ntop(AF_INET6, &nexthop->src.ipv6, - addrstr, sizeof(addrstr))) - vty_out(vty, ", src %s", - addrstr); - } + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn->p.family == AF_INET && nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + vty_out(vty, ", rmapsrc %pI6", &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + vty_out(vty, ", src %pI6", &nexthop->src.ipv6); break; case NEXTHOP_TYPE_IFINDEX: @@ -591,13 +593,13 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) { /* Use helper to format each nexthop */ - show_nexthop_detail_helper(vty, re, nexthop, + show_nexthop_detail_helper(vty, rn, re, nexthop, false /*not backup*/); vty_out(vty, "\n"); /* Include backup(s), if present */ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) - show_nh_backup_helper(vty, re, nexthop); + show_nh_backup_helper(vty, rn, re, nexthop); } zebra_show_ip_route_opaque(vty, re, NULL); @@ -704,8 +706,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, for (ALL_NEXTHOPS_PTR(nhg, nexthop)) { json_nexthop = json_object_new_object(); - show_nexthop_json_helper(json_nexthop, - nexthop, re); + show_nexthop_json_helper(json_nexthop, nexthop, rn, re); json_object_array_add(json_nexthops, json_nexthop); @@ -725,8 +726,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, for (ALL_NEXTHOPS_PTR(nhg, nexthop)) { json_nexthop = json_object_new_object(); - show_nexthop_json_helper(json_nexthop, - nexthop, re); + show_nexthop_json_helper(json_nexthop, nexthop, + rn, re); json_object_array_add(json_nexthops, json_nexthop); } @@ -791,7 +792,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, len - 3 + (2 * nexthop_level(nexthop)), ' '); } - show_route_nexthop_helper(vty, re, nexthop); + show_route_nexthop_helper(vty, rn, re, nexthop); vty_out(vty, ", %s\n", up_str); } @@ -822,7 +823,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, vty_out(vty, " b%c %*c", (star_p ? '*' : ' '), len - 3 + (2 * nexthop_level(nexthop)), ' '); - show_route_nexthop_helper(vty, re, nexthop); + show_route_nexthop_helper(vty, rn, re, nexthop); vty_out(vty, "\n"); } @@ -1278,14 +1279,15 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe, for (ALL_NEXTHOPS(nhe->nhg, nexthop)) { if (json_nexthop_array) { json_nexthops = json_object_new_object(); - show_nexthop_json_helper(json_nexthops, nexthop, NULL); + show_nexthop_json_helper(json_nexthops, nexthop, NULL, + NULL); } else { if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) vty_out(vty, " "); else /* Make recursive nexthops a bit more clear */ vty_out(vty, " "); - show_route_nexthop_helper(vty, NULL, nexthop); + show_route_nexthop_helper(vty, NULL, NULL, nexthop); } if (nhe->backup_info == NULL || nhe->backup_info->nhe == NULL) { @@ -1343,7 +1345,7 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe, if (json_backup_nexthop_array) { json_backup_nexthops = json_object_new_object(); show_nexthop_json_helper(json_backup_nexthops, - nexthop, NULL); + nexthop, NULL, NULL); json_object_array_add(json_backup_nexthop_array, json_backup_nexthops); } else { @@ -1356,7 +1358,8 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe, * clear */ vty_out(vty, " "); - show_route_nexthop_helper(vty, NULL, nexthop); + show_route_nexthop_helper(vty, NULL, NULL, + nexthop); vty_out(vty, "\n"); } } @@ -2104,8 +2107,11 @@ DEFUN_HIDDEN (show_route_zebra_dump, return CMD_SUCCESS; } -static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop, - struct route_entry *re, unsigned int num) +static void show_ip_route_nht_dump(struct vty *vty, + const struct nexthop *nexthop, + const struct route_node *rn, + const struct route_entry *re, + unsigned int num) { char buf[SRCDEST2STR_BUFFER]; @@ -2129,10 +2135,12 @@ static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop, nexthop->vrf_id)); } - if (nexthop->src.ipv4.s_addr - && (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, - sizeof(buf)))) - vty_out(vty, " source: %s\n", buf); + if (nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, " rmapsrc: %pI4\n", + &nexthop->rmap_src.ipv4); + else if (nexthop->src.ipv4.s_addr) + vty_out(vty, " source: %pI4\n", + &nexthop->src.ipv4.s_addr); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -2149,11 +2157,15 @@ static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop, nexthop->vrf_id)); } - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) { - if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, - sizeof(buf))) - vty_out(vty, " source: %s\n", buf); - } + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn->p.family == AF_INET && nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, " rmapsrc: %pI4\n", + &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + vty_out(vty, " rmapsrc: %pI6\n", + &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + vty_out(vty, " source: %pI6\n", &nexthop->src.ipv6); break; case NEXTHOP_TYPE_IFINDEX: vty_out(vty, @@ -2245,7 +2257,7 @@ static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table) for (ALL_NEXTHOPS_PTR(&(re->nhe->nhg), nexthop)) { nexthop_num++; - show_ip_route_nht_dump(vty, nexthop, re, + show_ip_route_nht_dump(vty, nexthop, rn, re, nexthop_num); }