Author: cem
Date: Mon Sep 9 22:54:27 2019
New Revision: 352112
URL: https://svnweb.freebsd.org/changeset/base/352112
Log:
ddb(4): Add 'show route ' and 'show routetable []'
These commands show the route resolved for a specified destination, or
print out the entire routing table for a given address family (or all
families, if none is explicitly provided).
Discussed with: emaste
Differential Revision:https://reviews.freebsd.org/D21510
Modified:
head/share/man/man4/ddb.4
head/sys/net/rtsock.c
Modified: head/share/man/man4/ddb.4
==
--- head/share/man/man4/ddb.4 Mon Sep 9 22:08:22 2019(r352111)
+++ head/share/man/man4/ddb.4 Mon Sep 9 22:54:27 2019(r352112)
@@ -60,7 +60,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 30, 2018
+.Dd September 9, 2019
.Dt DDB 4
.Os
.Sh NAME
@@ -953,6 +953,20 @@ at address
.Ar addr .
Addresses of particular pointers can be gathered with "show allrman"
command.
+.\"
+.Pp
+.It Ic show Cm route Ar addr
+Show route table result for destination
+.Ar addr .
+At this time, INET and INET6 formatted addresses are supported.
+.\"
+.Pp
+.It Ic show Cm routetable Oo Ar af Oc
+Show full route table or tables.
+If
+.Ar af
+is specified, show only routes for the given numeric address family.
+If no argument is specified, dump the route table for all address families.
.\"
.Pp
.It Ic show Cm rtc
Modified: head/sys/net/rtsock.c
==
--- head/sys/net/rtsock.c Mon Sep 9 22:08:22 2019(r352111)
+++ head/sys/net/rtsock.c Mon Sep 9 22:54:27 2019(r352112)
@@ -31,6 +31,7 @@
* @(#)rtsock.c8.7 (Berkeley) 10/12/95
* $FreeBSD$
*/
+#include "opt_ddb.h"
#include "opt_mpath.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -53,6 +54,11 @@
#include
#include
+#ifdef DDB
+#include
+#include
+#endif
+
#include
#include
#include
@@ -1995,3 +2001,404 @@ static struct domain routedomain = {
};
VNET_DOMAIN_SET(route);
+
+#ifdef DDB
+/*
+ * Unfortunately, RTF_ values are expressed as raw masks rather than powers of
+ * 2, so we cannot use them as nice C99 initializer indices below.
+ */
+static const char * const rtf_flag_strings[] = {
+ "UP",
+ "GATEWAY",
+ "HOST",
+ "REJECT",
+ "DYNAMIC",
+ "MODIFIED",
+ "DONE",
+ "UNUSED_0x80",
+ "UNUSED_0x100",
+ "XRESOLVE",
+ "LLDATA",
+ "STATIC",
+ "BLACKHOLE",
+ "UNUSED_0x2000",
+ "PROTO2",
+ "PROTO1",
+ "UNUSED_0x1",
+ "UNUSED_0x2",
+ "PROTO3",
+ "FIXEDMTU",
+ "PINNED",
+ "LOCAL",
+ "BROADCAST",
+ "MULTICAST",
+ /* Big gap. */
+ [28] = "STICKY",
+ [30] = "RNH_LOCKED",
+ [31] = "GWFLAG_COMPAT",
+};
+
+static const char * __pure
+rt_flag_name(unsigned idx)
+{
+ if (idx >= nitems(rtf_flag_strings))
+ return ("INVALID_FLAG");
+ if (rtf_flag_strings[idx] == NULL)
+ return ("UNKNOWN");
+ return (rtf_flag_strings[idx]);
+}
+
+static void
+rt_dumpaddr_ddb(const char *name, const struct sockaddr *sa)
+{
+ char buf[INET6_ADDRSTRLEN], *res;
+
+ res = NULL;
+ if (sa == NULL)
+ res = "NULL";
+ else if (sa->sa_family == AF_INET) {
+ res = inet_ntop(AF_INET,
+ &((const struct sockaddr_in *)sa)->sin_addr,
+ buf, sizeof(buf));
+ } else if (sa->sa_family == AF_INET6) {
+ res = inet_ntop(AF_INET6,
+ &((const struct sockaddr_in6 *)sa)->sin6_addr,
+ buf, sizeof(buf));
+ } else if (sa->sa_family == AF_LINK) {
+ res = "on link";
+ }
+
+ if (res != NULL) {
+ db_printf("%s <%s> ", name, res);
+ return;
+ }
+
+ db_printf("%s ", name, sa->sa_family);
+}
+
+static int
+rt_dumpentry_ddb(struct radix_node *rn, void *arg __unused)
+{
+ struct sockaddr_storage ss;
+ struct rtentry *rt;
+ int flags, idx;
+
+ /* If RNTORT is important, put it in a header. */
+ rt = (void *)rn;
+
+ rt_dumpaddr_ddb("dst", rt_key(rt));
+ rt_dumpaddr_ddb("gateway", rt->rt_gateway);
+ rt_dumpaddr_ddb("netmask", rtsock_fix_netmask(rt_key(rt), rt_mask(rt),
+ ));
+ if (rt->rt_ifp != NULL && (rt->rt_ifp->if_flags & IFF_DYING) == 0) {
+ rt_dumpaddr_ddb("ifp", rt->rt_ifp->if_addr->ifa_addr);
+ rt_dumpaddr_ddb("ifa", rt->rt_ifa->ifa_addr);
+ }
+
+ db_printf("flags ");
+ flags = rt->rt_flags;
+ if (flags == 0)
+ db_printf("none");
+
+ while ((idx = ffs(flags)) > 0) {
+ idx--;
+
+ if (flags != rt->rt_flags)
+ db_printf(",");
+