Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153850521
D21568.id62409.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D21568.id62409.diff
View Options
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -3549,6 +3549,7 @@
gdb/gdb_cons.c optional gdb
gdb/gdb_main.c optional gdb
gdb/gdb_packet.c optional gdb
+gdb/netgdb.c optional ddb debugnet gdb inet
geom/bde/g_bde.c optional geom_bde
geom/bde/g_bde_crypt.c optional geom_bde
geom/bde/g_bde_lock.c optional geom_bde
Index: sys/gdb/gdb.h
===================================================================
--- sys/gdb/gdb.h
+++ sys/gdb/gdb.h
@@ -46,6 +46,7 @@
gdb_putc_f *gdb_putc;
gdb_term_f *gdb_term;
int gdb_active;
+ void (*gdb_sendpacket)(const void *, size_t);
};
#define GDB_DBGPORT(name, probe, init, term, getc, putc) \
Index: sys/gdb/gdb_packet.c
===================================================================
--- sys/gdb/gdb_packet.c
+++ sys/gdb/gdb_packet.c
@@ -45,7 +45,27 @@
static char gdb_rxbuf[GDB_BUFSZ];
char *gdb_rxp = NULL;
size_t gdb_rxsz = 0;
-static char gdb_txbuf[GDB_BUFSZ];
+
+/*
+ * The goal here is to allow in-place framing without making the math around
+ * 'gdb_txbuf' more complicated. A generous reading of union special rule for
+ * "common initial sequence" suggests this may be valid in standard C99 and
+ * later.
+ */
+static union {
+ struct _midbuf {
+ char mb_pad1;
+ char mb_buf[GDB_BUFSZ];
+ char mb_pad2[4];
+ } __packed txu_midbuf;
+ /* sizeof includes trailing nul byte and this is intentional. */
+ char txu_fullbuf[GDB_BUFSZ + sizeof("$#..")];
+} gdb_tx_u;
+#define gdb_txbuf gdb_tx_u.txu_midbuf.mb_buf
+#define gdb_tx_fullbuf gdb_tx_u.txu_fullbuf
+_Static_assert(sizeof(gdb_tx_u.txu_midbuf) == sizeof(gdb_tx_u.txu_fullbuf) &&
+ offsetof(struct _midbuf, mb_buf) == 1,
+ "assertions necessary for correctness");
char *gdb_txp = NULL; /* Used in inline functions. */
#define C2N(c) (((c) < 'A') ? (c) - '0' : \
@@ -218,6 +238,29 @@
gdb_tx_char(tp);
}
+/*
+ * Take raw packet buffer and perform typical GDB packet framing, but not run-
+ * length encoding, before forwarding to driver ::gdb_sendpacket() routine.
+ */
+static void
+gdb_tx_sendpacket(void)
+{
+ size_t msglen, i;
+ unsigned char csum;
+
+ msglen = gdb_txp - gdb_txbuf;
+
+ /* Add GDB packet framing */
+ gdb_tx_fullbuf[0] = '$';
+
+ csum = 0;
+ for (i = 0; i < msglen; i++)
+ csum += (unsigned char)gdb_txbuf[i];
+ snprintf(&gdb_tx_fullbuf[1 + msglen], 4, "#%02x", (unsigned)csum);
+
+ gdb_cur->gdb_sendpacket(gdb_tx_fullbuf, msglen + 4);
+}
+
int
gdb_tx_end(void)
{
@@ -226,6 +269,11 @@
unsigned char c, cksum;
do {
+ if (gdb_cur->gdb_sendpacket != NULL) {
+ gdb_tx_sendpacket();
+ goto getack;
+ }
+
gdb_cur->gdb_putc('$');
cksum = 0;
@@ -284,6 +332,7 @@
c = cksum & 0x0f;
gdb_cur->gdb_putc(N2C(c));
+getack:
c = gdb_getc();
} while (c != '+');
Index: sys/gdb/netgdb.h
===================================================================
--- /dev/null
+++ sys/gdb/netgdb.h
@@ -0,0 +1,44 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2019 Isilon Systems, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#pragma once
+
+/*
+ * Protocol information, for use by the userspace proxy server.
+ *
+ * It might make sense to allow not hardcoding these parameters as future work
+ * (e.g., for use in environments with arbitrary port filtering).
+ *
+ * The herald port is only used for initial handshake. The proxy server will
+ * choose a different remote port to connect back to the NetGDB client on by
+ * sending the HERALD ACK from that other port.
+ */
+#define NETGDB_HERALDPORT 20025
+#define NETGDB_CLIENTPORT 20026
+
+#define NETGDB_PROTO_V1 0x2515f095 /* Rolled a 2^32 sided die. */
Index: sys/gdb/netgdb.c
===================================================================
--- /dev/null
+++ sys/gdb/netgdb.c
@@ -0,0 +1,391 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2019 Isilon Systems, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * netgdb.c
+ * FreeBSD subsystem supporting debugging the FreeBSD kernel over the network.
+ *
+ * There are three pieces necessary to use NetGDB.
+ *
+ * First, a dedicated proxy server must be running to accept connections from
+ * both NetGDB and gdb(1), and pass bidirectional traffic between the two
+ * protocols.
+ *
+ * Second, The NetGDB client is activated much like ordinary 'gdb' and
+ * similarly to 'netdump' in ddb(4). Like other debugnet(4) clients
+ * (netdump(4)), the network interface on the route to the proxy server must be
+ * online and support debugnet(4).
+ *
+ * Finally, the remote (k)gdb(1) uses 'target remote <proxy>:<port>' to connect
+ * to the proxy server.
+ *
+ * NetGDBv1 speaks the literal GDB remote serial protocol, and uses a 1:1
+ * relationship between GDB packets and plain debugnet packets. There is no
+ * encryption utilized to keep debugging sessions private, so this is only
+ * appropriate for local segments or trusted networks.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ddb.h"
+#ifndef DDB
+#error "NetGDB cannot be used without DDB at this time"
+#endif
+
+#include <sys/param.h>
+#include <sys/kdb.h>
+#include <sys/sbuf.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/ttydefaults.h>
+
+#include <machine/gdb_machdep.h>
+
+#ifdef DDB
+#include <ddb/ddb.h>
+#include <ddb/db_command.h>
+#include <ddb/db_lex.h>
+#endif
+
+#include <net/debugnet.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/route.h>
+
+#include <gdb/gdb.h>
+#include <gdb/gdb_int.h>
+#include <gdb/netgdb.h>
+
+FEATURE(netgdb, "NetGDB support");
+SYSCTL_NODE(_debug_gdb, OID_AUTO, netgdb, CTLFLAG_RD, NULL,
+ "NetGDB parameters");
+
+static unsigned netgdb_debug;
+SYSCTL_UINT(_debug_gdb_netgdb, OID_AUTO, debug, CTLFLAG_RWTUN,
+ &netgdb_debug, 0,
+ "Debug message verbosity (0: off; 1: on)");
+
+#define NETGDB_DEBUG(f, ...) do { \
+ if (netgdb_debug > 0) \
+ printf(("%s [%s:%d]: " f), __func__, __FILE__, __LINE__, ## \
+ __VA_ARGS__); \
+} while (false)
+
+static void netgdb_fini(void);
+
+/* Runtime state. */
+static char netgdb_rxbuf[GDB_BUFSZ + 16]; /* Some overhead for framing. */
+static struct sbuf netgdb_rxsb;
+static ssize_t netgdb_rx_off;
+
+static struct debugnet_pcb *netgdb_conn;
+static struct gdb_dbgport *netgdb_prev_dbgport;
+static int *netgdb_prev_kdb_inactive;
+
+/* TODO(CEM) disable ack mode */
+
+/*
+ * Receive non-TX ACK packets on the client port.
+ *
+ * The mbuf chain will have all non-debugnet framing headers removed
+ * (ethernet, inet, udp). It will start with a debugnet_msg_hdr, of
+ * which the header is guaranteed to be contiguous. If m_pullup is
+ * used, the supplied in-out mbuf pointer should be updated
+ * appropriately.
+ *
+ * If the handler frees the mbuf chain, it should set the mbuf pointer
+ * to NULL. Otherwise, the debugnet input framework will free the
+ * chain.
+ */
+static void
+netgdb_rx(struct debugnet_pcb *pcb, struct mbuf **mb)
+{
+ const struct debugnet_msg_hdr *dnh;
+ struct mbuf *m;
+ uint32_t rlen, count;
+ int error;
+
+ m = *mb;
+ dnh = mtod(m, const void *);
+
+ if (ntohl(dnh->mh_type) == DEBUGNET_FINISHED) {
+ sbuf_putc(&netgdb_rxsb, CTRL('C'));
+ return;
+ }
+
+ if (ntohl(dnh->mh_type) != DEBUGNET_DATA) {
+ printf("%s: Got unexpected debugnet message %u\n",
+ __func__, ntohl(dnh->mh_type));
+ return;
+ }
+
+ rlen = ntohl(dnh->mh_len);
+#define _SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len + 1))
+ if (_SBUF_FREESPACE(&netgdb_rxsb) < rlen) {
+ NETGDB_DEBUG("Backpressure: Not ACKing RX of packet that "
+ "would overflow our buffer (%zd/%zd used).\n",
+ netgdb_rxsb.s_len, netgdb_rxsb.s_size);
+ return;
+ }
+#undef _SBUF_FREESPACE
+
+ error = debugnet_ack_output(pcb, dnh->mh_seqno);
+ if (error != 0) {
+ printf("%s: Couldn't ACK rx packet %u; %d\n", __func__,
+ ntohl(dnh->mh_seqno), error);
+ /*
+ * Sender will re-xmit, and assuming the condition is
+ * transient, we'll process the packet's contentss later.
+ */
+ return;
+ }
+
+ m_adj(m, sizeof(*dnh));
+ dnh = NULL;
+
+ /*
+ * Inlined m_apply -- why isn't there a macro or inline function
+ * version?
+ */
+ while (m != NULL && m->m_len == 0)
+ m = m->m_next;
+ while (rlen > 0) {
+ MPASS(m != NULL && m->m_len >= 0);
+ count = min((uint32_t)m->m_len, rlen);
+ (void)sbuf_bcat(&netgdb_rxsb, mtod(m, const void *), count);
+ rlen -= count;
+ m = m->m_next;
+ }
+}
+
+/*
+ * The following routines implement a pseudo GDB debugport (an emulated serial
+ * driver that the MI gdb(4) code does I/O with).
+ */
+
+static int
+netgdb_dbg_getc(void)
+{
+ int c;
+
+ while (true) {
+ /* Pull bytes off any currently cached packet first. */
+ if (netgdb_rx_off < sbuf_len(&netgdb_rxsb)) {
+ c = netgdb_rxsb.s_buf[netgdb_rx_off];
+ netgdb_rx_off++;
+ break;
+ }
+
+ /* Reached EOF? Reuse buffer. */
+ sbuf_clear(&netgdb_rxsb);
+ netgdb_rx_off = 0;
+
+ /* Check for CTRL-C on console/serial, if any. */
+ if (netgdb_prev_dbgport != NULL) {
+ c = netgdb_prev_dbgport->gdb_getc();
+ if (c == CTRL('C'))
+ break;
+ }
+
+ debugnet_network_poll(netgdb_conn);
+ }
+
+ if (c == CTRL('C')) {
+ netgdb_fini();
+ /* Caller gdb_getc() will print that we got ^C. */
+ }
+ return (c);
+}
+
+static void
+netgdb_dbg_sendpacket(const void *buf, size_t len)
+{
+ struct debugnet_proto_aux aux;
+ int error;
+
+ MPASS(len <= UINT32_MAX);
+
+ /*
+ * GDB packet boundaries matter. debugnet_send() fragments a single
+ * request into many sequential debugnet messages. Mark full packet
+ * length and offset for potential reassembly by the proxy.
+ */
+ aux = (struct debugnet_proto_aux) {
+ .dp_aux2 = len,
+ .dp_aux1_add_sent = true,
+ };
+
+ error = debugnet_send(netgdb_conn, DEBUGNET_DATA, buf, len, &aux);
+ if (error != 0) {
+ printf("%s: Network error: %d; trying to switch back to ddb.\n",
+ __func__, error);
+ netgdb_fini();
+
+ if (kdb_dbbe_select("ddb") != 0)
+ printf("The ddb backend could not be selected.\n");
+ else {
+ printf("using longjmp, hope it works!\n");
+ kdb_reenter();
+ }
+ }
+
+}
+
+/* Just used for + / - GDB-level ACKs. */
+static void
+netgdb_dbg_putc(int i)
+{
+ char c;
+
+ c = i;
+ netgdb_dbg_sendpacket(&c, 1);
+
+}
+
+static struct gdb_dbgport netgdb_gdb_dbgport = {
+ .gdb_name = "netgdb",
+ .gdb_getc = netgdb_dbg_getc,
+ .gdb_putc = netgdb_dbg_putc,
+ .gdb_sendpacket = netgdb_dbg_sendpacket,
+};
+
+static void
+netgdb_init(void)
+{
+ struct kdb_dbbe *be, **iter;
+
+ /*
+ * Force enable GDB. (If no other debugports were registered at boot,
+ * KDB thinks it doesn't exist.)
+ */
+ SET_FOREACH(iter, kdb_dbbe_set) {
+ be = *iter;
+ if (strcmp(be->dbbe_name, "gdb") != 0)
+ continue;
+ if (be->dbbe_active == -1) {
+ netgdb_prev_kdb_inactive = &be->dbbe_active;
+ be->dbbe_active = 0;
+ }
+ break;
+ }
+
+ /* Force netgdb debugport. */
+ netgdb_prev_dbgport = gdb_cur;
+ gdb_cur = &netgdb_gdb_dbgport;
+
+ sbuf_new(&netgdb_rxsb, netgdb_rxbuf, sizeof(netgdb_rxbuf),
+ SBUF_FIXEDLEN);
+ netgdb_rx_off = 0;
+}
+
+static void
+netgdb_fini(void)
+{
+
+ /* TODO: tear down conn gracefully? */
+ debugnet_free(netgdb_conn);
+ netgdb_conn = NULL;
+
+ sbuf_delete(&netgdb_rxsb);
+
+ gdb_cur = netgdb_prev_dbgport;
+
+ if (netgdb_prev_kdb_inactive != NULL) {
+ *netgdb_prev_kdb_inactive = -1;
+ netgdb_prev_kdb_inactive = NULL;
+ }
+}
+
+#ifdef DDB
+/*
+ * Usage: netgdb -s <server> [-g <gateway -c <localip> -i <interface>]
+ *
+ * Order is not significant.
+ *
+ * Currently, this command does not support configuring encryption or
+ * compression.
+ */
+DB_FUNC(netgdb, db_netgdb_cmd, db_cmd_table, CS_OWN, NULL)
+{
+ struct debugnet_ddb_config params;
+ struct debugnet_conn_params dcp;
+ struct debugnet_pcb *pcb;
+ int error;
+
+ if (panicstr == NULL) {
+ /* TODO: This limitation should be removed in future work. */
+ printf("%s: netgdb is currently limited to use only after a "
+ "panic. Sorry.\n", __func__);
+ return;
+ }
+
+ error = debugnet_parse_ddb_cmd("netgdb", ¶ms);
+ if (error != 0) {
+ db_printf("Error configuring netgdb: %d\n", error);
+ return;
+ }
+
+ if (!params.dd_has_client)
+ params.dd_client = INADDR_ANY;
+ if (!params.dd_has_gateway)
+ params.dd_gateway = INADDR_ANY;
+
+ dcp = (struct debugnet_conn_params) {
+ .dc_ifp = params.dd_ifp,
+ .dc_client = params.dd_client,
+ .dc_server = params.dd_server,
+ .dc_gateway = params.dd_gateway,
+ .dc_herald_port = NETGDB_HERALDPORT,
+ .dc_client_port = NETGDB_CLIENTPORT,
+ .dc_herald_aux2 = NETGDB_PROTO_V1,
+ .dc_rx_handler = netgdb_rx,
+ };
+
+ error = debugnet_connect(&dcp, &pcb);
+ if (error != 0) {
+ printf("failed to contact netgdb server: %d\n", error);
+ return;
+ }
+
+ netgdb_conn = pcb;
+ netgdb_init();
+
+ if (kdb_dbbe_select("gdb") != 0) {
+ db_printf("The remote GDB backend could not be selected.\n");
+ netgdb_fini();
+ return;
+ }
+
+ /*
+ * Mark that we are done in the debugger. kdb_trap() should re-enter
+ * with the new backend.
+ */
+ db_cmd_loop_done = 1;
+ db_printf("(ctrl-c will return control to ddb)\n");
+}
+#endif /* DDB */
Index: sys/kern/subr_kdb.c
===================================================================
--- sys/kern/subr_kdb.c
+++ sys/kern/subr_kdb.c
@@ -77,7 +77,6 @@
static int kdb_alt_break_to_debugger = KDB_ALT_BREAK_TO_DEBUGGER;
KDB_BACKEND(null, NULL, NULL, NULL, NULL);
-SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe);
static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS);
static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS);
Index: sys/net/debugnet.h
===================================================================
--- sys/net/debugnet.h
+++ sys/net/debugnet.h
@@ -107,6 +107,14 @@
const void *dc_herald_data;
uint32_t dc_herald_datalen;
+ /*
+ * Consistent with debugnet_send(), aux paramaters to debugnet
+ * functions are provided host-endian (but converted to
+ * network endian on the wire).
+ */
+ uint32_t dc_herald_aux2;
+ uint64_t dc_herald_aux1;
+
/*
* If NULL, debugnet is a unidirectional channel from panic machine to
* remote server (like netdump).
@@ -123,12 +131,14 @@
* If the handler frees the mbuf chain, it should set the mbuf pointer
* to NULL. Otherwise, the debugnet input framework will free the
* chain.
+ *
+ * The handler should ACK receieved packets with debugnet_ack_output.
*/
void (*dc_rx_handler)(struct debugnet_pcb *, struct mbuf **);
};
/*
- * Open a unidirectional stream to the specified server's herald port.
+ * Open a stream to the specified server's herald port.
*
* If all goes well, the server will send ACK from a different port to our ack
* port. This allows servers to somewhat gracefully handle multiple debugnet
@@ -158,9 +168,9 @@
* - if auxdata is NULL, mh_aux1 and mh_aux2 will have zero values
* otherwise, auxdata->dp_aux1 and auxdata->dp_aux2 translate directly into
* the header fields.
- * - for netdump, the flag 'dp_aux1_add_sent' can be used to indicate that
- * sends broken into multiple packets should track the in-send offset and
- * add that to the initial aux1 for each packet.
+ * - the flag 'dp_aux1_add_sent' can be used to indicate that sends broken
+ * into multiple packets should track the in-send offset and add that to
+ * the initial aux1 for each packet.
*
* Returns zero on success, or an errno on failure.
*/
@@ -181,6 +191,16 @@
return (debugnet_send(pcb, mhtype, NULL, 0, NULL));
}
+/*
+ * Full-duplex RX should ACK received messages.
+ */
+int debugnet_ack_output(struct debugnet_pcb *, uint32_t seqno /*net endian*/);
+
+/*
+ * Check and/or wait for further packets.
+ */
+void debugnet_network_poll(struct debugnet_pcb *);
+
/*
* PCB accessors.
*/
Index: sys/net/debugnet.c
===================================================================
--- sys/net/debugnet.c
+++ sys/net/debugnet.c
@@ -183,7 +183,7 @@
return (debugnet_ip_output(pcb, m));
}
-static int
+int
debugnet_ack_output(struct debugnet_pcb *pcb, uint32_t seqno /* net endian */)
{
struct debugnet_ack *dn_ack;
@@ -333,7 +333,7 @@
printf(". ");
goto retransmit;
}
- debugnet_network_poll(pcb->dp_ifp);
+ debugnet_network_poll(pcb);
DELAY(500);
if (pcb->dp_state == DN_STATE_REMOTE_CLOSED)
return (ECONNRESET);
@@ -580,8 +580,11 @@
* driver directly for packets.
*/
void
-debugnet_network_poll(struct ifnet *ifp)
+debugnet_network_poll(struct debugnet_pcb *pcb)
{
+ struct ifnet *ifp;
+
+ ifp = pcb->dp_ifp;
ifp->if_debugnet_methods->dn_poll(ifp, 1000);
}
@@ -613,6 +616,7 @@
debugnet_connect(const struct debugnet_conn_params *dcp,
struct debugnet_pcb **pcb_out)
{
+ struct debugnet_proto_aux herald_auxdata;
struct debugnet_pcb *pcb;
struct ifnet *ifp;
int error;
@@ -741,8 +745,12 @@
}
MPASS(pcb->dp_state == DN_STATE_HAVE_GW_MAC);
+ herald_auxdata = (struct debugnet_proto_aux) {
+ .dp_aux1 = dcp->dc_herald_aux1,
+ .dp_aux2 = dcp->dc_herald_aux2,
+ };
error = debugnet_send(pcb, DEBUGNET_HERALD, dcp->dc_herald_data,
- dcp->dc_herald_datalen, NULL);
+ dcp->dc_herald_datalen, &herald_auxdata);
if (error != 0) {
printf("%s: failed to herald debugnet server\n", __func__);
goto cleanup;
Index: sys/net/debugnet_inet.c
===================================================================
--- sys/net/debugnet_inet.c
+++ sys/net/debugnet_inet.c
@@ -407,7 +407,7 @@
return (error);
for (polls = 0; polls < debugnet_npolls &&
pcb->dp_state < DN_STATE_HAVE_GW_MAC; polls++) {
- debugnet_network_poll(pcb->dp_ifp);
+ debugnet_network_poll(pcb);
DELAY(500);
}
if (pcb->dp_state >= DN_STATE_HAVE_GW_MAC)
Index: sys/net/debugnet_int.h
===================================================================
--- sys/net/debugnet_int.h
+++ sys/net/debugnet_int.h
@@ -87,7 +87,6 @@
int debugnet_ether_output(struct mbuf *, struct ifnet *, struct ether_addr,
u_short);
void debugnet_handle_udp(struct debugnet_pcb *, struct mbuf **);
-void debugnet_network_poll(struct ifnet *);
#ifdef INET
int debugnet_arp_gw(struct debugnet_pcb *);
Index: sys/sys/kdb.h
===================================================================
--- sys/sys/kdb.h
+++ sys/sys/kdb.h
@@ -31,6 +31,7 @@
#ifndef _SYS_KDB_H_
#define _SYS_KDB_H_
+#include <sys/linker_set.h>
#include <machine/setjmp.h>
struct pcb;
@@ -61,6 +62,8 @@
}; \
DATA_SET(kdb_dbbe_set, name##_dbbe)
+SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe);
+
extern u_char kdb_active; /* Non-zero while in debugger. */
extern int debugger_on_trap; /* enter the debugger on trap. */
extern struct kdb_dbbe *kdb_dbbe; /* Default debugger backend or NULL. */
Index: sys/sys/param.h
===================================================================
--- sys/sys/param.h
+++ sys/sys/param.h
@@ -60,7 +60,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1300999 /* Master, propagated to newvers */
+#define __FreeBSD_version 1301999 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 25, 6:15 AM (22 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32113341
Default Alt Text
D21568.id62409.diff (21 KB)
Attached To
Mode
D21568: Implement NetGDB(4)
Attached
Detach File
Event Timeline
Log In to Comment