Commit a048b40e authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Kirsher

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: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Tested-by: default avatarStephen Ko  <stephen.s.ko@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent d94ce9b2
...@@ -1244,6 +1244,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, ...@@ -1244,6 +1244,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
struct vlan_hdr *vlan; struct vlan_hdr *vlan;
/* l3 headers */ /* l3 headers */
struct iphdr *ipv4; struct iphdr *ipv4;
struct ipv6hdr *ipv6;
} hdr; } hdr;
__be16 protocol; __be16 protocol;
u8 nexthdr = 0; /* default to not TCP */ u8 nexthdr = 0; /* default to not TCP */
...@@ -1284,6 +1285,13 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, ...@@ -1284,6 +1285,13 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
/* record next protocol */ /* record next protocol */
nexthdr = hdr.ipv4->protocol; nexthdr = hdr.ipv4->protocol;
hdr.network += hlen; 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 #ifdef IXGBE_FCOE
} else if (protocol == __constant_htons(ETH_P_FCOE)) { } else if (protocol == __constant_htons(ETH_P_FCOE)) {
if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN)) if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN))
...@@ -1294,7 +1302,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, ...@@ -1294,7 +1302,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
return hdr.network - data; return hdr.network - data;
} }
/* finally sort out TCP */ /* finally sort out TCP/UDP */
if (nexthdr == IPPROTO_TCP) { if (nexthdr == IPPROTO_TCP) {
if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))
return max_len; return max_len;
...@@ -1307,6 +1315,11 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, ...@@ -1307,6 +1315,11 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
return hdr.network - data; return hdr.network - data;
hdr.network += hlen; 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);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment