Changeset View
Changeset View
Standalone View
Standalone View
sys/net/debugnet.h
- This file was added.
/*- | |||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||||
* | |||||
* Copyright (c) 2019 Isilon Systems, LLC. | |||||
* Copyright (c) 2005-2014 Sandvine Incorporated | |||||
* Copyright (c) 2000 Darrell Anderson <anderson@cs.duke.edu> | |||||
* All rights reserved. | |||||
* | |||||
* 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$ | |||||
*/ | |||||
/* | |||||
* Debugnet provides a reliable, bidirectional, UDP-encapsulated datagram | |||||
* transport while a machine is in a debug state. (N-1 CPUs stopped, | |||||
* interrupts disabled, may or may not be in a panic(9) state.) Only one | |||||
* stream may be active at a time. A dedicated server must be running to | |||||
* accept connections. | |||||
*/ | |||||
#pragma once | |||||
#include <sys/types.h> | |||||
#include <netinet/in.h> | |||||
/* | |||||
* Debugnet protocol details. | |||||
*/ | |||||
#define DEBUGNET_HERALD 1 /* Connection handshake. */ | |||||
#define DEBUGNET_FINISHED 2 /* Close the connection. */ | |||||
#define DEBUGNET_DATA 3 /* Contains data. */ | |||||
struct debugnet_msg_hdr { | |||||
uint32_t mh_type; /* Debugnet message type. */ | |||||
uint32_t mh_seqno; /* Match acks with msgs. */ | |||||
uint64_t mh_offset; /* Offset in fragment. */ | |||||
uint32_t mh_len; /* Attached data (bytes). */ | |||||
uint32_t mh_aux2; /* Consumer-specific. */ | |||||
} __packed; | |||||
struct debugnet_ack { | |||||
uint32_t da_seqno; /* Match acks with msgs. */ | |||||
} __packed; | |||||
#define DEBUGNET_MAX_IN_FLIGHT 64 | |||||
#ifdef _KERNEL | |||||
/* | |||||
* Hook API for network drivers. | |||||
*/ | |||||
enum debugnet_ev { | |||||
DEBUGNET_START, | |||||
DEBUGNET_END, | |||||
}; | |||||
struct ifnet; | |||||
struct mbuf; | |||||
typedef void debugnet_init_t(struct ifnet *, int *nrxr, int *ncl, int *clsize); | |||||
typedef void debugnet_event_t(struct ifnet *, enum debugnet_ev); | |||||
typedef int debugnet_transmit_t(struct ifnet *, struct mbuf *); | |||||
typedef int debugnet_poll_t(struct ifnet *, int); | |||||
struct debugnet_methods { | |||||
debugnet_init_t *dn_init; | |||||
debugnet_event_t *dn_event; | |||||
debugnet_transmit_t *dn_transmit; | |||||
debugnet_poll_t *dn_poll; | |||||
}; | |||||
#define DEBUGNET_SUPPORTED_NIC(ifp) \ | |||||
((ifp)->if_debugnet_methods != NULL && (ifp)->if_type == IFT_ETHER) | |||||
/* | |||||
* Debugnet consumer API. | |||||
*/ | |||||
struct debugnet_conn_params { | |||||
struct ifnet *dc_ifp; | |||||
in_addr_t dc_client; | |||||
in_addr_t dc_server; | |||||
in_addr_t dc_gateway; | |||||
uint16_t dc_herald_port; | |||||
uint16_t dc_client_ack_port; | |||||
const void *dc_herald_data; | |||||
uint32_t dc_herald_datalen; | |||||
}; | |||||
struct debugnet_pcb; /* opaque */ | |||||
/* | |||||
* Open a unidirectional 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 | |||||
* clients. (Clients are limited to single connections.) | |||||
* | |||||
* Returns zero on success, or errno. | |||||
*/ | |||||
int debugnet_connect(const struct debugnet_conn_params *, | |||||
struct debugnet_pcb **pcb_out); | |||||
/* | |||||
* Free a debugnet stream that was previously successfully opened. | |||||
* | |||||
* No attempt is made to cleanly terminate communication with the remote | |||||
* server. Consumers should first send an empty DEBUGNET_FINISHED message, or | |||||
* otherwise let the remote know they are signing off. | |||||
*/ | |||||
void debugnet_free(struct debugnet_pcb *); | |||||
/* | |||||
* Send a message, with common debugnet_msg_hdr header, to the connected remote | |||||
* server. | |||||
* | |||||
* - mhtype translates directly to mh_type (e.g., DEBUGNET_DATA, or some other | |||||
* protocol-specific type). | |||||
* - Data and datalen describe the attached data; datalen may be zero. | |||||
* - If auxdata is NULL, mh_offset's initial value and mh_aux2 will be zero. | |||||
* Otherwise, mh_offset's initial value will be auxdata->dp_offset_start and | |||||
* mh_aux2 will have the value of auxdata->dp_aux2. | |||||
* | |||||
* Returns zero on success, or an errno on failure. | |||||
*/ | |||||
struct debugnet_proto_aux { | |||||
markj: The indentation here is off. | |||||
Done Inline ActionsIt isn't, or rather, this is intentional. It's a nested bullet point. cem: It isn't, or rather, this is intentional. It's a nested bullet point. | |||||
uint64_t dp_offset_start; | |||||
uint32_t dp_aux2; | |||||
}; | |||||
int debugnet_send(struct debugnet_pcb *, uint32_t mhtype, const void *data, | |||||
uint32_t datalen, const struct debugnet_proto_aux *auxdata); | |||||
/* | |||||
* A simple wrapper around the above when no data or auxdata is needed. | |||||
*/ | |||||
static inline int | |||||
debugnet_sendempty(struct debugnet_pcb *pcb, uint32_t mhtype) | |||||
{ | |||||
return (debugnet_send(pcb, mhtype, NULL, 0, NULL)); | |||||
} | |||||
/* | |||||
* PCB accessors. | |||||
*/ | |||||
/* | |||||
* Get the 48-bit MAC address of the discovered next hop (gateway, or | |||||
* destination server if it is on the same segment. | |||||
*/ | |||||
const unsigned char *debugnet_get_gw_mac(const struct debugnet_pcb *); | |||||
/* | |||||
* Callbacks from core mbuf code. | |||||
*/ | |||||
void debugnet_any_ifnet_update(struct ifnet *); | |||||
/* Expose sysctl variables for netdump(4) to alias. */ | |||||
extern int debugnet_npolls; | |||||
extern int debugnet_nretries; | |||||
extern int debugnet_arp_nretries; | |||||
/* | |||||
* Conditionally-defined macros for device drivers so we can avoid ifdef | |||||
* wrappers in every single implementation. | |||||
*/ | |||||
#ifdef DEBUGNET | |||||
#define DEBUGNET_DEFINE(driver) \ | |||||
static debugnet_init_t driver##_debugnet_init; \ | |||||
static debugnet_event_t driver##_debugnet_event; \ | |||||
static debugnet_transmit_t driver##_debugnet_transmit; \ | |||||
static debugnet_poll_t driver##_debugnet_poll; \ | |||||
\ | |||||
static struct debugnet_methods driver##_debugnet_methods = { \ | |||||
.dn_init = driver##_debugnet_init, \ | |||||
.dn_event = driver##_debugnet_event, \ | |||||
.dn_transmit = driver##_debugnet_transmit, \ | |||||
.dn_poll = driver##_debugnet_poll, \ | |||||
} | |||||
#define DEBUGNET_NOTIFY_MTU(ifp) debugnet_any_ifnet_update(ifp) | |||||
#define DEBUGNET_SET(ifp, driver) \ | |||||
(ifp)->if_debugnet_methods = &driver##_debugnet_methods | |||||
#else /* !DEBUGNET || !INET */ | |||||
#define DEBUGNET_DEFINE(driver) | |||||
#define DEBUGNET_NOTIFY_MTU(ifp) | |||||
#define DEBUGNET_SET(ifp, driver) | |||||
#endif /* DEBUGNET && INET */ | |||||
#endif /* _KERNEL */ |
The indentation here is off.