svn commit: r307498 - in stable/11/sys: dev/hyperv/netvsc dev/hyperv/vmbus net
Sepherosa Ziehau
sephe at FreeBSD.org
Mon Oct 17 08:10:26 UTC 2016
Author: sephe
Date: Mon Oct 17 08:10:24 2016
New Revision: 307498
URL: https://svnweb.freebsd.org/changeset/base/307498
Log:
MFC 305405,305407,305408,305410,305411,305453
305405
hyperv/vmbus: Stringent header length and total length check.
While I'm here, minor style changes.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7752
305407
hyperv/hn: Stringent NVS notification length check.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7753
305408
hyperv/hn: Stringent NVS RNDIS packets length checks.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7755
305410
net/rndis: Define RNDIS status message, which could be sent by device.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7757
305411
hyperv/hn: Stringent RNDIS control message length check.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7758
305453
hyperv/hn: Stringent RNDIS packet message length/offset check.
While I'm here, use definition in net/rndis.h
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7782
Modified:
stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c
stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c
stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.h
stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c
stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h
stable/11/sys/net/rndis.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c Mon Oct 17 08:06:19 2016 (r307497)
+++ stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c Mon Oct 17 08:10:24 2016 (r307498)
@@ -742,32 +742,53 @@ hv_nv_on_receive(struct hn_softc *sc, st
{
const struct vmbus_chanpkt_rxbuf *pkt;
const struct hn_nvs_hdr *nvs_hdr;
- int count = 0;
- int i = 0;
+ int count, i, hlen;
- /* Make sure that this is a RNDIS message. */
+ if (__predict_false(VMBUS_CHANPKT_DATALEN(pkthdr) < sizeof(*nvs_hdr))) {
+ if_printf(rxr->hn_ifp, "invalid nvs RNDIS\n");
+ return;
+ }
nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr);
+
+ /* Make sure that this is a RNDIS message. */
if (__predict_false(nvs_hdr->nvs_type != HN_NVS_TYPE_RNDIS)) {
if_printf(rxr->hn_ifp, "nvs type %u, not RNDIS\n",
nvs_hdr->nvs_type);
return;
}
-
+
+ hlen = VMBUS_CHANPKT_GETLEN(pkthdr->cph_hlen);
+ if (__predict_false(hlen < sizeof(*pkt))) {
+ if_printf(rxr->hn_ifp, "invalid rxbuf chanpkt\n");
+ return;
+ }
pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;
- if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
- if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n",
+ if (__predict_false(pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID)) {
+ if_printf(rxr->hn_ifp, "invalid rxbuf_id 0x%08x\n",
pkt->cp_rxbuf_id);
return;
}
count = pkt->cp_rxbuf_cnt;
+ if (__predict_false(hlen <
+ __offsetof(struct vmbus_chanpkt_rxbuf, cp_rxbuf[count]))) {
+ if_printf(rxr->hn_ifp, "invalid rxbuf_cnt %d\n", count);
+ return;
+ }
/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
- for (i = 0; i < count; i++) {
- hv_rf_on_receive(sc, rxr,
- rxr->hn_rxbuf + pkt->cp_rxbuf[i].rb_ofs,
- pkt->cp_rxbuf[i].rb_len);
+ for (i = 0; i < count; ++i) {
+ int ofs, len;
+
+ ofs = pkt->cp_rxbuf[i].rb_ofs;
+ len = pkt->cp_rxbuf[i].rb_len;
+ if (__predict_false(ofs + len > NETVSC_RECEIVE_BUFFER_SIZE)) {
+ if_printf(rxr->hn_ifp, "%dth RNDIS msg overflow rxbuf, "
+ "ofs %d, len %d\n", i, ofs, len);
+ continue;
+ }
+ hv_rf_on_receive(sc, rxr, rxr->hn_rxbuf + ofs, len);
}
/*
@@ -816,7 +837,12 @@ hn_proc_notify(struct hn_softc *sc, cons
{
const struct hn_nvs_hdr *hdr;
+ if (VMBUS_CHANPKT_DATALEN(pkt) < sizeof(*hdr)) {
+ if_printf(sc->hn_ifp, "invalid nvs notify\n");
+ return;
+ }
hdr = VMBUS_CHANPKT_CONST_DATA(pkt);
+
if (hdr->nvs_type == HN_NVS_TYPE_TXTBL_NOTE) {
/* Useless; ignore */
return;
Modified: stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c Mon Oct 17 08:06:19 2016 (r307497)
+++ stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c Mon Oct 17 08:10:24 2016 (r307498)
@@ -72,7 +72,7 @@ __FBSDID("$FreeBSD$");
* Forward declarations
*/
static void hv_rf_receive_indicate_status(struct hn_softc *sc,
- const rndis_msg *response);
+ const void *data, int dlen);
static void hv_rf_receive_data(struct hn_rx_ring *rxr,
const void *data, int dlen);
static int hv_rf_query_device_mac(struct hn_softc *sc, uint8_t *eaddr);
@@ -131,59 +131,50 @@ hv_set_rppi_data(rndis_msg *rndis_mesg,
* RNDIS filter receive indicate status
*/
static void
-hv_rf_receive_indicate_status(struct hn_softc *sc, const rndis_msg *response)
+hv_rf_receive_indicate_status(struct hn_softc *sc, const void *data, int dlen)
{
- const rndis_indicate_status *indicate = &response->msg.indicate_status;
-
- switch(indicate->status) {
+ const struct rndis_status_msg *msg;
+
+ if (dlen < sizeof(*msg)) {
+ if_printf(sc->hn_ifp, "invalid RNDIS status\n");
+ return;
+ }
+ msg = data;
+
+ switch (msg->rm_status) {
case RNDIS_STATUS_MEDIA_CONNECT:
netvsc_linkstatus_callback(sc, 1);
break;
+
case RNDIS_STATUS_MEDIA_DISCONNECT:
netvsc_linkstatus_callback(sc, 0);
break;
+
default:
/* TODO: */
- if_printf(sc->hn_ifp,
- "unknown status %d received\n", indicate->status);
+ if_printf(sc->hn_ifp, "unknown RNDIS status 0x%08x\n",
+ msg->rm_status);
break;
}
}
static int
-hv_rf_find_recvinfo(const rndis_packet *rpkt, struct hn_recvinfo *info)
+hn_rndis_rxinfo(const void *info_data, int info_dlen, struct hn_recvinfo *info)
{
- const struct rndis_pktinfo *pi;
- uint32_t mask = 0, len;
-
- info->vlan_info = HN_NDIS_VLAN_INFO_INVALID;
- info->csum_info = HN_NDIS_RXCSUM_INFO_INVALID;
- info->hash_info = HN_NDIS_HASH_INFO_INVALID;
-
- if (rpkt->per_pkt_info_offset == 0)
- return (0);
- if (__predict_false(rpkt->per_pkt_info_offset &
- (RNDIS_PKTINFO_ALIGN - 1)))
- return (EINVAL);
- if (__predict_false(rpkt->per_pkt_info_offset <
- RNDIS_PACKET_MSG_OFFSET_MIN))
- return (EINVAL);
+ const struct rndis_pktinfo *pi = info_data;
+ uint32_t mask = 0;
- pi = (const struct rndis_pktinfo *)
- ((const uint8_t *)rpkt + rpkt->per_pkt_info_offset);
- len = rpkt->per_pkt_info_length;
-
- while (len != 0) {
+ while (info_dlen != 0) {
const void *data;
uint32_t dlen;
- if (__predict_false(len < sizeof(*pi)))
+ if (__predict_false(info_dlen < sizeof(*pi)))
return (EINVAL);
- if (__predict_false(len < pi->rm_size))
+ if (__predict_false(info_dlen < pi->rm_size))
return (EINVAL);
- len -= pi->rm_size;
+ info_dlen -= pi->rm_size;
- if (__predict_false(pi->rm_size & (RNDIS_PKTINFO_ALIGN - 1)))
+ if (__predict_false(pi->rm_size & RNDIS_PKTINFO_SIZE_ALIGNMASK))
return (EINVAL);
if (__predict_false(pi->rm_size < pi->rm_pktinfooffset))
return (EINVAL);
@@ -241,76 +232,223 @@ next:
return (0);
}
+static __inline bool
+hn_rndis_check_overlap(int off, int len, int check_off, int check_len)
+{
+
+ if (off < check_off) {
+ if (__predict_true(off + len <= check_off))
+ return (false);
+ } else if (off > check_off) {
+ if (__predict_true(check_off + check_len <= off))
+ return (false);
+ }
+ return (true);
+}
+
/*
* RNDIS filter receive data
*/
static void
hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen)
{
- const rndis_msg *message = data;
- const rndis_packet *rndis_pkt;
- uint32_t data_offset;
+ const struct rndis_packet_msg *pkt;
struct hn_recvinfo info;
-
- rndis_pkt = &message->msg.packet;
+ int data_off, pktinfo_off, data_len, pktinfo_len;
/*
- * Fixme: Handle multiple rndis pkt msgs that may be enclosed in this
- * netvsc packet (ie tot_data_buf_len != message_length)
+ * Check length.
*/
+ if (__predict_false(dlen < sizeof(*pkt))) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg\n");
+ return;
+ }
+ pkt = data;
- /* Remove rndis header, then pass data packet up the stack */
- data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
+ if (__predict_false(dlen < pkt->rm_len)) {
+ if_printf(rxr->hn_ifp, "truncated RNDIS packet msg, "
+ "dlen %d, msglen %u\n", dlen, pkt->rm_len);
+ return;
+ }
+ if (__predict_false(pkt->rm_len <
+ pkt->rm_datalen + pkt->rm_oobdatalen + pkt->rm_pktinfolen)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msglen, "
+ "msglen %u, data %u, oob %u, pktinfo %u\n",
+ pkt->rm_len, pkt->rm_datalen, pkt->rm_oobdatalen,
+ pkt->rm_pktinfolen);
+ return;
+ }
+ if (__predict_false(pkt->rm_datalen == 0)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, no data\n");
+ return;
+ }
- dlen -= data_offset;
- if (dlen < rndis_pkt->data_length) {
- if_printf(rxr->hn_ifp,
- "total length %u is less than data length %u\n",
- dlen, rndis_pkt->data_length);
+ /*
+ * Check offests.
+ */
+#define IS_OFFSET_INVALID(ofs) \
+ ((ofs) < RNDIS_PACKET_MSG_OFFSET_MIN || \
+ ((ofs) & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK))
+
+ /* XXX Hyper-V does not meet data offset alignment requirement */
+ if (__predict_false(pkt->rm_dataoffset < RNDIS_PACKET_MSG_OFFSET_MIN)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "data offset %u\n", pkt->rm_dataoffset);
+ return;
+ }
+ if (__predict_false(pkt->rm_oobdataoffset > 0 &&
+ IS_OFFSET_INVALID(pkt->rm_oobdataoffset))) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "oob offset %u\n", pkt->rm_oobdataoffset);
+ return;
+ }
+ if (__predict_true(pkt->rm_pktinfooffset > 0) &&
+ __predict_false(IS_OFFSET_INVALID(pkt->rm_pktinfooffset))) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "pktinfo offset %u\n", pkt->rm_pktinfooffset);
return;
}
- dlen = rndis_pkt->data_length;
- data = (const uint8_t *)data + data_offset;
+#undef IS_OFFSET_INVALID
- if (hv_rf_find_recvinfo(rndis_pkt, &info)) {
- if_printf(rxr->hn_ifp, "recvinfo parsing failed\n");
+ data_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_dataoffset);
+ data_len = pkt->rm_datalen;
+ pktinfo_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_pktinfooffset);
+ pktinfo_len = pkt->rm_pktinfolen;
+
+ /*
+ * Check OOB coverage.
+ */
+ if (__predict_false(pkt->rm_oobdatalen != 0)) {
+ int oob_off, oob_len;
+
+ if_printf(rxr->hn_ifp, "got oobdata\n");
+ oob_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_oobdataoffset);
+ oob_len = pkt->rm_oobdatalen;
+
+ if (__predict_false(oob_off + oob_len > pkt->rm_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "oob overflow, msglen %u, oob abs %d len %d\n",
+ pkt->rm_len, oob_off, oob_len);
+ return;
+ }
+
+ /*
+ * Check against data.
+ */
+ if (hn_rndis_check_overlap(oob_off, oob_len,
+ data_off, data_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "oob overlaps data, oob abs %d len %d, "
+ "data abs %d len %d\n",
+ oob_off, oob_len, data_off, data_len);
+ return;
+ }
+
+ /*
+ * Check against pktinfo.
+ */
+ if (pktinfo_len != 0 &&
+ hn_rndis_check_overlap(oob_off, oob_len,
+ pktinfo_off, pktinfo_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "oob overlaps pktinfo, oob abs %d len %d, "
+ "pktinfo abs %d len %d\n",
+ oob_off, oob_len, pktinfo_off, pktinfo_len);
+ return;
+ }
+ }
+
+ /*
+ * Check per-packet-info coverage and find useful per-packet-info.
+ */
+ info.vlan_info = HN_NDIS_VLAN_INFO_INVALID;
+ info.csum_info = HN_NDIS_RXCSUM_INFO_INVALID;
+ info.hash_info = HN_NDIS_HASH_INFO_INVALID;
+ if (__predict_true(pktinfo_len != 0)) {
+ bool overlap;
+ int error;
+
+ if (__predict_false(pktinfo_off + pktinfo_len > pkt->rm_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "pktinfo overflow, msglen %u, "
+ "pktinfo abs %d len %d\n",
+ pkt->rm_len, pktinfo_off, pktinfo_len);
+ return;
+ }
+
+ /*
+ * Check packet info coverage.
+ */
+ overlap = hn_rndis_check_overlap(pktinfo_off, pktinfo_len,
+ data_off, data_len);
+ if (__predict_false(overlap)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "pktinfo overlap data, pktinfo abs %d len %d, "
+ "data abs %d len %d\n",
+ pktinfo_off, pktinfo_len, data_off, data_len);
+ return;
+ }
+
+ /*
+ * Find useful per-packet-info.
+ */
+ error = hn_rndis_rxinfo(((const uint8_t *)pkt) + pktinfo_off,
+ pktinfo_len, &info);
+ if (__predict_false(error)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg "
+ "pktinfo\n");
+ return;
+ }
+ }
+
+ if (__predict_false(data_off + data_len > pkt->rm_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "data overflow, msglen %u, data abs %d len %d\n",
+ pkt->rm_len, data_off, data_len);
return;
}
- netvsc_recv(rxr, data, dlen, &info);
+ netvsc_recv(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info);
}
/*
* RNDIS filter on receive
*/
-int
+void
hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
const void *data, int dlen)
{
- const rndis_msg *rndis_hdr;
const struct rndis_comp_hdr *comp;
+ const struct rndis_msghdr *hdr;
+
+ if (__predict_false(dlen < sizeof(*hdr))) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS msg\n");
+ return;
+ }
+ hdr = data;
- rndis_hdr = data;
- switch (rndis_hdr->ndis_msg_type) {
- /* data message */
+ switch (hdr->rm_type) {
case REMOTE_NDIS_PACKET_MSG:
hv_rf_receive_data(rxr, data, dlen);
break;
- /* completion messages */
case REMOTE_NDIS_INITIALIZE_CMPLT:
case REMOTE_NDIS_QUERY_CMPLT:
case REMOTE_NDIS_SET_CMPLT:
- case REMOTE_NDIS_KEEPALIVE_CMPLT:
+ case REMOTE_NDIS_KEEPALIVE_CMPLT: /* unused */
+ if (dlen < sizeof(*comp)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS cmplt\n");
+ return;
+ }
comp = data;
+
KASSERT(comp->rm_rid > HN_RNDIS_RID_COMPAT_MAX,
- ("invalid rid 0x%08x\n", comp->rm_rid));
+ ("invalid RNDIS rid 0x%08x\n", comp->rm_rid));
vmbus_xact_ctx_wakeup(sc->hn_xact, comp, dlen);
break;
- /* notification message */
case REMOTE_NDIS_INDICATE_STATUS_MSG:
- hv_rf_receive_indicate_status(sc, rndis_hdr);
+ hv_rf_receive_indicate_status(sc, data, dlen);
break;
case REMOTE_NDIS_RESET_CMPLT:
@@ -321,15 +459,14 @@ hv_rf_on_receive(struct hn_softc *sc, st
* RESET is not issued by hn(4), so this message should
* _not_ be observed.
*/
- if_printf(sc->hn_ifp, "RESET CMPLT received\n");
+ if_printf(rxr->hn_ifp, "RESET cmplt received\n");
break;
default:
- if_printf(sc->hn_ifp, "unknown RNDIS message 0x%x\n",
- rndis_hdr->ndis_msg_type);
+ if_printf(rxr->hn_ifp, "unknown RNDIS msg 0x%x\n",
+ hdr->rm_type);
break;
}
- return (0);
}
/*
@@ -551,7 +688,7 @@ hn_rndis_query(struct hn_softc *sc, uint
* Check output data length and offset.
*/
/* ofs is the offset from the beginning of comp. */
- ofs = RNDIS_QUERY_COMP_INFOBUFABS(comp->rm_infobufoffset);
+ ofs = RNDIS_QUERY_COMP_INFOBUFOFFSET_ABS(comp->rm_infobufoffset);
if (ofs < sizeof(*comp) || ofs + comp->rm_infobuflen > comp_len) {
if_printf(sc->hn_ifp, "RNDIS query invalid comp ib off/len, "
"%u/%u\n", comp->rm_infobufoffset, comp->rm_infobuflen);
Modified: stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.h
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.h Mon Oct 17 08:06:19 2016 (r307497)
+++ stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.h Mon Oct 17 08:10:24 2016 (r307498)
@@ -40,7 +40,7 @@
*/
struct hn_rx_ring;
-int hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
+void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
const void *data, int dlen);
void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);
int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int *nchan,
Modified: stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c Mon Oct 17 08:06:19 2016 (r307497)
+++ stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c Mon Oct 17 08:10:24 2016 (r307498)
@@ -721,7 +721,20 @@ vmbus_chan_recv(struct vmbus_channel *ch
error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt));
if (error)
- return error;
+ return (error);
+
+ if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
+ device_printf(chan->ch_dev, "invalid hlen %u\n",
+ pkt.cph_hlen);
+ /* XXX this channel is dead actually. */
+ return (EIO);
+ }
+ if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) {
+ device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n",
+ pkt.cph_hlen, pkt.cph_tlen);
+ /* XXX this channel is dead actually. */
+ return (EIO);
+ }
hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen);
dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen;
@@ -729,7 +742,7 @@ vmbus_chan_recv(struct vmbus_channel *ch
if (*dlen0 < dlen) {
/* Return the size of this packet's data. */
*dlen0 = dlen;
- return ENOBUFS;
+ return (ENOBUFS);
}
*xactid = pkt.cph_xactid;
@@ -739,7 +752,7 @@ vmbus_chan_recv(struct vmbus_channel *ch
error = vmbus_rxbr_read(&chan->ch_rxbr, data, dlen, hlen);
KASSERT(!error, ("vmbus_rxbr_read failed"));
- return 0;
+ return (0);
}
int
@@ -751,13 +764,26 @@ vmbus_chan_recv_pkt(struct vmbus_channel
error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt));
if (error)
- return error;
+ return (error);
+
+ if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
+ device_printf(chan->ch_dev, "invalid hlen %u\n",
+ pkt.cph_hlen);
+ /* XXX this channel is dead actually. */
+ return (EIO);
+ }
+ if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) {
+ device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n",
+ pkt.cph_hlen, pkt.cph_tlen);
+ /* XXX this channel is dead actually. */
+ return (EIO);
+ }
pktlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen);
if (*pktlen0 < pktlen) {
/* Return the size of this packet. */
*pktlen0 = pktlen;
- return ENOBUFS;
+ return (ENOBUFS);
}
*pktlen0 = pktlen;
@@ -765,7 +791,7 @@ vmbus_chan_recv_pkt(struct vmbus_channel
error = vmbus_rxbr_read(&chan->ch_rxbr, pkt0, pktlen, 0);
KASSERT(!error, ("vmbus_rxbr_read failed"));
- return 0;
+ return (0);
}
static void
Modified: stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h Mon Oct 17 08:06:19 2016 (r307497)
+++ stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h Mon Oct 17 08:10:24 2016 (r307498)
@@ -153,6 +153,9 @@ do { \
#define VMBUS_CHANPKT_TOTLEN(tlen) \
roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN)
+#define VMBUS_CHANPKT_HLEN_MIN \
+ (sizeof(struct vmbus_chanpkt_hdr) >> VMBUS_CHANPKT_SIZE_SHIFT)
+
struct vmbus_chanpkt {
struct vmbus_chanpkt_hdr cp_hdr;
} __packed;
Modified: stable/11/sys/net/rndis.h
==============================================================================
--- stable/11/sys/net/rndis.h Mon Oct 17 08:06:19 2016 (r307497)
+++ stable/11/sys/net/rndis.h Mon Oct 17 08:10:24 2016 (r307498)
@@ -127,6 +127,14 @@ struct rndis_packet_msg {
(sizeof(struct rndis_packet_msg) - \
__offsetof(struct rndis_packet_msg, rm_dataoffset))
+/* Offset from the beginning of rndis_packet_msg. */
+#define RNDIS_PACKET_MSG_OFFSET_ABS(ofs) \
+ ((ofs) + __offsetof(struct rndis_packet_msg, rm_dataoffset))
+
+#define RNDIS_PACKET_MSG_OFFSET_ALIGN 4
+#define RNDIS_PACKET_MSG_OFFSET_ALIGNMASK \
+ (RNDIS_PACKET_MSG_OFFSET_ALIGN - 1)
+
/* Per-packet-info for RNDIS data message */
struct rndis_pktinfo {
uint32_t rm_size;
@@ -137,7 +145,8 @@ struct rndis_pktinfo {
#define RNDIS_PKTINFO_OFFSET \
__offsetof(struct rndis_pktinfo, rm_data[0])
-#define RNDIS_PKTINFO_ALIGN 4
+#define RNDIS_PKTINFO_SIZE_ALIGN 4
+#define RNDIS_PKTINFO_SIZE_ALIGNMASK (RNDIS_PKTINFO_SIZE_ALIGN - 1)
#define NDIS_PKTINFO_TYPE_CSUM 0
#define NDIS_PKTINFO_TYPE_IPSEC 1
@@ -236,7 +245,8 @@ struct rndis_query_comp {
uint32_t rm_infobufoffset;
};
-#define RNDIS_QUERY_COMP_INFOBUFABS(ofs) \
+/* infobuf offset from the beginning of rndis_query_comp. */
+#define RNDIS_QUERY_COMP_INFOBUFOFFSET_ABS(ofs) \
((ofs) + __offsetof(struct rndis_query_req, rm_rid))
/* Send a set object request. */
@@ -295,9 +305,28 @@ struct rndis_reset_comp {
uint32_t rm_adrreset;
};
-/* 802.3 link-state or undefined message error. */
+/* 802.3 link-state or undefined message error. Sent by device. */
#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007
+struct rndis_status_msg {
+ uint32_t rm_type;
+ uint32_t rm_len;
+ uint32_t rm_status;
+ uint32_t rm_stbuflen;
+ uint32_t rm_stbufoffset;
+ /* rndis_diag_info */
+};
+
+/*
+ * Immediately after rndis_status_msg.rm_stbufoffset, if a control
+ * message is malformatted, or a packet message contains inappropriate
+ * content.
+ */
+struct rndis_diag_info {
+ uint32_t rm_diagstatus;
+ uint32_t rm_erroffset;
+};
+
/* Keepalive messsage. May be sent by device. */
#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008
#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008
More information about the svn-src-all
mailing list