Page MenuHomeFreeBSD

D12417.id33233.diff
No OneTemporary

D12417.id33233.diff

Index: sys/dev/hyperv/netvsc/if_hn.c
===================================================================
--- sys/dev/hyperv/netvsc/if_hn.c
+++ sys/dev/hyperv/netvsc/if_hn.c
@@ -727,6 +727,7 @@
ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
else
ehlen = ETHER_HDR_LEN;
+ m_head->m_pkthdr.l2hlen = ehlen;
#ifdef INET
if (m_head->m_pkthdr.csum_flags & CSUM_IP_TSO) {
@@ -736,6 +737,7 @@
PULLUP_HDR(m_head, ehlen + sizeof(*ip));
ip = mtodo(m_head, ehlen);
iphlen = ip->ip_hl << 2;
+ m_head->m_pkthdr.l3hlen = iphlen;
PULLUP_HDR(m_head, ehlen + iphlen + sizeof(*th));
th = mtodo(m_head, ehlen + iphlen);
@@ -759,6 +761,7 @@
m_freem(m_head);
return (NULL);
}
+ m_head->m_pkthdr.l3hlen = sizeof(*ip6);
PULLUP_HDR(m_head, ehlen + sizeof(*ip6) + sizeof(*th));
th = mtodo(m_head, ehlen + sizeof(*ip6));
@@ -768,41 +771,34 @@
}
#endif
return (m_head);
-
}
/*
* NOTE: If this function failed, the m_head would be freed.
*/
static __inline struct mbuf *
-hn_check_tcpsyn(struct mbuf *m_head, int *tcpsyn)
+hn_set_hlen(struct mbuf *m_head)
{
const struct ether_vlan_header *evl;
- const struct tcphdr *th;
int ehlen;
- *tcpsyn = 0;
-
PULLUP_HDR(m_head, sizeof(*evl));
evl = mtod(m_head, const struct ether_vlan_header *);
if (evl->evl_encap_proto == ntohs(ETHERTYPE_VLAN))
ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
else
ehlen = ETHER_HDR_LEN;
+ m_head->m_pkthdr.l2hlen = ehlen;
#ifdef INET
- if (m_head->m_pkthdr.csum_flags & CSUM_IP_TCP) {
+ if (m_head->m_pkthdr.csum_flags & (CSUM_IP_TCP | CSUM_IP_UDP)) {
const struct ip *ip;
int iphlen;
PULLUP_HDR(m_head, ehlen + sizeof(*ip));
ip = mtodo(m_head, ehlen);
iphlen = ip->ip_hl << 2;
-
- PULLUP_HDR(m_head, ehlen + iphlen + sizeof(*th));
- th = mtodo(m_head, ehlen + iphlen);
- if (th->th_flags & TH_SYN)
- *tcpsyn = 1;
+ m_head->m_pkthdr.l3hlen = iphlen;
}
#endif
#if defined(INET6) && defined(INET)
@@ -814,18 +810,36 @@
PULLUP_HDR(m_head, ehlen + sizeof(*ip6));
ip6 = mtodo(m_head, ehlen);
- if (ip6->ip6_nxt != IPPROTO_TCP)
- return (m_head);
-
- PULLUP_HDR(m_head, ehlen + sizeof(*ip6) + sizeof(*th));
- th = mtodo(m_head, ehlen + sizeof(*ip6));
- if (th->th_flags & TH_SYN)
- *tcpsyn = 1;
+ if (ip6->ip6_nxt != IPPROTO_TCP) {
+ m_freem(m_head);
+ return (NULL);
+ }
+ m_head->m_pkthdr.l3hlen = sizeof(*ip6);
}
#endif
return (m_head);
}
+/*
+ * NOTE: If this function failed, the m_head would be freed.
+ */
+static __inline struct mbuf *
+hn_check_tcpsyn(struct mbuf *m_head, int *tcpsyn)
+{
+ const struct tcphdr *th;
+ int ehlen, iphlen;
+
+ *tcpsyn = 0;
+ ehlen = m_head->m_pkthdr.l2hlen;
+ iphlen = m_head->m_pkthdr.l3hlen;
+
+ PULLUP_HDR(m_head, ehlen + iphlen + sizeof(*th));
+ th = mtodo(m_head, ehlen + iphlen);
+ if (th->th_flags & TH_SYN)
+ *tcpsyn = 1;
+ return (m_head);
+}
+
#undef PULLUP_HDR
#endif /* INET6 || INET */
@@ -3010,7 +3024,8 @@
NDIS_LSO2_INFO_SIZE, NDIS_PKTINFO_TYPE_LSO);
#ifdef INET
if (m_head->m_pkthdr.csum_flags & CSUM_IP_TSO) {
- *pi_data = NDIS_LSO2_INFO_MAKEIPV4(0,
+ *pi_data = NDIS_LSO2_INFO_MAKEIPV4(
+ m_head->m_pkthdr.l2hlen + m_head->m_pkthdr.l3hlen,
m_head->m_pkthdr.tso_segsz);
}
#endif
@@ -3019,7 +3034,8 @@
#endif
#ifdef INET6
{
- *pi_data = NDIS_LSO2_INFO_MAKEIPV6(0,
+ *pi_data = NDIS_LSO2_INFO_MAKEIPV6(
+ m_head->m_pkthdr.l2hlen + m_head->m_pkthdr.l3hlen,
m_head->m_pkthdr.tso_segsz);
}
#endif
@@ -3036,11 +3052,15 @@
*pi_data |= NDIS_TXCSUM_INFO_IPCS;
}
- if (m_head->m_pkthdr.csum_flags & (CSUM_IP_TCP | CSUM_IP6_TCP))
- *pi_data |= NDIS_TXCSUM_INFO_TCPCS;
- else if (m_head->m_pkthdr.csum_flags &
- (CSUM_IP_UDP | CSUM_IP6_UDP))
- *pi_data |= NDIS_TXCSUM_INFO_UDPCS;
+ if (m_head->m_pkthdr.csum_flags &
+ (CSUM_IP_TCP | CSUM_IP6_TCP)) {
+ *pi_data |= NDIS_TXCSUM_INFO_MKTCPCS(
+ m_head->m_pkthdr.l2hlen + m_head->m_pkthdr.l3hlen);
+ } else if (m_head->m_pkthdr.csum_flags &
+ (CSUM_IP_UDP | CSUM_IP6_UDP)) {
+ *pi_data |= NDIS_TXCSUM_INFO_MKUDPCS(
+ m_head->m_pkthdr.l2hlen + m_head->m_pkthdr.l3hlen);
+ }
}
pkt_hlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen;
@@ -5566,6 +5586,13 @@
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
continue;
}
+ } else if (m_head->m_pkthdr.csum_flags &
+ (CSUM_IP_UDP | CSUM_IP_TCP | CSUM_IP6_UDP | CSUM_IP6_TCP)) {
+ m_head = hn_set_hlen(m_head);
+ if (__predict_false(m_head == NULL)) {
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ continue;
+ }
}
#endif
@@ -5846,8 +5873,8 @@
#if defined(INET6) || defined(INET)
/*
- * Perform TSO packet header fixup now, since the TSO
- * packet header should be cache-hot.
+ * Perform TSO packet header fixup or get l2/l3 header length now,
+ * since packet headers should be cache-hot.
*/
if (m->m_pkthdr.csum_flags & CSUM_TSO) {
m = hn_tso_fixup(m);
@@ -5855,6 +5882,13 @@
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
return EIO;
}
+ } else if (m->m_pkthdr.csum_flags &
+ (CSUM_IP_UDP | CSUM_IP_TCP | CSUM_IP6_UDP | CSUM_IP6_TCP)) {
+ m = hn_set_hlen(m);
+ if (__predict_false(m == NULL)) {
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ return EIO;
+ }
}
#endif
Index: sys/dev/hyperv/netvsc/ndis.h
===================================================================
--- sys/dev/hyperv/netvsc/ndis.h
+++ sys/dev/hyperv/netvsc/ndis.h
@@ -402,4 +402,13 @@
#define NDIS_TXCSUM_INFO_IPCS 0x00000010
#define NDIS_TXCSUM_INFO_THOFF 0x03ff0000
+#define NDIS_TXCSUM_INFO_MKL4CS(thoff, flag) \
+ ((((uint32_t)(thoff)) << 16) | (flag))
+
+#define NDIS_TXCSUM_INFO_MKTCPCS(thoff) \
+ NDIS_TXCSUM_INFO_MKL4CS((thoff), NDIS_TXCSUM_INFO_TCPCS)
+
+#define NDIS_TXCSUM_INFO_MKUDPCS(thoff) \
+ NDIS_TXCSUM_INFO_MKL4CS((thoff), NDIS_TXCSUM_INFO_UDPCS)
+
#endif /* !_NET_NDIS_H_ */

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 14, 3:22 AM (20 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15790606
Default Alt Text
D12417.id33233.diff (5 KB)

Event Timeline