GRE: Disable segmentation offloads w/ CSUM and we are encapsulated via FOU
This patch fixes an issue I found in which we were dropping frames if we
had enabled checksums on GRE headers that were encapsulated by either FOU
or GUE. Without this patch I was barely able to get 1 Gb/s of throughput.
With this patch applied I am now at least getting around 6 Gb/s.
The issue is due to the fact that with FOU or GUE applied we do not provide
a transport offset pointing to the GRE header, nor do we offload it in
software as the GRE header is completely skipped by GSO and treated like a
VXLAN or GENEVE type header. As such we need to prevent the stack from
generating it and also prevent GRE from generating it via any interface we
create.
Fixes: c3483384ee
("gro: Allow tunnel stacking in the case of FOU/GUE")
Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0a1a37b6d6
commit
a0ca153f98
5 changed files with 29 additions and 4 deletions
|
@ -203,6 +203,9 @@ static struct sk_buff **fou_gro_receive(struct sk_buff **head,
|
|||
*/
|
||||
NAPI_GRO_CB(skb)->encap_mark = 0;
|
||||
|
||||
/* Flag this frame as already having an outer encap header */
|
||||
NAPI_GRO_CB(skb)->is_fou = 1;
|
||||
|
||||
rcu_read_lock();
|
||||
offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
|
||||
ops = rcu_dereference(offloads[proto]);
|
||||
|
@ -368,6 +371,9 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head,
|
|||
*/
|
||||
NAPI_GRO_CB(skb)->encap_mark = 0;
|
||||
|
||||
/* Flag this frame as already having an outer encap header */
|
||||
NAPI_GRO_CB(skb)->is_fou = 1;
|
||||
|
||||
rcu_read_lock();
|
||||
offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
|
||||
ops = rcu_dereference(offloads[guehdr->proto_ctype]);
|
||||
|
|
|
@ -150,6 +150,14 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head,
|
|||
if ((greh->flags & ~(GRE_KEY|GRE_CSUM)) != 0)
|
||||
goto out;
|
||||
|
||||
/* We can only support GRE_CSUM if we can track the location of
|
||||
* the GRE header. In the case of FOU/GUE we cannot because the
|
||||
* outer UDP header displaces the GRE header leaving us in a state
|
||||
* of limbo.
|
||||
*/
|
||||
if ((greh->flags & GRE_CSUM) && NAPI_GRO_CB(skb)->is_fou)
|
||||
goto out;
|
||||
|
||||
type = greh->protocol;
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
|
@ -862,9 +862,16 @@ static void __gre_tunnel_init(struct net_device *dev)
|
|||
dev->hw_features |= GRE_FEATURES;
|
||||
|
||||
if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
|
||||
/* TCP offload with GRE SEQ is not supported. */
|
||||
dev->features |= NETIF_F_GSO_SOFTWARE;
|
||||
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
|
||||
/* TCP offload with GRE SEQ is not supported, nor
|
||||
* can we support 2 levels of outer headers requiring
|
||||
* an update.
|
||||
*/
|
||||
if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
|
||||
(tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
|
||||
dev->features |= NETIF_F_GSO_SOFTWARE;
|
||||
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
|
||||
}
|
||||
|
||||
/* Can use a lockless transmit, unless we generate
|
||||
* output sequences
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue