Skip to content

Commit

Permalink
ipv6: sr: fix seg6 encap performances with TSO enabled
Browse files Browse the repository at this point in the history
Enabling TSO can lead to abysmal performances when using seg6 in
encap mode, such as with the ixgbe driver. This patch adds a call to
iptunnel_handle_offloads() to remove the encapsulation bit if needed.

Before:
root@comp4-seg6bpf:~# iperf3 -c fc00::55
Connecting to host fc00::55, port 5201
[  4] local fc45::4 port 36592 connected to fc00::55 port 5201
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec   196 KBytes  1.60 Mbits/sec   47   6.66 KBytes
[  4]   1.00-2.00   sec   304 KBytes  2.49 Mbits/sec  100   5.33 KBytes
[  4]   2.00-3.00   sec   284 KBytes  2.32 Mbits/sec   92   5.33 KBytes

After:
root@comp4-seg6bpf:~# iperf3 -c fc00::55
Connecting to host fc00::55, port 5201
[  4] local fc45::4 port 43062 connected to fc00::55 port 5201
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec  1.03 GBytes  8.89 Gbits/sec    0    743 KBytes
[  4]   1.00-2.00   sec  1.03 GBytes  8.87 Gbits/sec    0    743 KBytes
[  4]   2.00-3.00   sec  1.03 GBytes  8.87 Gbits/sec    0    743 KBytes

Reported-by: Tom Herbert <tom@quantonium.net>
Fixes: 6c8702c ("ipv6: sr: add support for SRH encapsulation and injection with lwtunnels")
Signed-off-by: David Lebrun <dlebrun@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David Lebrun authored and David S. Miller committed Mar 30, 2018
1 parent f97c3dc commit 5807b22
Showing 1 changed file with 7 additions and 9 deletions.
16 changes: 7 additions & 9 deletions net/ipv6/seg6_iptunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/net.h>
#include <linux/module.h>
#include <net/ip.h>
#include <net/ip_tunnels.h>
#include <net/lwtunnel.h>
#include <net/netevent.h>
#include <net/netns/generic.h>
Expand Down Expand Up @@ -211,11 +212,6 @@ static int seg6_do_srh(struct sk_buff *skb)

tinfo = seg6_encap_lwtunnel(dst->lwtstate);

if (likely(!skb->encapsulation)) {
skb_reset_inner_headers(skb);
skb->encapsulation = 1;
}

switch (tinfo->mode) {
case SEG6_IPTUN_MODE_INLINE:
if (skb->protocol != htons(ETH_P_IPV6))
Expand All @@ -224,10 +220,12 @@ static int seg6_do_srh(struct sk_buff *skb)
err = seg6_do_srh_inline(skb, tinfo->srh);
if (err)
return err;

skb_reset_inner_headers(skb);
break;
case SEG6_IPTUN_MODE_ENCAP:
err = iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6);
if (err)
return err;

if (skb->protocol == htons(ETH_P_IPV6))
proto = IPPROTO_IPV6;
else if (skb->protocol == htons(ETH_P_IP))
Expand All @@ -239,6 +237,8 @@ static int seg6_do_srh(struct sk_buff *skb)
if (err)
return err;

skb_set_inner_transport_header(skb, skb_transport_offset(skb));
skb_set_inner_protocol(skb, skb->protocol);
skb->protocol = htons(ETH_P_IPV6);
break;
case SEG6_IPTUN_MODE_L2ENCAP:
Expand All @@ -262,8 +262,6 @@ static int seg6_do_srh(struct sk_buff *skb)
ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
skb_set_transport_header(skb, sizeof(struct ipv6hdr));

skb_set_inner_protocol(skb, skb->protocol);

return 0;
}

Expand Down

0 comments on commit 5807b22

Please sign in to comment.