Page MenuHomeFreeBSD

D7821.id20160.diff
No OneTemporary

D7821.id20160.diff

Index: sys/netinet/ip6.h
===================================================================
--- sys/netinet/ip6.h
+++ sys/netinet/ip6.h
@@ -108,6 +108,9 @@
#define IP6TOS_ECT 0x02 /* ECN-capable transport */
#endif
+#define IPV6_FLOW_TOS_SHIFT 20
+#define IPV6_FLOW_TOS_MASK 0xff
+
/*
* Extension Headers
*/
Index: sys/netinet/tcp_input.c
===================================================================
--- sys/netinet/tcp_input.c
+++ sys/netinet/tcp_input.c
@@ -735,7 +735,8 @@
#ifdef INET6
if (isipv6)
- iptos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
+ iptos = (ntohl(ip6->ip6_flow) >> IPV6_FLOW_TOS_SHIFT) &
+ IPV6_FLOW_TOS_MASK;
#endif
#if defined(INET) && defined(INET6)
else
Index: sys/netinet/tcp_lro.h
===================================================================
--- sys/netinet/tcp_lro.h
+++ sys/netinet/tcp_lro.h
@@ -67,6 +67,7 @@
uint32_t tsecr;
uint16_t window;
uint16_t timestamp; /* flag, not a TCP hdr field. */
+ uint8_t ecn; /* ECN bits from IP TOS field */
struct timeval mtime;
};
LIST_HEAD(lro_head, lro_entry);
Index: sys/netinet/tcp_lro.c
===================================================================
--- sys/netinet/tcp_lro.c
+++ sys/netinet/tcp_lro.c
@@ -309,6 +309,8 @@
void
tcp_lro_flush(struct lro_ctrl *lc, struct lro_entry *le)
{
+ uint32_t ipv6_flow;
+ uint8_t tos;
if (le->append_cnt > 0) {
struct tcphdr *th;
@@ -323,6 +325,10 @@
ip6 = le->le_ip6;
ip6->ip6_plen = p_len;
+ ipv6_flow = ntohl(ip6->ip6_flow);
+ ipv6_flow &= ~(IPTOS_ECN_MASK << IPV6_FLOW_TOS_SHIFT);
+ ipv6_flow |= le->ecn << IPV6_FLOW_TOS_SHIFT;
+ ip6->ip6_flow = htonl(ipv6_flow);
th = (struct tcphdr *)(ip6 + 1);
le->m_head->m_pkthdr.csum_flags = CSUM_DATA_VALID |
CSUM_PSEUDO_HDR;
@@ -358,6 +364,10 @@
le->m_head->m_pkthdr.csum_flags = CSUM_DATA_VALID |
CSUM_PSEUDO_HDR | CSUM_IP_CHECKED | CSUM_IP_VALID;
le->p_len += ETHER_HDR_LEN;
+ tos = ip4->ip_tos;
+ tos &= ~IPTOS_ECN_MASK;
+ tos |= le->ecn;
+ ip4->ip_tos = tos;
break;
}
#endif
@@ -615,6 +625,7 @@
uint16_t eh_type, tcp_data_len;
struct lro_head *bucket;
int force_flush = 0;
+ uint8_t ecn;
/* We expect a contiguous header [eh, ip, tcp]. */
@@ -637,6 +648,8 @@
return (error);
tcp_data_len = ntohs(ip6->ip6_plen);
ip_len = sizeof(*ip6) + tcp_data_len;
+ ecn = (ntohl(ip6->ip6_flow) >> IPV6_FLOW_TOS_SHIFT) &
+ IPTOS_ECN_MASK;
break;
}
#endif
@@ -656,6 +669,7 @@
return (error);
ip_len = ntohs(ip4->ip_len);
tcp_data_len = ip_len - sizeof(*ip4);
+ ecn = ip4->ip_tos & IPTOS_ECN_MASK;
break;
}
#endif
@@ -822,6 +836,13 @@
tcp_data_len, ~csum);
#endif
+ /*
+ * If CE has been flagged on any packet, then CE needs to be set
+ * on the IP header when we send the packet up the stack.
+ */
+ if (ecn == IPTOS_ECN_CE)
+ le->ecn = ecn;
+
if (tcp_data_len == 0) {
m_freem(m);
/*
@@ -888,6 +909,7 @@
le->dest_ip6 = ip6->ip6_dst;
le->eh_type = eh_type;
le->p_len = m->m_pkthdr.len - ETHER_HDR_LEN - sizeof(*ip6);
+ le->ecn = ecn;
break;
#endif
#ifdef INET
@@ -897,6 +919,7 @@
le->dest_ip4 = ip4->ip_dst.s_addr;
le->eh_type = eh_type;
le->p_len = m->m_pkthdr.len - ETHER_HDR_LEN;
+ le->ecn = ecn;
break;
#endif
}
Index: sys/netinet/tcp_output.c
===================================================================
--- sys/netinet/tcp_output.c
+++ sys/netinet/tcp_output.c
@@ -1146,7 +1146,8 @@
!((tp->t_flags & TF_FORCEDATA) && len == 1)) {
#ifdef INET6
if (isipv6)
- ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
+ ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 <<
+ IPV6_FLOW_TOS_SHIFT);
else
#endif
ip->ip_tos |= IPTOS_ECN_ECT0;

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 21, 3:40 AM (13 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27106449
Default Alt Text
D7821.id20160.diff (3 KB)

Event Timeline