Date: Thu, 13 Oct 2016 07:17:04 +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-10@freebsd.org Subject: svn commit: r307193 - in stable/10/sys: dev/hyperv/netvsc net Message-ID: <201610130717.u9D7H4r9011543@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610130717.u9D7H4r9011543>