summaryrefslogtreecommitdiff
path: root/net/ipv6/ip6_gre.c
diff options
context:
space:
mode:
authorAlexander Duyck <aduyck@mirantis.com>2016-04-14 22:33:51 +0300
committerDavid S. Miller <davem@davemloft.net>2016-04-17 02:09:13 +0300
commitac4eb009e4776e9ef4c0484865c2f5a3786eecae (patch)
tree003dff017535f1fff6a2fba35886a203a0650fa0 /net/ipv6/ip6_gre.c
parenta9e242ca43b13e5a5d176f97dfd2481c339934b7 (diff)
downloadlinux-ac4eb009e4776e9ef4c0484865c2f5a3786eecae.tar.xz
ip6gre: Add support for basic offloads offloads excluding GSO
This patch adds support for the basic offloads we support on most devices. Specifically with this patch set we can support checksum offload, basic scatter-gather, and highdma. Signed-off-by: Alexander Duyck <aduyck@mirantis.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_gre.c')
-rw-r--r--net/ipv6/ip6_gre.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 2be66e7b4a78..1a5ad143be40 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -598,6 +598,18 @@ static void init_tel_txopt(struct ipv6_tel_txoption *opt, __u8 encap_limit)
opt->ops.opt_nflen = 8;
}
+static __sum16 gre6_checksum(struct sk_buff *skb)
+{
+ __wsum csum;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ csum = lco_csum(skb);
+ else
+ csum = skb_checksum(skb, sizeof(struct ipv6hdr),
+ skb->len - sizeof(struct ipv6hdr), 0);
+ return csum_fold(csum);
+}
+
static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
struct net_device *dev,
__u8 dsfield,
@@ -750,8 +762,7 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
}
if (tunnel->parms.o_flags&GRE_CSUM) {
*ptr = 0;
- *(__sum16 *)ptr = ip_compute_csum((void *)(ipv6h+1),
- skb->len - sizeof(struct ipv6hdr));
+ *(__sum16 *)ptr = gre6_checksum(skb);
}
}
@@ -1507,6 +1518,11 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = {
.ndo_get_iflink = ip6_tnl_get_iflink,
};
+#define GRE6_FEATURES (NETIF_F_SG | \
+ NETIF_F_FRAGLIST | \
+ NETIF_F_HIGHDMA | \
+ NETIF_F_HW_CSUM)
+
static void ip6gre_tap_setup(struct net_device *dev)
{
@@ -1540,6 +1556,9 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
nt->net = dev_net(dev);
ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]);
+ dev->features |= GRE6_FEATURES;
+ dev->hw_features |= GRE6_FEATURES;
+
/* Can use a lockless transmit, unless we generate output sequences */
if (!(nt->parms.o_flags & GRE_SEQ))
dev->features |= NETIF_F_LLTX;