zebra/vty: use prefix2str and unify show ip/ipv6 route code
Use prefix2str where possible. As now ip/ipv6 are practically
identical, they are merged removing unneeded code duplication.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 1e39ebd..bc453de 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -699,6 +699,7 @@
struct rib *rib;
struct nexthop *nexthop, *tnexthop;
int recursing;
+ char buf[PREFIX_STRLEN];
RNODE_FOREACH_RIB (rn, rib)
{
@@ -710,15 +711,15 @@
? " using Multicast RIB"
: " using Unicast RIB";
}
- vty_out (vty, "Routing entry for %s/%d%s%s",
- inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen, mcast_info,
- VTY_NEWLINE);
+ vty_out (vty, "Routing entry for %s%s%s",
+ prefix2str (&rn->p, buf, sizeof(buf)), mcast_info,
+ VTY_NEWLINE);
vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
- vty_out (vty, ", best");
+ vty_out (vty, ", best");
if (rib->refcnt)
- vty_out (vty, ", refcnt %ld", rib->refcnt);
+ vty_out (vty, ", refcnt %ld", rib->refcnt);
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
vty_out (vty, ", blackhole");
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
@@ -728,10 +729,12 @@
#define ONE_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7
if (rib->type == ZEBRA_ROUTE_RIP
- || rib->type == ZEBRA_ROUTE_OSPF
- || rib->type == ZEBRA_ROUTE_BABEL
- || rib->type == ZEBRA_ROUTE_ISIS
- || rib->type == ZEBRA_ROUTE_BGP)
+ || rib->type == ZEBRA_ROUTE_RIPNG
+ || rib->type == ZEBRA_ROUTE_OSPF
+ || rib->type == ZEBRA_ROUTE_OSPF6
+ || rib->type == ZEBRA_ROUTE_BABEL
+ || rib->type == ZEBRA_ROUTE_ISIS
+ || rib->type == ZEBRA_ROUTE_BGP)
{
time_t uptime;
struct tm *tm;
@@ -756,53 +759,60 @@
}
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
- {
- char addrstr[32];
+ {
+ vty_out (vty, " %c%s",
+ CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
+ recursing ? " " : "");
- vty_out (vty, " %c%s",
- CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
- recursing ? " " : "");
+ switch (nexthop->type)
+ {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
+ if (nexthop->ifindex)
+ vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ case NEXTHOP_TYPE_IPV6_IFNAME:
+ vty_out (vty, " %s",
+ inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, sizeof(buf)));
+ if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
+ vty_out (vty, ", %s", nexthop->ifname);
+ else if (nexthop->ifindex)
+ vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ vty_out (vty, " directly connected, %s",
+ ifindex2ifname (nexthop->ifindex));
+ break;
+ case NEXTHOP_TYPE_IFNAME:
+ vty_out (vty, " directly connected, %s", nexthop->ifname);
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ vty_out (vty, " directly connected, Null0");
+ break;
+ default:
+ break;
+ }
+ if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ vty_out (vty, " inactive");
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
- if (nexthop->ifindex)
- vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
- break;
- case NEXTHOP_TYPE_IFINDEX:
- vty_out (vty, " directly connected, %s",
- ifindex2ifname (nexthop->ifindex));
- break;
- case NEXTHOP_TYPE_IFNAME:
- vty_out (vty, " directly connected, %s", nexthop->ifname);
- break;
- case NEXTHOP_TYPE_BLACKHOLE:
- vty_out (vty, " directly connected, Null0");
- break;
- default:
- break;
- }
- if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
- vty_out (vty, " inactive");
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
+ vty_out (vty, " onlink");
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
- vty_out (vty, " onlink");
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ vty_out (vty, " (recursive)");
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
- vty_out (vty, " (recursive)");
-
- switch (nexthop->type)
+ switch (nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
case NEXTHOP_TYPE_IPV4_IFNAME:
if (nexthop->src.ipv4.s_addr)
{
- if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
- sizeof addrstr))
- vty_out (vty, ", src %s", addrstr);
+ if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
+ vty_out (vty, ", src %s", buf);
}
break;
#ifdef HAVE_IPV6
@@ -811,17 +821,16 @@
case NEXTHOP_TYPE_IPV6_IFNAME:
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);
+ if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
+ vty_out (vty, ", src %s", buf);
}
break;
#endif /* HAVE_IPV6 */
default:
- break;
+ break;
}
- vty_out (vty, "%s", VTY_NEWLINE);
- }
+ vty_out (vty, "%s", VTY_NEWLINE);
+ }
vty_out (vty, "%s", VTY_NEWLINE);
}
}
@@ -840,14 +849,13 @@
if (nexthop == rib->nexthop)
{
/* Prefix information. */
- len = vty_out (vty, "%c%c%c %s/%d",
+ len = vty_out (vty, "%c%c%c %s",
zebra_route_char (rib->type),
CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
? '>' : ' ',
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
? '*' : ' ',
- inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
- rn->p.prefixlen);
+ prefix2str (&rn->p, buf, sizeof buf));
/* Distance and metric display. */
if (rib->type != ZEBRA_ROUTE_CONNECT
@@ -862,34 +870,44 @@
len - 3 + (2 * recursing), ' ');
switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
- if (nexthop->ifindex)
- vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
- break;
- case NEXTHOP_TYPE_IFINDEX:
- vty_out (vty, " is directly connected, %s",
- ifindex2ifname (nexthop->ifindex));
- break;
- case NEXTHOP_TYPE_IFNAME:
- vty_out (vty, " is directly connected, %s", nexthop->ifname);
- break;
- case NEXTHOP_TYPE_BLACKHOLE:
- vty_out (vty, " is directly connected, Null0");
- break;
- default:
- break;
- }
+ {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
+ if (nexthop->ifindex)
+ vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ case NEXTHOP_TYPE_IPV6_IFNAME:
+ vty_out (vty, " via %s",
+ inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
+ if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
+ vty_out (vty, ", %s", nexthop->ifname);
+ else if (nexthop->ifindex)
+ vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ vty_out (vty, " is directly connected, %s",
+ ifindex2ifname (nexthop->ifindex));
+ break;
+ case NEXTHOP_TYPE_IFNAME:
+ vty_out (vty, " is directly connected, %s", nexthop->ifname);
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ vty_out (vty, " is directly connected, Null0");
+ break;
+ default:
+ break;
+ }
if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
- vty_out (vty, " inactive");
+ vty_out (vty, " inactive");
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
- vty_out (vty, " onlink");
+ vty_out (vty, " onlink");
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
- vty_out (vty, " (recursive)");
+ vty_out (vty, " (recursive)");
switch (nexthop->type)
{
@@ -898,7 +916,7 @@
case NEXTHOP_TYPE_IPV4_IFNAME:
if (nexthop->src.ipv4.s_addr)
{
- if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
+ if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
vty_out (vty, ", src %s", buf);
}
break;
@@ -908,13 +926,13 @@
case NEXTHOP_TYPE_IPV6_IFNAME:
if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
{
- if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
+ if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
vty_out (vty, ", src %s", buf);
}
break;
#endif /* HAVE_IPV6 */
default:
- break;
+ break;
}
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
@@ -923,10 +941,12 @@
vty_out (vty, ", rej");
if (rib->type == ZEBRA_ROUTE_RIP
- || rib->type == ZEBRA_ROUTE_OSPF
- || rib->type == ZEBRA_ROUTE_BABEL
- || rib->type == ZEBRA_ROUTE_ISIS
- || rib->type == ZEBRA_ROUTE_BGP)
+ || rib->type == ZEBRA_ROUTE_RIPNG
+ || rib->type == ZEBRA_ROUTE_OSPF
+ || rib->type == ZEBRA_ROUTE_OSPF6
+ || rib->type == ZEBRA_ROUTE_BABEL
+ || rib->type == ZEBRA_ROUTE_ISIS
+ || rib->type == ZEBRA_ROUTE_BGP)
{
time_t uptime;
struct tm *tm;
@@ -1376,6 +1396,7 @@
struct route_node *rn;
struct static_ipv4 *si;
struct route_table *stable;
+ char buf[PREFIX_STRLEN];
int write;
write = 0;
@@ -1388,8 +1409,7 @@
for (rn = route_top (stable); rn; rn = route_next (rn))
for (si = rn->info; si; si = si->next)
{
- vty_out (vty, "%s %s/%d", cmd, inet_ntoa (rn->p.u.prefix4),
- rn->p.prefixlen);
+ vty_out (vty, "%s %s", cmd, prefix2str (&rn->p, buf, sizeof buf));
switch (si->type)
{
@@ -1794,208 +1814,6 @@
return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
}
-/* New RIB. Detailed information for IPv6 route. */
-static void
-vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
-{
- struct rib *rib;
- struct nexthop *nexthop, *tnexthop;
- int recursing;
- char buf[BUFSIZ];
-
- RNODE_FOREACH_RIB (rn, rib)
- {
- vty_out (vty, "Routing entry for %s/%d%s",
- inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
- rn->p.prefixlen,
- VTY_NEWLINE);
- vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
- vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
- if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
- vty_out (vty, ", best");
- if (rib->refcnt)
- vty_out (vty, ", refcnt %ld", rib->refcnt);
- if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
- vty_out (vty, ", blackhole");
- if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
- vty_out (vty, ", reject");
- vty_out (vty, "%s", VTY_NEWLINE);
-
-#define ONE_DAY_SECOND 60*60*24
-#define ONE_WEEK_SECOND 60*60*24*7
- if (rib->type == ZEBRA_ROUTE_RIPNG
- || rib->type == ZEBRA_ROUTE_OSPF6
- || rib->type == ZEBRA_ROUTE_BABEL
- || rib->type == ZEBRA_ROUTE_ISIS
- || rib->type == ZEBRA_ROUTE_BGP)
- {
- time_t uptime;
- struct tm *tm;
-
- uptime = time (NULL);
- uptime -= rib->uptime;
- tm = gmtime (&uptime);
-
- 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);
- else if (uptime < ONE_WEEK_SECOND)
- 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%s", VTY_NEWLINE);
- }
-
- for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
- {
- vty_out (vty, " %c%s",
- CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
- recursing ? " " : "");
-
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- case NEXTHOP_TYPE_IPV6_IFNAME:
- vty_out (vty, " %s",
- inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
- if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
- vty_out (vty, ", %s", nexthop->ifname);
- else if (nexthop->ifindex)
- vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
- break;
- case NEXTHOP_TYPE_IFINDEX:
- vty_out (vty, " directly connected, %s",
- ifindex2ifname (nexthop->ifindex));
- break;
- case NEXTHOP_TYPE_IFNAME:
- vty_out (vty, " directly connected, %s",
- nexthop->ifname);
- break;
- default:
- break;
- }
- if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
- vty_out (vty, " inactive");
-
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
- vty_out (vty, " onlink");
-
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
- vty_out (vty, " (recursive)");
-
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-}
-
-static void
-vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
- struct rib *rib)
-{
- struct nexthop *nexthop, *tnexthop;
- int recursing;
- int len = 0;
- char buf[BUFSIZ];
-
- /* Nexthop information. */
- for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
- {
- if (nexthop == rib->nexthop)
- {
- /* Prefix information. */
- len = vty_out (vty, "%c%c%c %s/%d",
- zebra_route_char (rib->type),
- CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
- ? '>' : ' ',
- CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
- ? '*' : ' ',
- inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
- rn->p.prefixlen);
-
- /* Distance and metric display. */
- if (rib->type != ZEBRA_ROUTE_CONNECT
- && rib->type != ZEBRA_ROUTE_KERNEL)
- len += vty_out (vty, " [%d/%d]", rib->distance,
- rib->metric);
- }
- else
- vty_out (vty, " %c%*c",
- CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
- ? '*' : ' ',
- len - 3 + (2 * recursing), ' ');
-
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- case NEXTHOP_TYPE_IPV6_IFNAME:
- vty_out (vty, " via %s",
- inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
- if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
- vty_out (vty, ", %s", nexthop->ifname);
- else if (nexthop->ifindex)
- vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
- break;
- case NEXTHOP_TYPE_IFINDEX:
- vty_out (vty, " is directly connected, %s",
- ifindex2ifname (nexthop->ifindex));
- break;
- case NEXTHOP_TYPE_IFNAME:
- vty_out (vty, " is directly connected, %s",
- nexthop->ifname);
- break;
- default:
- break;
- }
- if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
- vty_out (vty, " inactive");
-
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
- vty_out (vty, " (recursive)");
-
- if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
- vty_out (vty, ", bh");
- if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
- vty_out (vty, ", rej");
-
- if (rib->type == ZEBRA_ROUTE_RIPNG
- || rib->type == ZEBRA_ROUTE_OSPF6
- || rib->type == ZEBRA_ROUTE_BABEL
- || rib->type == ZEBRA_ROUTE_ISIS
- || rib->type == ZEBRA_ROUTE_BGP)
- {
- time_t uptime;
- struct tm *tm;
-
- uptime = time (NULL);
- uptime -= rib->uptime;
- tm = gmtime (&uptime);
-
-#define ONE_DAY_SECOND 60*60*24
-#define ONE_WEEK_SECOND 60*60*24*7
-
- if (uptime < ONE_DAY_SECOND)
- 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);
- 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, "%s", VTY_NEWLINE);
- }
-}
-
DEFUN (show_ipv6_route,
show_ipv6_route_cmd,
"show ipv6 route",
@@ -2021,7 +1839,7 @@
vty_out (vty, SHOW_ROUTE_V6_HEADER);
first = 0;
}
- vty_show_ipv6_route (vty, rn, rib);
+ vty_show_ip_route (vty, rn, rib);
}
return CMD_SUCCESS;
}
@@ -2063,7 +1881,7 @@
vty_out (vty, SHOW_ROUTE_V6_HEADER);
first = 0;
}
- vty_show_ipv6_route (vty, rn, rib);
+ vty_show_ip_route (vty, rn, rib);
}
return CMD_SUCCESS;
}
@@ -2103,7 +1921,7 @@
vty_out (vty, SHOW_ROUTE_V6_HEADER);
first = 0;
}
- vty_show_ipv6_route (vty, rn, rib);
+ vty_show_ip_route (vty, rn, rib);
}
return CMD_SUCCESS;
}
@@ -2139,7 +1957,7 @@
return CMD_WARNING;
}
- vty_show_ipv6_route_detail (vty, rn);
+ vty_show_ip_route_detail (vty, rn, 0);
route_unlock_node (rn);
@@ -2179,7 +1997,7 @@
return CMD_WARNING;
}
- vty_show_ipv6_route_detail (vty, rn);
+ vty_show_ip_route_detail (vty, rn, 0);
route_unlock_node (rn);
@@ -2257,7 +2075,7 @@
vty_out (vty, SHOW_ROUTE_V6_HEADER);
first = 0;
}
- vty_show_ipv6_route (vty, rn, rib);
+ vty_show_ip_route (vty, rn, rib);
}
return CMD_SUCCESS;
}
@@ -2282,9 +2100,7 @@
for (rn = route_top (stable); rn; rn = route_next (rn))
for (si = rn->info; si; si = si->next)
{
- vty_out (vty, "ipv6 route %s/%d",
- inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
- rn->p.prefixlen);
+ vty_out (vty, "ipv6 route %s", prefix2str (&rn->p, buf, sizeof buf));
switch (si->type)
{