From 3a61487a2dd33570f857a0dcd3653fa88d71a17f Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sat, 13 Aug 2011 10:29:44 -0700 Subject: [PATCH] Cleaned up payload length determination. --- sim_ether.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sim_ether.c b/sim_ether.c index 525f48bc..e15c1ad3 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -1971,8 +1971,12 @@ _eth_fix_ip_jumbo_offload(ETH_DEV* dev, const u_char* msg, int len) case IPPROTO_UDP: case IPPROTO_ICMP: ++dev->jumbo_fragmented; - payload_len = ntohs(IP->total_len) - IP_HLEN(IP); - mtu_payload = ETH_MIN_JUMBO_FRAME - 14 - IP_HLEN(IP); + /* When we're performing LSO (Large Send Offload), we're given a + 'template' header which may not include a value being populated + in the IP header length (which is only 16 bits). + We process as payload everything which isn't known header data. */ + payload_len = len - (14 + IP_HLEN(IP)); + mtu_payload = ETH_MIN_JUMBO_FRAME - (14 + IP_HLEN(IP)); frag_offset = 0; while (payload_len > 0) { ip_flags = frag_offset; @@ -2019,10 +2023,12 @@ _eth_fix_ip_jumbo_offload(ETH_DEV* dev, const u_char* msg, int len) eth_packet_trace_ex (dev, ((u_char *)IP)-14, len, "Fragmenting Jumbo TCP segment", 1, dev->dbit); TCP = (struct TCPHeader *)(((char *)IP)+IP_HLEN(IP)); orig_tcp_flags = ntohs(TCP->data_offset_and_flags); - if (0 == ntohs(IP->total_len)) /* Sometimes the IP header indicates a packet size of 0 */ - IP->total_len = htons(len-14); /* use the captured frame size to compute the IP length */ - payload_len = ntohs(IP->total_len) - (IP_HLEN(IP) + TCP_DATA_OFFSET(TCP)); - mtu_payload = ETH_MIN_JUMBO_FRAME - 14 - IP_HLEN(IP) - TCP_DATA_OFFSET(TCP); + /* When we're performing LSO (Large Send Offload), we're given a + 'template' header which may not include a value being populated + in the IP header length (which is only 16 bits). + We process as payload everything which isn't known header data. */ + payload_len = len - (14 + IP_HLEN(IP) + TCP_DATA_OFFSET(TCP)); + mtu_payload = ETH_MIN_JUMBO_FRAME - (14 + IP_HLEN(IP) + TCP_DATA_OFFSET(TCP)); while (payload_len > 0) { if (payload_len > mtu_payload) { TCP->data_offset_and_flags = htons(orig_tcp_flags&~(TCP_PSH_FLAG|TCP_FIN_FLAG|TCP_RST_FLAG));