Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136693617
D1761.id3606.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D1761.id3606.diff
View Options
Index: sys/netinet/ip_input.c
===================================================================
--- sys/netinet/ip_input.c
+++ sys/netinet/ip_input.c
@@ -442,7 +442,8 @@
struct ifaddr *ifa;
struct ifnet *ifp;
int checkif, hlen = 0;
- uint16_t sum, ip_len;
+ uint32_t ip_len;
+ uint16_t sum;
int dchg = 0; /* dest changed after fw */
struct in_addr odst; /* original dst address */
@@ -519,7 +520,10 @@
return;
#endif
- ip_len = ntohs(ip->ip_len);
+ if (M_HASHTYPE_GET(m) == M_HASHTYPE_LRO_TCP)
+ ip_len = m->m_pkthdr.len;
+ else
+ ip_len = ntohs(ip->ip_len);
if (ip_len < hlen) {
IPSTAT_INC(ips_badlen);
goto bad;
@@ -1443,6 +1447,7 @@
struct in_addr dest;
struct route ro;
int error, type = 0, code = 0, mtu = 0;
+ int ip_len;
if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) {
IPSTAT_INC(ips_cantforward);
@@ -1508,8 +1513,14 @@
m_free(mcopy);
mcopy = NULL;
}
+
+ if (M_HASHTYPE_GET(m) == M_HASHTYPE_LRO_TCP)
+ ip_len = m->m_pkthdr.len;
+ else
+ ip_len = ntohs(ip->ip_len);
+
if (mcopy != NULL) {
- mcopy->m_len = min(ntohs(ip->ip_len), M_TRAILINGSPACE(mcopy));
+ mcopy->m_len = min(ip_len, M_TRAILINGSPACE(mcopy));
mcopy->m_pkthdr.len = mcopy->m_len;
m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
}
@@ -1637,7 +1648,7 @@
if (ia != NULL)
mtu = ia->ia_ifp->if_mtu;
else
- mtu = ip_next_mtu(ntohs(ip->ip_len), 0);
+ mtu = ip_next_mtu(ip_len, 0);
}
IPSTAT_INC(ips_cantfrag);
break;
Index: sys/netinet/ip_output.c
===================================================================
--- sys/netinet/ip_output.c
+++ sys/netinet/ip_output.c
@@ -126,13 +126,14 @@
struct ifnet *ifp = NULL; /* keep compiler happy */
struct mbuf *m0;
int hlen = sizeof (struct ip);
+ int ip_len;
int mtu;
int error = 0;
struct sockaddr_in *dst;
const struct sockaddr_in *gw;
struct in_ifaddr *ia;
int isbroadcast;
- uint16_t ip_len, ip_off;
+ uint16_t ip_off;
struct route iproute;
struct rtentry *rte; /* cache for ro->ro_rt */
struct in_addr odst;
@@ -171,7 +172,11 @@
hlen = len; /* ip->ip_hl is updated above */
}
ip = mtod(m, struct ip *);
- ip_len = ntohs(ip->ip_len);
+
+ if (M_HASHTYPE_GET(m) == M_HASHTYPE_LRO_TCP)
+ ip_len = m->m_pkthdr.len;
+ else
+ ip_len = ntohs(ip->ip_len);
ip_off = ntohs(ip->ip_off);
/*
@@ -701,9 +706,13 @@
int firstlen;
struct mbuf **mnext;
int nfrags;
- uint16_t ip_len, ip_off;
+ int ip_len;
+ uint16_t ip_off;
- ip_len = ntohs(ip->ip_len);
+ if (M_HASHTYPE_GET(m0) == M_HASHTYPE_LRO_TCP)
+ ip_len = m0->m_pkthdr.len;
+ else
+ ip_len = ntohs(ip->ip_len);
ip_off = ntohs(ip->ip_off);
if (ip_off & IP_DF) { /* Fragmentation not allowed */
Index: sys/netinet/tcp_input.c
===================================================================
--- sys/netinet/tcp_input.c
+++ sys/netinet/tcp_input.c
@@ -644,7 +644,10 @@
ip6 = mtod(m, struct ip6_hdr *);
th = (struct tcphdr *)((caddr_t)ip6 + off0);
- tlen = sizeof(*ip6) + ntohs(ip6->ip6_plen) - off0;
+ if (M_HASHTYPE_GET(m) == M_HASHTYPE_LRO_TCP)
+ tlen = m->m_pkthdr.len - off0;
+ else
+ tlen = sizeof(*ip6) + ntohs(ip6->ip6_plen) - off0;
if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) {
if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
th->th_sum = m->m_pkthdr.csum_data;
@@ -695,8 +698,10 @@
}
ip = mtod(m, struct ip *);
th = (struct tcphdr *)((caddr_t)ip + off0);
- tlen = ntohs(ip->ip_len) - off0;
-
+ if (M_HASHTYPE_GET(m) == M_HASHTYPE_LRO_TCP)
+ tlen = m->m_pkthdr.len - off0;
+ else
+ tlen = ntohs(ip->ip_len) - off0;
if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
th->th_sum = m->m_pkthdr.csum_data;
Index: sys/netinet/tcp_lro.c
===================================================================
--- sys/netinet/tcp_lro.c
+++ sys/netinet/tcp_lro.c
@@ -62,6 +62,10 @@
#define LRO_ENTRIES 8 /* # of LRO entries per RX queue. */
#endif
+#ifndef LRO_PLEN_MAX
+#define LRO_PLEN_MAX 1048575 /* 1 MByte */
+#endif
+
#define TCP_LRO_UPDATE_CSUM 1
#ifndef TCP_LRO_UPDATE_CSUM
#define TCP_LRO_INVALID_CSUM 0x0000
@@ -218,9 +222,17 @@
if (le->append_cnt > 0) {
struct tcphdr *th;
- uint16_t p_len;
+ /*
+ * The TCP/IP stack should use the "m_pkthdr.len"
+ * field instead of the IP-payload length field to
+ * compute the total TCP payload length when it
+ * recognizes the M_HASHTYPE_LRO_TCP hash type. This
+ * allows accumulation of more than 64Kbytes worth of
+ * payload data.
+ */
+ enum { p_len = htons(65535) };
- p_len = htons(le->p_len);
+ M_HASHTYPE_SET(le->m_head, M_HASHTYPE_LRO_TCP);
switch (le->eh_type) {
#ifdef INET6
case ETHERTYPE_IPV6:
@@ -501,7 +513,7 @@
}
/* Flush now if appending will result in overflow. */
- if (le->p_len > (65535 - tcp_data_len)) {
+ if (le->p_len > (LRO_PLEN_MAX - tcp_data_len)) {
SLIST_REMOVE(&lc->lro_active, le, lro_entry, next);
tcp_lro_flush(lc, le);
break;
@@ -559,7 +571,7 @@
* If a possible next full length packet would cause an
* overflow, pro-actively flush now.
*/
- if (le->p_len > (65535 - lc->ifp->if_mtu)) {
+ if (le->p_len > (LRO_PLEN_MAX - lc->ifp->if_mtu)) {
SLIST_REMOVE(&lc->lro_active, le, lro_entry, next);
tcp_lro_flush(lc, le);
} else
Index: sys/sys/mbuf.h
===================================================================
--- sys/sys/mbuf.h
+++ sys/sys/mbuf.h
@@ -302,6 +302,7 @@
#define M_HASHTYPE_RSS_UDP_IPV6 9 /* IPv6 UDP 4-tuple */
#define M_HASHTYPE_RSS_UDP_IPV6_EX 10 /* IPv6 UDP 4-tuple + ext hdrs */
+#define M_HASHTYPE_LRO_TCP 254 /* TCP large receive offload */
#define M_HASHTYPE_OPAQUE 255 /* ordering, not affinity */
#define M_HASHTYPE_CLEAR(m) ((m)->m_pkthdr.rsstype = 0)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 19, 10:23 PM (10 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25685305
Default Alt Text
D1761.id3606.diff (5 KB)
Attached To
Mode
D1761: Extend LRO support to accumulate more than 65535 bytes
Attached
Detach File
Event Timeline
Log In to Comment