Skip to content

Commit 61c1db7

Browse files
Eric Dumazetdavem330
authored andcommitted
ipv6: sit: add GSO/TSO support
Now ipv6_gso_segment() is stackable, its relatively easy to implement GSO/TSO support for SIT tunnels Performance results, when segmentation is done after tunnel device (as no NIC is yet enabled for TSO SIT support) : Before patch : lpq84:~# ./netperf -H 2002:af6:1153:: -Cc MIGRATED TCP STREAM TEST from ::0 (::) port 0 AF_INET6 to 2002:af6:1153:: () port 0 AF_INET6 Recv Send Send Utilization Service Demand Socket Socket Message Elapsed Send Recv Send Recv Size Size Size Time Throughput local remote local remote bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB 87380 16384 16384 10.00 3168.31 4.81 4.64 2.988 2.877 After patch : lpq84:~# ./netperf -H 2002:af6:1153:: -Cc MIGRATED TCP STREAM TEST from ::0 (::) port 0 AF_INET6 to 2002:af6:1153:: () port 0 AF_INET6 Recv Send Send Utilization Service Demand Socket Socket Message Elapsed Send Recv Send Recv Size Size Size Time Throughput local remote local remote bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB 87380 16384 16384 10.00 5525.00 7.76 5.17 2.763 1.840 Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d3e5e00 commit 61c1db7

File tree

8 files changed

+40
-11
lines changed

8 files changed

+40
-11
lines changed

include/linux/netdev_features.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum {
4343
NETIF_F_FSO_BIT, /* ... FCoE segmentation */
4444
NETIF_F_GSO_GRE_BIT, /* ... GRE with TSO */
4545
NETIF_F_GSO_IPIP_BIT, /* ... IPIP tunnel with TSO */
46+
NETIF_F_GSO_SIT_BIT, /* ... SIT tunnel with TSO */
4647
NETIF_F_GSO_UDP_TUNNEL_BIT, /* ... UDP TUNNEL with TSO */
4748
NETIF_F_GSO_MPLS_BIT, /* ... MPLS segmentation */
4849
/**/NETIF_F_GSO_LAST = /* last bit, see GSO_MASK */
@@ -109,6 +110,7 @@ enum {
109110
#define NETIF_F_RXALL __NETIF_F(RXALL)
110111
#define NETIF_F_GSO_GRE __NETIF_F(GSO_GRE)
111112
#define NETIF_F_GSO_IPIP __NETIF_F(GSO_IPIP)
113+
#define NETIF_F_GSO_SIT __NETIF_F(GSO_SIT)
112114
#define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL)
113115
#define NETIF_F_GSO_MPLS __NETIF_F(GSO_MPLS)
114116
#define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER)

include/linux/skbuff.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,11 @@ enum {
320320

321321
SKB_GSO_IPIP = 1 << 7,
322322

323-
SKB_GSO_UDP_TUNNEL = 1 << 8,
323+
SKB_GSO_SIT = 1 << 8,
324324

325-
SKB_GSO_MPLS = 1 << 9,
325+
SKB_GSO_UDP_TUNNEL = 1 << 9,
326+
327+
SKB_GSO_MPLS = 1 << 10,
326328
};
327329

328330
#if BITS_PER_LONG > 32

net/core/ethtool.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
8282
[NETIF_F_FSO_BIT] = "tx-fcoe-segmentation",
8383
[NETIF_F_GSO_GRE_BIT] = "tx-gre-segmentation",
8484
[NETIF_F_GSO_IPIP_BIT] = "tx-ipip-segmentation",
85+
[NETIF_F_GSO_SIT_BIT] = "tx-sit-segmentation",
8586
[NETIF_F_GSO_UDP_TUNNEL_BIT] = "tx-udp_tnl-segmentation",
8687
[NETIF_F_GSO_MPLS_BIT] = "tx-mpls-segmentation",
8788

net/ipv4/af_inet.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,6 +1265,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
12651265
SKB_GSO_TCP_ECN |
12661266
SKB_GSO_GRE |
12671267
SKB_GSO_IPIP |
1268+
SKB_GSO_SIT |
12681269
SKB_GSO_TCPV6 |
12691270
SKB_GSO_UDP_TUNNEL |
12701271
SKB_GSO_MPLS |

net/ipv4/tcp_offload.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
5757
SKB_GSO_TCPV6 |
5858
SKB_GSO_GRE |
5959
SKB_GSO_IPIP |
60+
SKB_GSO_SIT |
6061
SKB_GSO_MPLS |
6162
SKB_GSO_UDP_TUNNEL |
6263
0) ||

net/ipv6/ip6_offload.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
9898
SKB_GSO_TCP_ECN |
9999
SKB_GSO_GRE |
100100
SKB_GSO_IPIP |
101+
SKB_GSO_SIT |
101102
SKB_GSO_UDP_TUNNEL |
102103
SKB_GSO_MPLS |
103104
SKB_GSO_TCPV6 |
@@ -276,6 +277,13 @@ static struct packet_offload ipv6_packet_offload __read_mostly = {
276277
},
277278
};
278279

