aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-05-24 04:26:29 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-10-23 00:13:48 -0400
commita048b40e0f9502bc75d7f9904c5399a0a87fa479 (patch)
treedb65df2be656ad4bf22239dd7653fe3ee07b06b2
parentd94ce9b283736a876b2e6dec665c68e5e8b5d55e (diff)
ixgbe: Add support for IPv6 and UDP to ixgbe_get_headlen
This change adds support for IPv6 and UDP to ixgbe_get_headlen. The advantage to this is that we can now handle ipv4/UDP, ipv6/TCP, and ipv6/UDP with a single memcpy instead of having to do them in multiple pskb_may_pull calls. A quick bit of testing shows that we increase throughput for a single session of netperf from 8800Mpbs to about 9300Mpbs in the case of ipv6/TCP. As such overall ipv6 performance should improve with this change. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Stephen Ko <stephen.s.ko@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index e2a6691cbd7c..3ef74f893c2e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1244,6 +1244,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
1244 struct vlan_hdr *vlan; 1244 struct vlan_hdr *vlan;
1245 /* l3 headers */ 1245 /* l3 headers */
1246 struct iphdr *ipv4; 1246 struct iphdr *ipv4;
1247 struct ipv6hdr *ipv6;
1247 } hdr; 1248 } hdr;
1248 __be16 protocol; 1249 __be16 protocol;
1249 u8 nexthdr = 0; /* default to not TCP */ 1250 u8 nexthdr = 0; /* default to not TCP */
@@ -1284,6 +1285,13 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
1284 /* record next protocol */ 1285 /* record next protocol */
1285 nexthdr = hdr.ipv4->protocol; 1286 nexthdr = hdr.ipv4->protocol;
1286 hdr.network += hlen; 1287 hdr.network += hlen;
1288 } else if (protocol == __constant_htons(ETH_P_IPV6)) {
1289 if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))
1290 return max_len;
1291
1292 /* record next protocol */
1293 nexthdr = hdr.ipv6->nexthdr;
1294 hdr.network += sizeof(struct ipv6hdr);
1287#ifdef IXGBE_FCOE 1295#ifdef IXGBE_FCOE
1288 } else if (protocol == __constant_htons(ETH_P_FCOE)) { 1296 } else if (protocol == __constant_htons(ETH_P_FCOE)) {
1289 if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN)) 1297 if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN))
@@ -1294,7 +1302,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
1294 return hdr.network - data; 1302 return hdr.network - data;
1295 } 1303 }
1296 1304
1297 /* finally sort out TCP */ 1305 /* finally sort out TCP/UDP */
1298 if (nexthdr == IPPROTO_TCP) { 1306 if (nexthdr == IPPROTO_TCP) {
1299 if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) 1307 if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))
1300 return max_len; 1308 return max_len;
@@ -1307,6 +1315,11 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
1307 return hdr.network - data; 1315 return hdr.network - data;
1308 1316
1309 hdr.network += hlen; 1317 hdr.network += hlen;
1318 } else if (nexthdr == IPPROTO_UDP) {
1319 if ((hdr.network - data) > (max_len - sizeof(struct udphdr)))
1320 return max_len;
1321
1322 hdr.network += sizeof(struct udphdr);
1310 } 1323 }
1311 1324
1312 /* 1325 /*