Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137701628
D21482.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D21482.diff
View Options
Index: head/share/man/man4/ddb.4
===================================================================
--- head/share/man/man4/ddb.4
+++ head/share/man/man4/ddb.4
@@ -1192,7 +1192,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: head/sys/net/debugnet.h
===================================================================
--- head/sys/net/debugnet.h
+++ head/sys/net/debugnet.h
@@ -176,11 +176,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.
*
@@ -191,6 +192,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: head/sys/net/debugnet.c
===================================================================
--- head/sys/net/debugnet.c
+++ head/sys/net/debugnet.c
@@ -491,8 +491,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;
@@ -527,8 +531,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
@@ -842,37 +925,21 @@
t = db_read_token_flags(DRT_WSPACE);
}
- /* 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: head/sys/net/debugnet_int.h
===================================================================
--- head/sys/net/debugnet_int.h
+++ head/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: head/sys/netinet/netdump/netdump_client.c
===================================================================
--- head/sys/netinet/netdump/netdump_client.c
+++ head/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,14 +158,23 @@
&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
netdump_enabled_sysctl(SYSCTL_HANDLER_ARGS)
{
@@ -296,10 +305,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;
@@ -369,14 +374,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);
@@ -406,32 +413,25 @@
NETDUMP_ASSERT_WLOCKED();
- if (td != NULL)
- vnet = TD_TO_VNET(td);
- else
- vnet = vnet0;
- CURVNET_SET(vnet);
- if (td != NULL && !IS_DEFAULT_VNET(curvnet)) {
+ if (conf->kda_iface[0] != 0) {
+ if (td != NULL)
+ vnet = TD_TO_VNET(td);
+ else
+ vnet = vnet0;
+ CURVNET_SET(vnet);
+ if (td != NULL && !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();
+ } else
+ ifp = NULL;
- 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);
- }
-
- 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) == \
@@ -527,8 +527,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,
@@ -549,8 +550,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));
@@ -776,11 +778,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
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 26, 12:09 AM (3 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26193208
Default Alt Text
D21482.diff (10 KB)
Attached To
Mode
D21482: debugnet(4): Infer non-server connection parameters
Attached
Detach File
Event Timeline
Log In to Comment