svn commit: r307193 - in stable/10/sys: dev/hyperv/netvsc net
Sepherosa Ziehau
sephe at FreeBSD.org
Thu Oct 13 07:17:06 UTC 2016
Author: sephe
Date: Thu Oct 13 07:17:04 2016
New Revision: 307193
URL: https://svnweb.freebsd.org/changeset/base/307193
Log:
MFC 305175,305176,305179,305182,305268,305270,305276
305175
net/rndis: Define per-packet-info for RNDIS packet message
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7708
305176
hyperv/hn: Stringent per-packet-info verification.
While I'm here, minor style changes.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7709
305179
hyperv/hn: Fix VLAN tag construction.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7716
305182
net/rndis: Define types for RNDIS pktinfo rm_type field.
They are defined by NDIS spec, so the NDIS prefix.
Reviewed by: hps
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7717
305268
hyperv/hn: Rework RXCSUM related bits
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7735
305270
hyperv/hn: Simplify RX hash related bits.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7736
305276
hyperv/hn: Use the per-packet-info types defined by net/rndis.h
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7737
Modified:
stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c
stable/10/sys/dev/hyperv/netvsc/if_hnreg.h
stable/10/sys/dev/hyperv/netvsc/if_hnvar.h
stable/10/sys/dev/hyperv/netvsc/ndis.h
stable/10/sys/net/rndis.h
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 07:12:20 2016 (r307192)
+++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 07:17:04 2016 (r307193)
@@ -1307,6 +1307,7 @@ netvsc_recv(struct hn_rx_ring *rxr, cons
struct ifnet *ifp = rxr->hn_ifp;
struct mbuf *m_new;
int size, do_lro = 0, do_csum = 1;
+ int hash_type = M_HASHTYPE_OPAQUE;
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
return (0);
@@ -1352,28 +1353,29 @@ netvsc_recv(struct hn_rx_ring *rxr, cons
do_csum = 0;
/* receive side checksum offload */
- if (info->csum_info != NULL) {
+ if (info->csum_info != HN_NDIS_RXCSUM_INFO_INVALID) {
/* IP csum offload */
- if (info->csum_info->receive.ip_csum_succeeded && do_csum) {
+ if ((info->csum_info & NDIS_RXCSUM_INFO_IPCS_OK) && do_csum) {
m_new->m_pkthdr.csum_flags |=
(CSUM_IP_CHECKED | CSUM_IP_VALID);
rxr->hn_csum_ip++;
}
/* TCP/UDP csum offload */
- if ((info->csum_info->receive.tcp_csum_succeeded ||
- info->csum_info->receive.udp_csum_succeeded) && do_csum) {
+ if ((info->csum_info & (NDIS_RXCSUM_INFO_UDPCS_OK |
+ NDIS_RXCSUM_INFO_TCPCS_OK)) && do_csum) {
m_new->m_pkthdr.csum_flags |=
(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
m_new->m_pkthdr.csum_data = 0xffff;
- if (info->csum_info->receive.tcp_csum_succeeded)
+ if (info->csum_info & NDIS_RXCSUM_INFO_TCPCS_OK)
rxr->hn_csum_tcp++;
else
rxr->hn_csum_udp++;
}
- if (info->csum_info->receive.ip_csum_succeeded &&
- info->csum_info->receive.tcp_csum_succeeded)
+ if ((info->csum_info &
+ (NDIS_RXCSUM_INFO_TCPCS_OK | NDIS_RXCSUM_INFO_IPCS_OK)) ==
+ (NDIS_RXCSUM_INFO_TCPCS_OK | NDIS_RXCSUM_INFO_IPCS_OK))
do_lro = 1;
} else {
const struct ether_header *eh;
@@ -1429,20 +1431,20 @@ netvsc_recv(struct hn_rx_ring *rxr, cons
}
}
skip:
- if (info->vlan_info != NULL) {
- m_new->m_pkthdr.ether_vtag = info->vlan_info->u1.s1.vlan_id;
+ if (info->vlan_info != HN_NDIS_VLAN_INFO_INVALID) {
+ m_new->m_pkthdr.ether_vtag = EVL_MAKETAG(
+ NDIS_VLAN_INFO_ID(info->vlan_info),
+ NDIS_VLAN_INFO_PRI(info->vlan_info),
+ NDIS_VLAN_INFO_CFI(info->vlan_info));
m_new->m_flags |= M_VLANTAG;
}
- if (info->hash_info != NULL && info->hash_value != NULL) {
- int hash_type = M_HASHTYPE_OPAQUE;
-
+ if (info->hash_info != HN_NDIS_HASH_INFO_INVALID) {
rxr->hn_rss_pkts++;
- m_new->m_pkthdr.flowid = info->hash_value->hash_value;
- if ((info->hash_info->hash_info & NDIS_HASH_FUNCTION_MASK) ==
+ m_new->m_pkthdr.flowid = info->hash_value;
+ if ((info->hash_info & NDIS_HASH_FUNCTION_MASK) ==
NDIS_HASH_FUNCTION_TOEPLITZ) {
- uint32_t type =
- (info->hash_info->hash_info & NDIS_HASH_TYPE_MASK);
+ uint32_t type = (info->hash_info & NDIS_HASH_TYPE_MASK);
switch (type) {
case NDIS_HASH_IPV4:
@@ -1470,14 +1472,10 @@ skip:
break;
}
}
- M_HASHTYPE_SET(m_new, hash_type);
} else {
- if (info->hash_value != NULL)
- m_new->m_pkthdr.flowid = info->hash_value->hash_value;
- else
- m_new->m_pkthdr.flowid = rxr->hn_rx_idx;
- M_HASHTYPE_SET(m_new, M_HASHTYPE_OPAQUE);
+ m_new->m_pkthdr.flowid = rxr->hn_rx_idx;
}
+ M_HASHTYPE_SET(m_new, hash_type);
/*
* Note: Moved RX completion back to hv_nv_on_receive() so all
Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 07:12:20 2016 (r307192)
+++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 07:17:04 2016 (r307193)
@@ -154,79 +154,92 @@ hv_rf_receive_indicate_status(struct hn_
static int
hv_rf_find_recvinfo(const rndis_packet *rpkt, struct hn_recvinfo *info)
{
- const rndis_per_packet_info *ppi;
- uint32_t mask, len;
+ const struct rndis_pktinfo *pi;
+ uint32_t mask = 0, len;
- info->vlan_info = NULL;
- info->csum_info = NULL;
- info->hash_info = NULL;
- info->hash_value = NULL;
+ 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;
+ 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);
- ppi = (const rndis_per_packet_info *)
+ pi = (const struct rndis_pktinfo *)
((const uint8_t *)rpkt + rpkt->per_pkt_info_offset);
len = rpkt->per_pkt_info_length;
- mask = 0;
while (len != 0) {
- const void *ppi_dptr;
- uint32_t ppi_dlen;
+ const void *data;
+ uint32_t dlen;
- if (__predict_false(ppi->size < ppi->per_packet_info_offset))
- return EINVAL;
- ppi_dlen = ppi->size - ppi->per_packet_info_offset;
- ppi_dptr = (const uint8_t *)ppi + ppi->per_packet_info_offset;
-
- switch (ppi->type) {
- case ieee_8021q_info:
- if (__predict_false(ppi_dlen < sizeof(ndis_8021q_info)))
- return EINVAL;
- info->vlan_info = ppi_dptr;
+ if (__predict_false(len < sizeof(*pi)))
+ return (EINVAL);
+ if (__predict_false(len < pi->rm_size))
+ return (EINVAL);
+ len -= pi->rm_size;
+
+ if (__predict_false(pi->rm_size & (RNDIS_PKTINFO_ALIGN - 1)))
+ return (EINVAL);
+ if (__predict_false(pi->rm_size < pi->rm_pktinfooffset))
+ return (EINVAL);
+ dlen = pi->rm_size - pi->rm_pktinfooffset;
+ data = pi->rm_data;
+
+ switch (pi->rm_type) {
+ case NDIS_PKTINFO_TYPE_VLAN:
+ if (__predict_false(dlen < NDIS_VLAN_INFO_SIZE))
+ return (EINVAL);
+ info->vlan_info = *((const uint32_t *)data);
mask |= HV_RF_RECVINFO_VLAN;
break;
- case tcpip_chksum_info:
- if (__predict_false(ppi_dlen <
- sizeof(rndis_tcp_ip_csum_info)))
- return EINVAL;
- info->csum_info = ppi_dptr;
+ case NDIS_PKTINFO_TYPE_CSUM:
+ if (__predict_false(dlen < NDIS_RXCSUM_INFO_SIZE))
+ return (EINVAL);
+ info->csum_info = *((const uint32_t *)data);
mask |= HV_RF_RECVINFO_CSUM;
break;
- case nbl_hash_value:
- if (__predict_false(ppi_dlen <
- sizeof(struct rndis_hash_value)))
- return EINVAL;
- info->hash_value = ppi_dptr;
+ case HN_NDIS_PKTINFO_TYPE_HASHVAL:
+ if (__predict_false(dlen < HN_NDIS_HASH_VALUE_SIZE))
+ return (EINVAL);
+ info->hash_value = *((const uint32_t *)data);
mask |= HV_RF_RECVINFO_HASHVAL;
break;
- case nbl_hash_info:
- if (__predict_false(ppi_dlen <
- sizeof(struct rndis_hash_info)))
- return EINVAL;
- info->hash_info = ppi_dptr;
+ case HN_NDIS_PKTINFO_TYPE_HASHINF:
+ if (__predict_false(dlen < HN_NDIS_HASH_INFO_SIZE))
+ return (EINVAL);
+ info->hash_info = *((const uint32_t *)data);
mask |= HV_RF_RECVINFO_HASHINF;
break;
default:
- goto skip;
+ goto next;
}
if (mask == HV_RF_RECVINFO_ALL) {
/* All found; done */
break;
}
-skip:
- if (__predict_false(len < ppi->size))
- return EINVAL;
- len -= ppi->size;
- ppi = (const rndis_per_packet_info *)
- ((const uint8_t *)ppi + ppi->size);
+next:
+ pi = (const struct rndis_pktinfo *)
+ ((const uint8_t *)pi + pi->rm_size);
}
- return 0;
+
+ /*
+ * Final fixup.
+ * - If there is no hash value, invalidate the hash info.
+ */
+ if ((mask & HV_RF_RECVINFO_HASHVAL) == 0)
+ info->hash_info = HN_NDIS_HASH_INFO_INVALID;
+ return (0);
}
/*
Modified: stable/10/sys/dev/hyperv/netvsc/if_hnreg.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Thu Oct 13 07:12:20 2016 (r307192)
+++ stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Thu Oct 13 07:17:04 2016 (r307193)
@@ -208,4 +208,17 @@ struct hn_nvs_rndis_ack {
} __packed;
CTASSERT(sizeof(struct hn_nvs_rndis_ack) >= HN_NVS_REQSIZE_MIN);
+/*
+ * RNDIS extension
+ */
+
+/* Per-packet hash info */
+#define HN_NDIS_HASH_INFO_SIZE sizeof(uint32_t)
+#define HN_NDIS_PKTINFO_TYPE_HASHINF NDIS_PKTINFO_TYPE_ORIG_NBLIST
+/* NDIS_HASH_ */
+
+/* Per-packet hash value */
+#define HN_NDIS_HASH_VALUE_SIZE sizeof(uint32_t)
+#define HN_NDIS_PKTINFO_TYPE_HASHVAL NDIS_PKTINFO_TYPE_PKT_CANCELID
+
#endif /* !_IF_HNREG_H_ */
Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 07:12:20 2016 (r307192)
+++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 07:17:04 2016 (r307193)
@@ -55,11 +55,15 @@ struct rndix_hash_value;
struct ndis_8021q_info_;
struct rndis_tcp_ip_csum_info_;
+#define HN_NDIS_VLAN_INFO_INVALID 0xffffffff
+#define HN_NDIS_RXCSUM_INFO_INVALID 0
+#define HN_NDIS_HASH_INFO_INVALID 0
+
struct hn_recvinfo {
- const struct ndis_8021q_info_ *vlan_info;
- const struct rndis_tcp_ip_csum_info_ *csum_info;
- const struct rndis_hash_info *hash_info;
- const struct rndis_hash_value *hash_value;
+ uint32_t vlan_info;
+ uint32_t csum_info;
+ uint32_t hash_info;
+ uint32_t hash_value;
};
#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
Modified: stable/10/sys/dev/hyperv/netvsc/ndis.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 07:12:20 2016 (r307192)
+++ stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 07:17:04 2016 (r307193)
@@ -203,4 +203,32 @@ struct ndis_rssprm_toeplitz {
uint32_t rss_ind[NDIS_HASH_INDCNT];
};
+/*
+ * Per-packet-info
+ */
+
+/* VLAN */
+#define NDIS_VLAN_INFO_SIZE sizeof(uint32_t)
+#define NDIS_VLAN_INFO_PRI_MASK 0x0007
+#define NDIS_VLAN_INFO_CFI_MASK 0x0008
+#define NDIS_VLAN_INFO_ID_MASK 0xfff0
+#define NDIS_VLAN_INFO_MAKE(id, pri, cfi) \
+ (((pri) & NVIS_VLAN_INFO_PRI_MASK) | \
+ (((cfi) & 0x1) << 3) | (((id) & 0xfff) << 4))
+#define NDIS_VLAN_INFO_ID(inf) (((inf) & NDIS_VLAN_INFO_ID_MASK) >> 4)
+#define NDIS_VLAN_INFO_CFI(inf) (((inf) & NDIS_VLAN_INFO_CFI_MASK) >> 3)
+#define NDIS_VLAN_INFO_PRI(inf) ((inf) & NDIS_VLAN_INFO_PRI_MASK)
+
+/* Reception checksum */
+#define NDIS_RXCSUM_INFO_SIZE sizeof(uint32_t)
+#define NDIS_RXCSUM_INFO_TCPCS_FAILED 0x0001
+#define NDIS_RXCSUM_INFO_UDPCS_FAILED 0x0002
+#define NDIS_RXCSUM_INFO_IPCS_FAILED 0x0004
+#define NDIS_RXCSUM_INFO_TCPCS_OK 0x0008
+#define NDIS_RXCSUM_INFO_UDPCS_OK 0x0010
+#define NDIS_RXCSUM_INFO_IPCS_OK 0x0020
+#define NDIS_RXCSUM_INFO_LOOPBACK 0x0040
+#define NDIS_RXCSUM_INFO_TCPCS_INVAL 0x0080
+#define NDIS_RXCSUM_INFO_IPCS_INVAL 0x0100
+
#endif /* !_NET_NDIS_H_ */
Modified: stable/10/sys/net/rndis.h
==============================================================================
--- stable/10/sys/net/rndis.h Thu Oct 13 07:12:20 2016 (r307192)
+++ stable/10/sys/net/rndis.h Thu Oct 13 07:17:04 2016 (r307193)
@@ -112,6 +112,39 @@ struct rndis_packet_msg {
};
/*
+ * Minimum value for rm_dataoffset, rm_oobdataoffset, and
+ * rm_pktinfooffset.
+ */
+#define RNDIS_PACKET_MSG_OFFSET_MIN \
+ (sizeof(struct rndis_packet_msg) - \
+ __offsetof(struct rndis_packet_msg, rm_dataoffset))
+
+/* Per-packet-info for RNDIS data message */
+struct rndis_pktinfo {
+ uint32_t rm_size;
+ uint32_t rm_type; /* NDIS_PKTINFO_TYPE_ */
+ uint32_t rm_pktinfooffset;
+ uint8_t rm_data[];
+};
+
+#define RNDIS_PKTINFO_OFFSET \
+ __offsetof(struct rndis_pktinfo, rm_data[0])
+#define RNDIS_PKTINFO_ALIGN 4
+
+#define NDIS_PKTINFO_TYPE_CSUM 0
+#define NDIS_PKTINFO_TYPE_IPSEC 1
+#define NDIS_PKTINFO_TYPE_LSO 2
+#define NDIS_PKTINFO_TYPE_CLASSIFY 3
+/* reserved 4 */
+#define NDIS_PKTINFO_TYPE_SGLIST 5
+#define NDIS_PKTINFO_TYPE_VLAN 6
+#define NDIS_PKTINFO_TYPE_ORIG 7
+#define NDIS_PKTINFO_TYPE_PKT_CANCELID 8
+#define NDIS_PKTINFO_TYPE_ORIG_NBLIST 9
+#define NDIS_PKTINFO_TYPE_CACHE_NBLIST 10
+#define NDIS_PKTINFO_TYPE_PKT_PAD 11
+
+/*
* RNDIS control messages
*/
struct rndis_comp_hdr {
More information about the svn-src-stable-10
mailing list