*/
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;
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;
/*
* 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:
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",
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:
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");
}
}
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,
/*
* 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)
{
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");
* 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;
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:
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);
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);
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);
}
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);
}
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");
}
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) {
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 {
* clear
*/
vty_out(vty, " ");
- show_route_nexthop_helper(vty, NULL, nexthop);
+ show_route_nexthop_helper(vty, NULL, NULL,
+ nexthop);
vty_out(vty, "\n");
}
}
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];
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:
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,
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);
}