Hide Forgot
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.