Bug 693430

Summary: [5.3] e1000e: TX bytes stats are over-reported when NAT is enabled and used
Product: Red Hat Enterprise Linux 5 Reporter: Flavio Leitner <fleitner>
Component: kernelAssignee: Flavio Leitner <fleitner>
Status: CLOSED INSUFFICIENT_DATA QA Contact: Red Hat Kernel QE team <kernel-qe>
Severity: high Docs Contact:
Priority: high    
Version: 5.3CC: james.leddy
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 699490 (view as bug list) Environment:
Last Closed: 2011-05-30 18:17:52 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Bug Depends On:    
Bug Blocks: 699490    

Description Flavio Leitner 2011-04-04 16:17:42 UTC
Description of problem:

A NAT rule might use skb_copy() which returns a linear skb.  However, if the original skb is non-linear, the gso headers confuses the e1000e driver which reports the wrong number of tx bytes.

The driver does:
[...]
        segs = skb_shinfo(skb)->gso_segs ? : 1;
        /* multiply data chunks by size of headers */
        bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;

The skb_headlen() will return the full packet length for a linear skb and not just the packet headers.  As the segs is not 0 because before it was a non-linear, then the driver will actually multiply the total packet length by the number of segs which is clearly incorrect.

Version-Release number of selected component (if applicable):
2.6.18-254.el5

How reproducible:
Always

Steps to Reproduce:
1. on the server, add the iptables rule and run the tcp_send.pl reproducer
2. on the client, run the tcp_client.pl
3. compare the statistics when the client connects to the original port with the redirected port.

Server:
# iptables -t nat -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,ACK SYN --dport  8888 -j REDIRECT --to-ports  8877

# ./tcp_send.pl -p 8877 &

client connecting directly:
$ ./tcp_receive.pl  -s server_ip:8877  10m

or
client connecting to the redirected port:
$ ./tcp_receive.pl  -s server_ip:8877  10m
 
Actual results:
This is when connecting directly:
# sar -n DEV 2 2 | egrep 'IFACE|eth2'
Average:        IFACE   rxpck/s   txpck/s   rxbyt/s   txbyt/s   rxcmp/s   txcmp/s  rxmcst/s
Average:         eth2    415.25    912.25  27406.50 1312921.50      0.00      0.00      0.00

This is when connecting to the redirected port:
Average:         eth2    415.50    914.50  27421.50 8838014.00      0.00      0.00      0.00


Expected results:
The same amount to be reported.