aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/igb
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-11-12 20:13:38 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-11-22 05:01:04 -0500
commitf2fb4ab2a647d6576812cbb3ae1979538112f6c8 (patch)
tree9f489e21310da7f1943dbe15797dbf03c278d8fb /drivers/net/ethernet/intel/igb
parent63d4a8f963fce8fe5d8ba3d5eba34d7d7ca6f82b (diff)
igb: Do not parse past IP header on fragments beyond the first
This change makes it so that only the first fragment in a series of fragments will have the L4 header pulled. Previously we were always pulling the L4 header as well and in the case of UDP this can harm performance since only the first fragment will have the header, the rest just contain data which should be left in the paged portion of the packet. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igb')
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 0fe25210629b..0ce145e93545 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -6145,20 +6145,23 @@ static unsigned int igb_get_headlen(unsigned char *data,
6145 if (hlen < sizeof(struct iphdr)) 6145 if (hlen < sizeof(struct iphdr))
6146 return hdr.network - data; 6146 return hdr.network - data;
6147 6147
6148 /* record next protocol */ 6148 /* record next protocol if header is present */
6149 nexthdr = hdr.ipv4->protocol; 6149 if (!hdr.ipv4->frag_off)
6150 hdr.network += hlen; 6150 nexthdr = hdr.ipv4->protocol;
6151 } else if (protocol == __constant_htons(ETH_P_IPV6)) { 6151 } else if (protocol == __constant_htons(ETH_P_IPV6)) {
6152 if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr))) 6152 if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))
6153 return max_len; 6153 return max_len;
6154 6154
6155 /* record next protocol */ 6155 /* record next protocol */
6156 nexthdr = hdr.ipv6->nexthdr; 6156 nexthdr = hdr.ipv6->nexthdr;
6157 hdr.network += sizeof(struct ipv6hdr); 6157 hlen = sizeof(struct ipv6hdr);
6158 } else { 6158 } else {
6159 return hdr.network - data; 6159 return hdr.network - data;
6160 } 6160 }
6161 6161
6162 /* relocate pointer to start of L4 header */
6163 hdr.network += hlen;
6164
6162 /* finally sort out TCP */ 6165 /* finally sort out TCP */
6163 if (nexthdr == IPPROTO_TCP) { 6166 if (nexthdr == IPPROTO_TCP) {
6164 if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) 6167 if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))