diff options
author | dim <dim@FreeBSD.org> | 2015-02-22 16:04:37 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-02-22 16:04:37 +0000 |
commit | 9bd5a747dd2c968d97a8932065fb94723bbeae9c (patch) | |
tree | 62a36bf13e95aeb90982314c4943a29b289e60ee /usr.bin/netstat/route.c | |
parent | 1e024675bcd5e4ace8bffb2dd6afd3fa8b8ad7f3 (diff) | |
parent | 88c4104dd7fac3a58708a6de5dcd21610a7f0316 (diff) | |
download | FreeBSD-src-9bd5a747dd2c968d97a8932065fb94723bbeae9c.zip FreeBSD-src-9bd5a747dd2c968d97a8932065fb94723bbeae9c.tar.gz |
Merge ^/head r279023 through r279162.
Diffstat (limited to 'usr.bin/netstat/route.c')
-rw-r--r-- | usr.bin/netstat/route.c | 320 |
1 files changed, 210 insertions, 110 deletions
diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c index 7555615..5ae40b1 100644 --- a/usr.bin/netstat/route.c +++ b/usr.bin/netstat/route.c @@ -64,10 +64,12 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> #include <sysexits.h> #include <unistd.h> #include <err.h> +#include <libxo/xo.h> #include "netstat.h" #define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d))) @@ -78,25 +80,26 @@ __FBSDID("$FreeBSD$"); struct bits { u_long b_mask; char b_val; + const char *b_name; } bits[] = { - { RTF_UP, 'U' }, - { RTF_GATEWAY, 'G' }, - { RTF_HOST, 'H' }, - { RTF_REJECT, 'R' }, - { RTF_DYNAMIC, 'D' }, - { RTF_MODIFIED, 'M' }, - { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ - { RTF_XRESOLVE, 'X' }, - { RTF_STATIC, 'S' }, - { RTF_PROTO1, '1' }, - { RTF_PROTO2, '2' }, - { RTF_PROTO3, '3' }, - { RTF_BLACKHOLE,'B' }, - { RTF_BROADCAST,'b' }, + { RTF_UP, 'U', "up" }, + { RTF_GATEWAY, 'G', "gateway" }, + { RTF_HOST, 'H', "host" }, + { RTF_REJECT, 'R', "reject" }, + { RTF_DYNAMIC, 'D', "dynamic" }, + { RTF_MODIFIED, 'M', "modified" }, + { RTF_DONE, 'd', "done" }, /* Completed -- for routing msgs only */ + { RTF_XRESOLVE, 'X', "xresolve" }, + { RTF_STATIC, 'S', "static" }, + { RTF_PROTO1, '1', "proto1" }, + { RTF_PROTO2, '2', "proto2" }, + { RTF_PROTO3, '3', "proto3" }, + { RTF_BLACKHOLE,'B', "blackhole" }, + { RTF_BROADCAST,'b', "broadcast" }, #ifdef RTF_LLINFO - { RTF_LLINFO, 'L' }, + { RTF_LLINFO, 'L', "llinfo" }, #endif - { 0 , 0 } + { 0 , 0, NULL } }; /* @@ -143,14 +146,15 @@ static void size_cols_rtentry(struct rtentry *rt); static void p_rtnode_kvm(void); static void p_rtable_sysctl(int, int); static void p_rtable_kvm(int, int ); -static void p_rtree_kvm(struct radix_node *); -static void p_rtentry_sysctl(struct rt_msghdr *); -static void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int); +static void p_rtree_kvm(const char *name, struct radix_node *); +static void p_rtentry_kvm(const char *name, struct rtentry *); +static void p_rtentry_sysctl(const char *name, struct rt_msghdr *); +static void p_sockaddr(const char *name, struct sockaddr *, struct sockaddr *, + int, int); static const char *fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags); static void p_flags(int, const char *); static const char *fmt_flags(int f); -static void p_rtentry_kvm(struct rtentry *); static void domask(char *, in_addr_t, u_long); /* @@ -178,15 +182,17 @@ routepr(int fibnum, int af) if (clock_gettime(CLOCK_UPTIME, &uptime) < 0) err(EX_OSERR, "clock_gettime() failed"); - printf("Routing tables"); + xo_open_container("route-information"); + xo_emit("{T:Routing tables}"); if (fibnum) - printf(" (fib: %d)", fibnum); - printf("\n"); + xo_emit(" ({L:fib}: {:fib/%d})", fibnum); + xo_emit("\n"); if (Aflag == 0 && live != 0 && NewTree) p_rtable_sysctl(fibnum, af); else p_rtable_kvm(fibnum, af); + xo_close_container("route-information"); } @@ -221,9 +227,9 @@ pr_family(int af1) break; } if (afname) - printf("\n%s:\n", afname); + xo_emit("\n{k:address-family/%s}:\n", afname); else - printf("\nProtocol Family %d:\n", af1); + xo_emit("\n{L:Protocol Family} {k:address-family/%d}:\n", af1); } /* column widths; each followed by one space */ @@ -320,7 +326,7 @@ size_cols_rtentry(struct rtentry *rt) } if (rt->rt_ifp) { if (rt->rt_ifp != lastif) { - if (kget(rt->rt_ifp, ifnet) == 0) + if (kget(rt->rt_ifp, ifnet) == 0) len = strlen(ifnet.if_xname); else len = strlen("---"); @@ -333,7 +339,7 @@ size_cols_rtentry(struct rtentry *rt) if ((expire_time = rt->rt_expire - uptime.tv_sec) > 0) { len = snprintf(buffer, sizeof(buffer), "%d", - (int)expire_time); + (int)expire_time); wid_expire = MAX(len, wid_expire); } } @@ -349,9 +355,10 @@ pr_rthdr(int af1) { if (Aflag) - printf("%-8.8s ","Address"); + xo_emit("{T:/%-8.8s} ","Address"); if (Wflag) { - printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*s\n", + xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s} {T:/%*.*s} " + "{T:/%*.*s} {T:/%*.*s} {T:/%*.*s} {T:/%*s}\n", wid_dst, wid_dst, "Destination", wid_gw, wid_gw, "Gateway", wid_flags, wid_flags, "Flags", @@ -360,7 +367,8 @@ pr_rthdr(int af1) wid_if, wid_if, "Netif", wid_expire, "Expire"); } else { - printf("%-*.*s %-*.*s %-*.*s %*.*s %*s\n", + xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s} {T:/%*.*s} " + "{T:/%*s}\n", wid_dst, wid_dst, "Destination", wid_gw, wid_gw, "Gateway", wid_flags, wid_flags, "Flags", @@ -391,10 +399,11 @@ p_rtable_kvm(int fibnum, int af) struct radix_node_head **rt_tables; u_long rtree; int fam, af_size; + bool did_rt_family = false; kresolve_list(rl); if ((rtree = rl[N_RTREE].n_value) == 0) { - printf("rt_tables: symbol not in namelist\n"); + xo_emit("rt_tables: symbol not in namelist\n"); return; } @@ -406,6 +415,7 @@ p_rtable_kvm(int fibnum, int af) if (kread((u_long)(rtree), (char *)(rt_tables) + fibnum * af_size, af_size) != 0) err(EX_OSERR, "error retrieving radix pointers"); + xo_open_container("route-table"); for (fam = 0; fam <= AF_MAX; fam++) { int tmpfib; @@ -430,17 +440,30 @@ p_rtable_kvm(int fibnum, int af) continue; if (fam == AF_UNSPEC) { if (Aflag && af == 0) { - printf("Netmasks:\n"); - p_rtree_kvm(head.rnh_treetop); + xo_emit("{T:Netmasks}:\n"); + xo_open_list("netmasks"); + p_rtree_kvm("netmasks", head.rnh_treetop); + xo_close_list("netmasks"); } } else if (af == AF_UNSPEC || af == fam) { + if (!did_rt_family) { + xo_open_list("rt-family"); + did_rt_family = true; + } size_cols(fam, head.rnh_treetop); + xo_open_instance("rt-family"); pr_family(fam); do_rtent = 1; + xo_open_list("rt-entry"); pr_rthdr(fam); - p_rtree_kvm(head.rnh_treetop); + p_rtree_kvm("rt-entry", head.rnh_treetop); + xo_close_list("rt-entry"); + xo_close_instance("rt-family"); } } + if (did_rt_family) + xo_close_list("rt-family"); + xo_close_container("route-table"); free(rt_tables); } @@ -450,8 +473,18 @@ p_rtable_kvm(int fibnum, int af) * debugging kvm(3) interface. */ static void -p_rtree_kvm(struct radix_node *rn) +p_rtree_kvm(const char *name, struct radix_node *rn) { + bool opened; + + opened = false; + +#define DOOPEN() do { \ + if (!opened) { xo_open_instance(name); opened = true; } \ + } while (0) +#define DOCLOSE() do { \ + if (opened) { opened = false; xo_close_instance(name); } \ + } while(0) again: if (kget(rn, rnode) != 0) @@ -459,33 +492,46 @@ again: if (!(rnode.rn_flags & RNF_ACTIVE)) return; if (rnode.rn_bit < 0) { - if (Aflag) - printf("%-8.8lx ", (u_long)rn); + if (Aflag) { + DOOPEN(); + xo_emit("{q:radix-node/%-8.8lx} ", (u_long)rn); + } if (rnode.rn_flags & RNF_ROOT) { - if (Aflag) - printf("(root node)%s", + if (Aflag) { + DOOPEN(); + xo_emit("({:root/root} node){L:/%s}", rnode.rn_dupedkey ? " =>\n" : "\n"); + } } else if (do_rtent) { if (kget(rn, rtentry) == 0) { - p_rtentry_kvm(&rtentry); - if (Aflag) + DOOPEN(); + p_rtentry_kvm(name, &rtentry); + if (Aflag) { + DOOPEN(); p_rtnode_kvm(); + DOCLOSE(); + } } } else { - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key), - NULL, 0, 44); - putchar('\n'); + DOOPEN(); + p_sockaddr("address", + kgetsa((struct sockaddr *)rnode.rn_key), + NULL, 0, 44); + xo_emit("\n"); } + DOCLOSE(); if ((rn = rnode.rn_dupedkey)) goto again; } else { if (Aflag && do_rtent) { - printf("%-8.8lx ", (u_long)rn); + DOOPEN(); + xo_emit("{q:radix-node/%-8.8lx} ", (u_long)rn); p_rtnode_kvm(); + DOCLOSE(); } rn = rnode.rn_right; - p_rtree_kvm(rnode.rn_left); - p_rtree_kvm(rn); + p_rtree_kvm(name, rnode.rn_left); + p_rtree_kvm(name, rn); } } @@ -498,37 +544,41 @@ p_rtnode_kvm(void) if (rnode.rn_bit < 0) { if (rnode.rn_mask) { - printf("\t mask "); - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask), - NULL, 0, -1); + xo_emit("\t {L:mask} "); + p_sockaddr("netmask", + kgetsa((struct sockaddr *)rnode.rn_mask), + NULL, 0, -1); } else if (rm == 0) return; } else { - sprintf(nbuf, "(%d)", rnode.rn_bit); - printf("%6.6s %8.8lx : %8.8lx", nbuf, (u_long)rnode.rn_left, (u_long)rnode.rn_right); + xo_emit("{[:6}{:bit/(%d)}{]:} {q:left-node/%8.8lx} " + ": {q:right-node/%8.8lx}", rnode.rn_bit, + (u_long)rnode.rn_left, (u_long)rnode.rn_right); } while (rm) { if (kget(rm, rmask) != 0) break; sprintf(nbuf, " %d refs, ", rmask.rm_refs); - printf(" mk = %8.8lx {(%d),%s", - (u_long)rm, -1 - rmask.rm_bit, rmask.rm_refs ? nbuf : " "); + xo_emit(" mk = {q:node/%8.8lx} \\{({:bit/%d}),{nbufs/%s}", + (u_long)rm, -1 - rmask.rm_bit, rmask.rm_refs ? nbuf : " "); if (rmask.rm_flags & RNF_NORMAL) { struct radix_node rnode_aux; - printf(" <normal>, "); + xo_emit(" <{:mode/normal}>, "); if (kget(rmask.rm_leaf, rnode_aux) == 0) - p_sockaddr(kgetsa((struct sockaddr *)rnode_aux.rn_mask), + p_sockaddr("netmask", + kgetsa(/*XXX*/(void *)rnode_aux.rn_mask), NULL, 0, -1); else - p_sockaddr(NULL, NULL, 0, -1); + p_sockaddr(NULL, NULL, NULL, 0, -1); } else - p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask), - NULL, 0, -1); - putchar('}'); + p_sockaddr("netmask", + kgetsa((struct sockaddr *)rmask.rm_mask), + NULL, 0, -1); + xo_emit("\\}"); if ((rm = rmask.rm_mklist)) - printf(" ->"); + xo_emit(" {D:->}"); } - putchar('\n'); + xo_emit("\n"); } static void @@ -539,7 +589,8 @@ p_rtable_sysctl(int fibnum, int af) char *buf, *next, *lim; struct rt_msghdr *rtm; struct sockaddr *sa; - int fam = 0, ifindex = 0, size; + int fam = AF_UNSPEC, ifindex = 0, size; + int need_table_close = false; struct ifaddrs *ifap, *ifa; struct sockaddr_dl *sdl; @@ -566,7 +617,7 @@ p_rtable_sysctl(int fibnum, int af) errx(2, "realloc(%d) failed", size); memset(&ifmap[ifmap_size], 0, size - ifmap_size * - sizeof(struct ifmap_entry)); + sizeof(struct ifmap_entry)); ifmap_size = roundup(ifindex + 1, 32); } @@ -594,6 +645,8 @@ p_rtable_sysctl(int fibnum, int af) if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0) err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum); lim = buf + needed; + xo_open_container("route-table"); + xo_open_list("rt-family"); for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; if (rtm->rtm_version != RTM_VERSION) @@ -602,19 +655,35 @@ p_rtable_sysctl(int fibnum, int af) * Peek inside header to determine AF */ sa = (struct sockaddr *)(rtm + 1); + /* Only print family first time. */ if (fam != sa->sa_family) { + if (need_table_close) { + xo_close_list("rt-entry"); + xo_close_instance("rt-family"); + } + need_table_close = true; + fam = sa->sa_family; size_cols(fam, NULL); + xo_open_instance("rt-family"); pr_family(fam); + xo_open_list("rt-entry"); + pr_rthdr(fam); } - p_rtentry_sysctl(rtm); + p_rtentry_sysctl("rt-entry", rtm); + } + if (need_table_close) { + xo_close_list("rt-entry"); + xo_close_instance("rt-family"); } + xo_close_list("rt-family"); + xo_close_container("route-table"); free(buf); } static void -p_rtentry_sysctl(struct rt_msghdr *rtm) +p_rtentry_sysctl(const char *name, struct rt_msghdr *rtm) { struct sockaddr *sa = (struct sockaddr *)(rtm + 1); char buffer[128]; @@ -622,6 +691,8 @@ p_rtentry_sysctl(struct rt_msghdr *rtm) sa_u addr, mask, gw; unsigned int l; + xo_open_instance(name); + #define GETSA(_s, _f) { \ bzero(&(_s), sizeof(_s)); \ if (rtm->rtm_addrs & _f) { \ @@ -634,18 +705,20 @@ p_rtentry_sysctl(struct rt_msghdr *rtm) GETSA(addr, RTA_DST); GETSA(gw, RTA_GATEWAY); GETSA(mask, RTA_NETMASK); - p_sockaddr(&addr.u_sa, &mask.u_sa, rtm->rtm_flags, wid_dst); - p_sockaddr(&gw.u_sa, NULL, RTF_HOST, wid_gw); - snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags); + p_sockaddr("destination", &addr.u_sa, &mask.u_sa, rtm->rtm_flags, + wid_dst); + p_sockaddr("gateway", &gw.u_sa, NULL, RTF_HOST, wid_gw); + snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:}", + wid_flags); p_flags(rtm->rtm_flags, buffer); if (Wflag) { - printf("%*lu ", wid_pksent, rtm->rtm_rmx.rmx_pksent); + xo_emit("{t:use/%*lu} ", wid_pksent, rtm->rtm_rmx.rmx_pksent); if (rtm->rtm_rmx.rmx_mtu != 0) - printf("%*lu ", wid_mtu, rtm->rtm_rmx.rmx_mtu); + xo_emit("{t:mtu/%*lu} ", wid_mtu, rtm->rtm_rmx.rmx_mtu); else - printf("%*s ", wid_mtu, ""); + xo_emit("{P:/%*s} ", wid_mtu, ""); } memset(prettyname, 0, sizeof(prettyname)); @@ -656,32 +729,41 @@ p_rtentry_sysctl(struct rt_msghdr *rtm) strlcpy(prettyname, "---", sizeof(prettyname)); } - printf("%*.*s", wid_if, wid_if, prettyname); + xo_emit("{t:interface-name/%*.*s}", wid_if, wid_if, prettyname); if (rtm->rtm_rmx.rmx_expire) { time_t expire_time; - if ((expire_time = - rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0) - printf(" %*d", wid_expire, (int)expire_time); + if ((expire_time = rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0) + xo_emit(" {:expire-time/%*d}", wid_expire, + (int)expire_time); } - putchar('\n'); + xo_emit("\n"); + xo_close_instance(name); } static void -p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width) +p_sockaddr(const char *name, struct sockaddr *sa, struct sockaddr *mask, + int flags, int width) { const char *cp; + char buf[128]; cp = fmt_sockaddr(sa, mask, flags); - if (width < 0 ) - printf("%s ", cp); - else { - if (numeric_addr) - printf("%-*s ", width, cp); - else - printf("%-*.*s ", width, width, cp); + if (width < 0) { + snprintf(buf, sizeof(buf), "{:%s/%%s} ", name); + xo_emit(buf, cp); + } else { + if (numeric_addr) { + snprintf(buf, sizeof(buf), "{[:%d}{:%s/%%s}{]:} ", + -width, name); + xo_emit(buf, cp); + } else { + snprintf(buf, sizeof(buf), "{[:%d}{:%s/%%-.*s}{]:} ", + -width, name); + xo_emit(buf, width, cp); + } } } @@ -742,7 +824,7 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) case AF_NETGRAPH: { strlcpy(workbuf, ((struct sockaddr_ng *)sa)->sg_data, - sizeof(workbuf)); + sizeof(workbuf)); cp = workbuf; break; } @@ -798,7 +880,15 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) static void p_flags(int f, const char *format) { - printf(format, fmt_flags(f)); + struct bits *p; + + xo_emit(format, fmt_flags(f)); + + xo_open_list("flags_pretty"); + for (p = bits; p->b_mask; p++) + if (p->b_mask & f) + xo_emit("{le:flags_pretty/%s}", p->b_name); + xo_close_list("flags_pretty"); } static const char * @@ -816,7 +906,7 @@ fmt_flags(int f) } static void -p_rtentry_kvm(struct rtentry *rt) +p_rtentry_kvm(const char *name, struct rtentry *rt) { static struct ifnet ifnet, *lastif; static char buffer[128]; @@ -830,18 +920,21 @@ p_rtentry_kvm(struct rtentry *rt) bzero(&mask, sizeof(mask)); if (rt_mask(rt) && (sa = kgetsa(rt_mask(rt)))) bcopy(sa, &mask, sa->sa_len); - p_sockaddr(&addr.u_sa, &mask.u_sa, rt->rt_flags, wid_dst); - p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST, wid_gw); - snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags); + + p_sockaddr("destination", &addr.u_sa, &mask.u_sa, rt->rt_flags, + wid_dst); + p_sockaddr("gateway", kgetsa(rt->rt_gateway), NULL, RTF_HOST, wid_gw); + snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:}", + wid_flags); p_flags(rt->rt_flags, buffer); if (Wflag) { - printf("%*ju ", wid_pksent, + xo_emit("{[:%d}{t:use/%ju}{]:} ", -wid_pksent, (uintmax_t )kread_counter((u_long )rt->rt_pksent)); if (rt->rt_mtu != 0) - printf("%*lu ", wid_mtu, rt->rt_mtu); + xo_emit("{t:mtu/%*lu} ", wid_mtu, rt->rt_mtu); else - printf("%*s ", wid_mtu, ""); + xo_emit("{P:/%*s} ", wid_mtu, ""); } if (rt->rt_ifp) { if (rt->rt_ifp != lastif) { @@ -852,18 +945,19 @@ p_rtentry_kvm(struct rtentry *rt) strlcpy(prettyname, "---", sizeof(prettyname)); lastif = rt->rt_ifp; } - printf("%*.*s", wid_if, wid_if, prettyname); + xo_emit("{t:interface-name/%*.*s}", wid_if, wid_if, prettyname); if (rt->rt_expire) { time_t expire_time; if ((expire_time = rt->rt_expire - uptime.tv_sec) > 0) - printf(" %*d", wid_expire, (int)expire_time); + xo_emit(" {:expire-time/%*d}", + wid_expire, (int)expire_time); } if (rt->rt_nodes[0].rn_dupedkey) - printf(" =>"); + xo_emit(" =>"); } - putchar('\n'); + xo_emit("\n"); } char * @@ -1022,7 +1116,7 @@ netname6(struct sockaddr_in6 *sa6, struct in6_addr *mask) } } if (illegal) - fprintf(stderr, "illegal prefixlen\n"); + xo_error("illegal prefixlen\n"); } else masklen = 128; @@ -1077,28 +1171,34 @@ rt_stats(void) kresolve_list(rl); if ((rtsaddr = rl[N_RTSTAT].n_value) == 0) { - printf("rtstat: symbol not in namelist\n"); + xo_emit("{W:rtstat: symbol not in namelist}\n"); return; } if ((rttaddr = rl[N_RTTRASH].n_value) == 0) { - printf("rttrash: symbol not in namelist\n"); + xo_emit("{W:rttrash: symbol not in namelist}\n"); return; } kread(rtsaddr, (char *)&rtstat, sizeof (rtstat)); kread(rttaddr, (char *)&rttrash, sizeof (rttrash)); - printf("routing:\n"); + xo_emit("{T:routing}:\n"); #define p(f, m) if (rtstat.f || sflag <= 1) \ - printf(m, rtstat.f, plural(rtstat.f)) - - p(rts_badredirect, "\t%hu bad routing redirect%s\n"); - p(rts_dynamic, "\t%hu dynamically created route%s\n"); - p(rts_newgateway, "\t%hu new gateway%s due to redirects\n"); - p(rts_unreach, "\t%hu destination%s found unreachable\n"); - p(rts_wildcard, "\t%hu use%s of a wildcard route\n"); + xo_emit(m, rtstat.f, plural(rtstat.f)) + + p(rts_badredirect, "\t{:bad-redirects/%hu} " + "{N:/bad routing redirect%s}\n"); + p(rts_dynamic, "\t{:dynamically-created/%hu} " + "{N:/dynamically created route%s}\n"); + p(rts_newgateway, "\t{:new-gateways/%hu} " + "{N:/new gateway%s due to redirects}\n"); + p(rts_unreach, "\t{:unreachable-destination/%hu} " + "{N:/destination%s found unreachable}\n"); + p(rts_wildcard, "\t{:wildcard-uses/%hu} " + "{N:/use%s of a wildcard route}\n"); #undef p if (rttrash || sflag <= 1) - printf("\t%u route%s not in table but not freed\n", + xo_emit("\t{:unused-but-not-freed/%u} " + "{N:/route%s not in table but not freed}\n", rttrash, plural(rttrash)); } |