aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-05-24 08:26:29 +0000
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-10-22 21:13:48 -0700
commita048b40e0f9502bc75d7f9904c5399a0a87fa479 (patch)
treedb65df2be656ad4bf22239dd7653fe3ee07b06b2 /drivers/net/ethernet/intel
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>
Diffstat (limited to 'drivers/net/ethernet/intel')
-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,
struct vlan_hdr *vlan;
/* l3 headers */
struct iphdr *ipv4;
+ struct ipv6hdr *ipv6;
} hdr;
__be16 protocol;
u8 nexthdr = 0; /* default to not TCP */
@@ -1284,6 +1285,13 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
/* record next protocol */
nexthdr = hdr.ipv4->protocol;
hdr.network += hlen;
+ } else if (protocol == __constant_htons(ETH_P_IPV6)) {
+ if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))
+ return max_len;
+
+ /* record next protocol */
+ nexthdr = hdr.ipv6->nexthdr;
+ hdr.network += sizeof(struct ipv6hdr);
#ifdef IXGBE_FCOE
} else if (protocol == __constant_htons(ETH_P_FCOE)) {
if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN))
@@ -1294,7 +1302,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
return hdr.network - data;
}
- /* finally sort out TCP */
+ /* finally sort out TCP/UDP */
if (nexthdr == IPPROTO_TCP) {
if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))
return max_len;
@@ -1307,6 +1315,11 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
return hdr.network - data;
hdr.network += hlen;
+ } else if (nexthdr == IPPROTO_UDP) {
+ if ((hdr.network - data) > (max_len - sizeof(struct udphdr)))
+ return max_len;
+
+ hdr.network += sizeof(struct udphdr);
}
/*