diff options
author | Eric Dumazet <edumazet@google.com> | 2013-10-20 23:47:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-21 18:49:39 -0400 |
commit | 61c1db7fae21ed33c614356a43bf6580c5e53118 (patch) | |
tree | 74e9756895dcf0006f57791684f6435d29c226ab /net/ipv6/sit.c | |
parent | d3e5e0062de5f2c6444455b5708a62a50c93a50c (diff) |
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 <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r-- | net/ipv6/sit.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 19269453a8ea..3a9038dd818d 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -933,10 +933,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
933 | ttl = iph6->hop_limit; | 933 | ttl = iph6->hop_limit; |
934 | tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); | 934 | tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); |
935 | 935 | ||
936 | if (likely(!skb->encapsulation)) { | 936 | skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT); |
937 | skb_reset_inner_headers(skb); | 937 | if (IS_ERR(skb)) |
938 | skb->encapsulation = 1; | 938 | goto out; |
939 | } | ||
940 | 939 | ||
941 | err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, | 940 | err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, |
942 | ttl, df, !net_eq(tunnel->net, dev_net(dev))); | 941 | ttl, df, !net_eq(tunnel->net, dev_net(dev))); |
@@ -946,8 +945,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
946 | tx_error_icmp: | 945 | tx_error_icmp: |
947 | dst_link_failure(skb); | 946 | dst_link_failure(skb); |
948 | tx_error: | 947 | tx_error: |
949 | dev->stats.tx_errors++; | ||
950 | dev_kfree_skb(skb); | 948 | dev_kfree_skb(skb); |
949 | out: | ||
950 | dev->stats.tx_errors++; | ||
951 | return NETDEV_TX_OK; | 951 | return NETDEV_TX_OK; |
952 | } | 952 | } |
953 | 953 | ||
@@ -956,13 +956,15 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
956 | struct ip_tunnel *tunnel = netdev_priv(dev); | 956 | struct ip_tunnel *tunnel = netdev_priv(dev); |
957 | const struct iphdr *tiph = &tunnel->parms.iph; | 957 | const struct iphdr *tiph = &tunnel->parms.iph; |
958 | 958 | ||
959 | if (likely(!skb->encapsulation)) { | 959 | skb = iptunnel_handle_offloads(skb, false, SKB_GSO_IPIP); |
960 | skb_reset_inner_headers(skb); | 960 | if (IS_ERR(skb)) |
961 | skb->encapsulation = 1; | 961 | goto out; |
962 | } | ||
963 | 962 | ||
964 | ip_tunnel_xmit(skb, dev, tiph, IPPROTO_IPIP); | 963 | ip_tunnel_xmit(skb, dev, tiph, IPPROTO_IPIP); |
965 | return NETDEV_TX_OK; | 964 | return NETDEV_TX_OK; |
965 | out: | ||
966 | dev->stats.tx_errors++; | ||
967 | return NETDEV_TX_OK; | ||
966 | } | 968 | } |
967 | 969 | ||
968 | static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb, | 970 | static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb, |
@@ -1292,6 +1294,12 @@ static void ipip6_dev_free(struct net_device *dev) | |||
1292 | free_netdev(dev); | 1294 | free_netdev(dev); |
1293 | } | 1295 | } |
1294 | 1296 | ||
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 | |||
1295 | static void ipip6_tunnel_setup(struct net_device *dev) | 1303 | static void ipip6_tunnel_setup(struct net_device *dev) |
1296 | { | 1304 | { |
1297 | dev->netdev_ops = &ipip6_netdev_ops; | 1305 | dev->netdev_ops = &ipip6_netdev_ops; |
@@ -1305,6 +1313,8 @@ static void ipip6_tunnel_setup(struct net_device *dev) | |||
1305 | dev->iflink = 0; | 1313 | dev->iflink = 0; |
1306 | dev->addr_len = 4; | 1314 | dev->addr_len = 4; |
1307 | dev->features |= NETIF_F_LLTX; | 1315 | dev->features |= NETIF_F_LLTX; |
1316 | dev->features |= SIT_FEATURES; | ||
1317 | dev->hw_features |= SIT_FEATURES; | ||
1308 | } | 1318 | } |
1309 | 1319 | ||
1310 | static int ipip6_tunnel_init(struct net_device *dev) | 1320 | static int ipip6_tunnel_init(struct net_device *dev) |