Page MenuHomeFreeBSD

D21482.id61523.diff
No OneTemporary

D21482.id61523.diff

Index: share/man/man4/ddb.4
===================================================================
--- share/man/man4/ddb.4
+++ share/man/man4/ddb.4
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 30, 2019
+.Dd September 1, 2019
.Dt DDB 4
.Os
.Sh NAME
@@ -1161,7 +1161,7 @@
using the remote debug feature, with a connection to the serial
console port on the target machine.
.Pp
-.It Ic netdump Fl s Ar server Oo Fl g Ar gateway Oc Fl c Ar client Fl i Ar iface
+.It Ic netdump Fl s Ar server Oo Fl g Ar gateway Fl c Ar client Fl i Ar iface Oc
Configure
.Xr netdump 4
with the provided parameters, and immediately perform a netdump.
Index: sys/net/debugnet.h
===================================================================
--- sys/net/debugnet.h
+++ sys/net/debugnet.h
@@ -180,11 +180,12 @@
/*
* DDB parsing helper for common debugnet options.
*
- * -s <server> [-g <gateway] -c <localip> -i <interface>
+ * -s <server> [-g <gateway -c <localip> -i <interface>]
*
* Order is not significant. Interface is an online interface that supports
* debugnet and can route to the debugnet server. The other parameters are all
- * IP addresses. For now, all parameters are mandatory, except gateway.
+ * IP addresses. Only the server parameter is required. The others are
+ * inferred automatically from the routing table, if not explicitly provided.
*
* Provides basic '-h' using provided 'cmd' string.
*
@@ -195,6 +196,7 @@
in_addr_t dd_client;
in_addr_t dd_server;
in_addr_t dd_gateway;
+ bool dd_has_client : 1;
bool dd_has_gateway : 1;
};
int debugnet_parse_ddb_cmd(const char *cmd,
Index: sys/net/debugnet.c
===================================================================
--- sys/net/debugnet.c
+++ sys/net/debugnet.c
@@ -493,8 +493,12 @@
MPASS(pcb == &g_dnet_pcb);
ifp = pcb->dp_ifp;
- ifp->if_input = pcb->dp_drv_input;
- ifp->if_debugnet_methods->dn_event(ifp, DEBUGNET_END);
+ if (ifp != NULL) {
+ if (pcb->dp_drv_input != NULL)
+ ifp->if_input = pcb->dp_drv_input;
+ if (pcb->dp_event_started)
+ ifp->if_debugnet_methods->dn_event(ifp, DEBUGNET_END);
+ }
debugnet_mbuf_finish();
g_debugnet_pcb_inuse = false;
@@ -529,8 +533,87 @@
/* Switch to the debugnet mbuf zones. */
debugnet_mbuf_start();
+ /* At least one needed parameter is missing; infer it. */
+ if (pcb->dp_client == INADDR_ANY || pcb->dp_gateway == INADDR_ANY ||
+ pcb->dp_ifp == NULL) {
+ struct sockaddr_in dest_sin, *gw_sin, *local_sin;
+ struct rtentry *dest_rt;
+ struct ifnet *rt_ifp;
+
+ memset(&dest_sin, 0, sizeof(dest_sin));
+ dest_sin = (struct sockaddr_in) {
+ .sin_len = sizeof(dest_sin),
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = pcb->dp_server,
+ };
+
+ CURVNET_SET(vnet0);
+ dest_rt = rtalloc1((struct sockaddr *)&dest_sin, 0,
+ RTF_RNH_LOCKED);
+ CURVNET_RESTORE();
+
+ if (dest_rt == NULL) {
+ db_printf("%s: Could not get route for that server.\n",
+ __func__);
+ error = ENOENT;
+ goto cleanup;
+ }
+
+ if (dest_rt->rt_gateway->sa_family == AF_INET)
+ gw_sin = (struct sockaddr_in *)dest_rt->rt_gateway;
+ else {
+ if (dest_rt->rt_gateway->sa_family == AF_LINK)
+ DNETDEBUG("Destination address is on link.\n");
+ gw_sin = NULL;
+ }
+
+ MPASS(dest_rt->rt_ifa->ifa_addr->sa_family == AF_INET);
+ local_sin = (struct sockaddr_in *)dest_rt->rt_ifa->ifa_addr;
+
+ rt_ifp = dest_rt->rt_ifp;
+
+ if (pcb->dp_client == INADDR_ANY)
+ pcb->dp_client = local_sin->sin_addr.s_addr;
+ if (pcb->dp_gateway == INADDR_ANY && gw_sin != NULL)
+ pcb->dp_gateway = gw_sin->sin_addr.s_addr;
+ if (pcb->dp_ifp == NULL)
+ pcb->dp_ifp = rt_ifp;
+
+ RTFREE_LOCKED(dest_rt);
+ }
+
ifp = pcb->dp_ifp;
+
+ if (debugnet_debug > 0) {
+ char serbuf[INET_ADDRSTRLEN], clibuf[INET_ADDRSTRLEN],
+ gwbuf[INET_ADDRSTRLEN];
+ inet_ntop(AF_INET, &pcb->dp_server, serbuf, sizeof(serbuf));
+ inet_ntop(AF_INET, &pcb->dp_client, clibuf, sizeof(clibuf));
+ if (pcb->dp_gateway != INADDR_ANY)
+ inet_ntop(AF_INET, &pcb->dp_gateway, gwbuf, sizeof(gwbuf));
+ DNETDEBUG("Connecting to %s:%d%s%s from %s:%d on %s\n",
+ serbuf, pcb->dp_server_port,
+ (pcb->dp_gateway == INADDR_ANY) ? "" : " via ",
+ (pcb->dp_gateway == INADDR_ANY) ? "" : gwbuf,
+ clibuf, pcb->dp_client_ack_port, if_name(ifp));
+ }
+
+ /* Validate iface is online and supported. */
+ if (!DEBUGNET_SUPPORTED_NIC(ifp)) {
+ printf("%s: interface '%s' does not support debugnet\n",
+ __func__, if_name(ifp));
+ error = ENODEV;
+ goto cleanup;
+ }
+ if ((if_getflags(ifp) & IFF_UP) == 0) {
+ printf("%s: interface '%s' link is down\n", __func__,
+ if_name(ifp));
+ error = ENXIO;
+ goto cleanup;
+ }
+
ifp->if_debugnet_methods->dn_event(ifp, DEBUGNET_START);
+ pcb->dp_event_started = true;
/*
* We maintain the invariant that g_debugnet_pcb_inuse is always true
@@ -727,9 +810,6 @@
bool want_ifp;
char ch;
- /* Assume v4, dotted decimal encoding for now. */
- db_cmd_radix = 10;
-
struct my_inet_opt opt_client = {
.printname = "client",
.result = &result->dd_client,
@@ -744,6 +824,8 @@
},
*cur_inet_opt;
+ /* Assume v4, dotted decimal encoding for now. */
+ db_cmd_radix = 10;
ifp = NULL;
memset(result, 0, sizeof(*result));
@@ -847,37 +929,21 @@
t = db_read_token();
}
- /* Currently, all three are required. */
- if (!opt_client.has_opt || !opt_server.has_opt || ifp == NULL) {
- db_printf("%s needs all of client, server, and interface "
- "specified.\n", cmd);
+ if (!opt_server.has_opt) {
+ db_printf("%s: need a destination server address\n", cmd);
goto usage;
}
+ result->dd_has_client = opt_client.has_opt;
result->dd_has_gateway = opt_gateway.has_opt;
-
- /* Iface validation stolen from netdump_configure. */
- if (!DEBUGNET_SUPPORTED_NIC(ifp)) {
- db_printf("%s: interface '%s' does not support debugnet\n",
- cmd, if_name(ifp));
- error = ENODEV;
- goto cleanup;
- }
- if ((if_getflags(ifp) & IFF_UP) == 0) {
- db_printf("%s: interface '%s' link is down\n", cmd,
- if_name(ifp));
- error = ENXIO;
- goto cleanup;
- }
-
result->dd_ifp = ifp;
/* We parsed the full line to tEOL already, or bailed with an error. */
return (0);
usage:
- db_printf("Usage: %s -s <server> [-g <gateway>] -c <localip> "
- "-i <interface>\n", cmd);
+ db_printf("Usage: %s -s <server> [-g <gateway> -c <localip> "
+ "-i <interface>]\n", cmd);
error = EINVAL;
/* FALLTHROUGH */
cleanup:
Index: sys/net/debugnet_int.h
===================================================================
--- sys/net/debugnet_int.h
+++ sys/net/debugnet_int.h
@@ -69,6 +69,7 @@
enum dnet_pcb_st dp_state;
uint16_t dp_client_ack_port;
+ bool dp_event_started;
};
/* TODO(CEM): Obviate this assertion by using a BITSET(9) for acks. */
Index: sys/netinet/netdump/netdump_client.c
===================================================================
--- sys/netinet/netdump/netdump_client.c
+++ sys/netinet/netdump/netdump_client.c
@@ -138,8 +138,8 @@
SYSCTL_INT(_net_netdump, OID_AUTO, debug, CTLFLAG_RWTUN,
&nd_debug, 0,
"Debug message verbosity");
-SYSCTL_PROC(_net_netdump, OID_AUTO, enabled, CTLFLAG_RD | CTLTYPE_INT,
- &nd_ifp, 0, netdump_enabled_sysctl, "I", "netdump configuration status");
+SYSCTL_PROC(_net_netdump, OID_AUTO, enabled, CTLFLAG_RD | CTLTYPE_INT, NULL, 0,
+ netdump_enabled_sysctl, "I", "netdump configuration status");
static char nd_path[MAXPATHLEN];
SYSCTL_STRING(_net_netdump, OID_AUTO, path, CTLFLAG_RW,
nd_path, sizeof(nd_path),
@@ -158,12 +158,21 @@
&debugnet_arp_nretries, 0,
"Number of ARP attempts before giving up");
+static bool nd_is_enabled;
static bool
netdump_enabled(void)
{
NETDUMP_ASSERT_LOCKED();
- return (nd_ifp != NULL);
+ return (nd_is_enabled);
+}
+
+static void
+netdump_set_enabled(bool status)
+{
+
+ NETDUMP_ASSERT_LOCKED();
+ nd_is_enabled = status;
}
static int
@@ -297,10 +306,6 @@
printf("netdump_start: can't netdump; no server IP given\n");
return (EINVAL);
}
- if (nd_client.s_addr == INADDR_ANY) {
- printf("netdump_start: can't netdump; no client IP given\n");
- return (EINVAL);
- }
/* We start dumping at offset 0. */
di->dumpoff = 0;
@@ -370,14 +375,16 @@
struct diocskerneldump_arg kda;
NETDUMP_ASSERT_WLOCKED();
- KASSERT(netdump_enabled(), ("%s: nd_ifp NULL", __func__));
+ KASSERT(netdump_enabled(), ("%s: not enabled", __func__));
bzero(&kda, sizeof(kda));
kda.kda_index = KDA_REMOVE_DEV;
(void)dumper_remove(nd_conf.ndc_iface, &kda);
- if_rele(nd_ifp);
+ if (nd_ifp != NULL)
+ if_rele(nd_ifp);
nd_ifp = NULL;
+ netdump_set_enabled(false);
log(LOG_WARNING, "netdump: Lost configured interface %s\n",
nd_conf.ndc_iface);
@@ -402,28 +409,21 @@
NETDUMP_ASSERT_WLOCKED();
- CURVNET_SET(TD_TO_VNET(td));
- if (!IS_DEFAULT_VNET(curvnet)) {
+ if (conf->kda_iface[0] != 0) {
+ CURVNET_SET(TD_TO_VNET(td));
+ if (!IS_DEFAULT_VNET(curvnet)) {
+ CURVNET_RESTORE();
+ return (EINVAL);
+ }
+ ifp = ifunit_ref(conf->kda_iface);
CURVNET_RESTORE();
- return (EINVAL);
- }
- ifp = ifunit_ref(conf->kda_iface);
- CURVNET_RESTORE();
-
- if (ifp == NULL)
- return (ENOENT);
- if ((if_getflags(ifp) & IFF_UP) == 0) {
- if_rele(ifp);
- return (ENXIO);
- }
- if (!DEBUGNET_SUPPORTED_NIC(ifp)) {
- if_rele(ifp);
- return (ENODEV);
- }
+ } else
+ ifp = NULL;
- if (netdump_enabled())
+ if (nd_ifp != NULL)
if_rele(nd_ifp);
nd_ifp = ifp;
+ netdump_set_enabled(true);
#define COPY_SIZED(elm) do { \
_Static_assert(sizeof(nd_conf.ndc_ ## elm) == \
@@ -519,8 +519,9 @@
break;
}
- strlcpy(conf12->ndc12_iface, nd_ifp->if_xname,
- sizeof(conf12->ndc12_iface));
+ if (nd_ifp != NULL)
+ strlcpy(conf12->ndc12_iface, nd_ifp->if_xname,
+ sizeof(conf12->ndc12_iface));
memcpy(&conf12->ndc12_server, &nd_server,
sizeof(conf12->ndc12_server));
memcpy(&conf12->ndc12_client, &nd_client,
@@ -541,8 +542,9 @@
break;
}
- strlcpy(conf->kda_iface, nd_ifp->if_xname,
- sizeof(conf->kda_iface));
+ if (nd_ifp != NULL)
+ strlcpy(conf->kda_iface, nd_ifp->if_xname,
+ sizeof(conf->kda_iface));
memcpy(&conf->kda_server, &nd_server, sizeof(nd_server));
memcpy(&conf->kda_client, &nd_client, sizeof(nd_client));
memcpy(&conf->kda_gateway, &nd_gateway, sizeof(nd_gateway));
@@ -768,11 +770,17 @@
/* Translate to a netdump dumper config. */
memset(&conf, 0, sizeof(conf));
- strlcpy(conf.kda_iface, if_name(params.dd_ifp), sizeof(conf.kda_iface));
+
+ if (params.dd_ifp != NULL)
+ strlcpy(conf.kda_iface, if_name(params.dd_ifp),
+ sizeof(conf.kda_iface));
conf.kda_af = AF_INET;
conf.kda_server.in4 = (struct in_addr) { params.dd_server };
- conf.kda_client.in4 = (struct in_addr) { params.dd_client };
+ if (params.dd_has_client)
+ conf.kda_client.in4 = (struct in_addr) { params.dd_client };
+ else
+ conf.kda_client.in4 = (struct in_addr) { INADDR_ANY };
if (params.dd_has_gateway)
conf.kda_gateway.in4 = (struct in_addr) { params.dd_gateway };
else

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 10, 4:22 AM (16 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29473347
Default Alt Text
D21482.id61523.diff (10 KB)

Event Timeline