Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Oct 2016 07:46:13 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r307495 - in stable/11/sys: dev/hyperv/netvsc net
Message-ID:  <201610170746.u9H7kDji017720@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Mon Oct 17 07:46:13 2016
New Revision: 307495
URL: https://svnweb.freebsd.org/changeset/base/307495

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/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
  stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c
  stable/11/sys/dev/hyperv/netvsc/if_hnreg.h
  stable/11/sys/dev/hyperv/netvsc/if_hnvar.h
  stable/11/sys/dev/hyperv/netvsc/ndis.h
  stable/11/sys/net/rndis.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Mon Oct 17 07:38:21 2016	(r307494)
+++ stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Mon Oct 17 07:46:13 2016	(r307495)
@@ -1289,7 +1289,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_HASH;
+	int hash_type;
 
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 		return (0);
@@ -1335,28 +1335,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;
@@ -1412,18 +1413,21 @@ 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) {
+	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;
+		hash_type = M_HASHTYPE_OPAQUE_HASH;
+		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:
@@ -1452,12 +1456,8 @@ skip:
 			}
 		}
 	} 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;
-			hash_type = M_HASHTYPE_OPAQUE;
-		}
+		m_new->m_pkthdr.flowid = rxr->hn_rx_idx;
+		hash_type = M_HASHTYPE_OPAQUE;
 	}
 	M_HASHTYPE_SET(m_new, hash_type);
 

Modified: stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c	Mon Oct 17 07:38:21 2016	(r307494)
+++ stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c	Mon Oct 17 07:46:13 2016	(r307495)
@@ -153,79 +153,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/11/sys/dev/hyperv/netvsc/if_hnreg.h
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/if_hnreg.h	Mon Oct 17 07:38:21 2016	(r307494)
+++ stable/11/sys/dev/hyperv/netvsc/if_hnreg.h	Mon Oct 17 07:46:13 2016	(r307495)
@@ -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/11/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/if_hnvar.h	Mon Oct 17 07:38:21 2016	(r307494)
+++ stable/11/sys/dev/hyperv/netvsc/if_hnvar.h	Mon Oct 17 07:46:13 2016	(r307495)
@@ -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/11/sys/dev/hyperv/netvsc/ndis.h
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/ndis.h	Mon Oct 17 07:38:21 2016	(r307494)
+++ stable/11/sys/dev/hyperv/netvsc/ndis.h	Mon Oct 17 07:46:13 2016	(r307495)
@@ -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/11/sys/net/rndis.h
==============================================================================
--- stable/11/sys/net/rndis.h	Mon Oct 17 07:38:21 2016	(r307494)
+++ stable/11/sys/net/rndis.h	Mon Oct 17 07:46:13 2016	(r307495)
@@ -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 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610170746.u9H7kDji017720>