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 {
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to