280+
static const struct net_offload sit_offload = {
281+
.callbacks = {
282+
.gso_send_check = ipv6_gso_send_check,
283+
.gso_segment = ipv6_gso_segment,
284+
},
285+
};
286+
279287
static int __init ipv6_offload_init(void)
280288
{
281289

@@ -287,6 +295,9 @@ static int __init ipv6_offload_init(void)
287295
pr_crit("%s: Cannot add EXTHDRS protocol offload\n", __func__);
288296

289297
dev_add_offload(&ipv6_packet_offload);
298+
299+
inet_add_offload(&sit_offload, IPPROTO_IPV6);
300+
290301
return 0;
291302
}
292303

net/ipv6/sit.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -933,10 +933,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
933933
ttl = iph6->hop_limit;
934934
tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
935935

936-
if (likely(!skb->encapsulation)) {
937-
skb_reset_inner_headers(skb);
938-
skb->encapsulation = 1;
939-
}
936+
skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT);
937+
if (IS_ERR(skb))
938+
goto out;
940939

941940
err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos,
942941
ttl, df, !net_eq(tunnel->net, dev_net(dev)));
@@ -946,8 +945,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
946945
tx_error_icmp:
947946
dst_link_failure(skb);
948947
tx_error:
949-
dev->stats.tx_errors++;
950948
dev_kfree_skb(skb);
949+
out:
950+
dev->stats.tx_errors++;
951951
return NETDEV_TX_OK;
952952
}
953953

@@ -956,13 +956,15 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
956956
struct ip_tunnel *tunnel = netdev_priv(dev);
957957
const struct iphdr *tiph = &tunnel->parms.iph;
958958

959-
if (likely(!skb->encapsulation)) {
960-
skb_reset_inner_headers(skb);
961-
skb->encapsulation = 1;
962-
}
959+
skb = iptunnel_handle_offloads(skb, false, SKB_GSO_IPIP);
960+
if (IS_ERR(skb))
961+
goto out;
963962

964963
ip_tunnel_xmit(skb, dev, tiph, IPPROTO_IPIP);
965964
return NETDEV_TX_OK;
965+
out:
966+
dev->stats.tx_errors++;
967+
return NETDEV_TX_OK;
966968
}
967969

968970
static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
@@ -1292,6 +1294,12 @@ static void ipip6_dev_free(struct net_device *dev)
12921294
free_netdev(dev);
12931295
}
12941296

1297+
#define SIT_FEATURES (NETIF_F_SG | \
1298+
NETIF_F_FRAGLIST | \
1299+
NETIF_F_HIGHDMA | \
1300+
NETIF_F_GSO_SOFTWARE | \
1301+
NETIF_F_HW_CSUM)
1302+
12951303
static void ipip6_tunnel_setup(struct net_device *dev)
12961304
{
12971305
dev->netdev_ops = &ipip6_netdev_ops;
@@ -1305,6 +1313,8 @@ static void ipip6_tunnel_setup(struct net_device *dev)
13051313
dev->iflink = 0;
13061314
dev->addr_len = 4;
13071315
dev->features |= NETIF_F_LLTX;
1316+
dev->features |= SIT_FEATURES;
1317+
dev->hw_features |= SIT_FEATURES;
13081318
}
13091319

13101320
static int ipip6_tunnel_init(struct net_device *dev)

net/ipv6/udp_offload.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
6565
SKB_GSO_UDP_TUNNEL |
6666
SKB_GSO_GRE |
6767
SKB_GSO_IPIP |
68+
SKB_GSO_SIT |
6869
SKB_GSO_MPLS) ||
6970
!(type & (SKB_GSO_UDP))))
7071
goto out;

0 commit comments

Comments
 (0)