diff options
author | Vlad Yasevich <vyasevich@gmail.com> | 2015-01-31 10:40:18 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-02 19:28:05 -0800 |
commit | 32dce968dd987adfb0c00946d78dad9154f64759 (patch) | |
tree | b5005ef754bb0dd4d6b15a37d94be210e2ee9045 /net/ipv6 | |
parent | 03485f2adcde0c2d4e9228b659be78e872486bbb (diff) | |
download | linux-32dce968dd987adfb0c00946d78dad9154f64759.tar.gz linux-32dce968dd987adfb0c00946d78dad9154f64759.tar.bz2 linux-32dce968dd987adfb0c00946d78dad9154f64759.zip |
ipv6: Allow for partial checksums on non-ufo packets
Currntly, if we are not doing UFO on the packet, all UDP
packets will start with CHECKSUM_NONE and thus perform full
checksum computations in software even if device support
IPv6 checksum offloading.
Let's start start with CHECKSUM_PARTIAL if the device
supports it and we are sending only a single packet at
or below mtu size.
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_output.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index b89d3c27dac7..1a036f35d833 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1227,6 +1227,7 @@ static int __ip6_append_data(struct sock *sk, u32 tskey = 0; struct rt6_info *rt = (struct rt6_info *)cork->dst; struct ipv6_txoptions *opt = v6_cork->opt; + int csummode = CHECKSUM_NONE; skb = skb_peek_tail(queue); if (!skb) { @@ -1283,6 +1284,14 @@ emsgsize: tskey = sk->sk_tskey++; } + /* If this is the first and only packet and device + * supports checksum offloading, let's use it. + */ + if (!skb && + length + fragheaderlen < mtu && + rt->dst.dev->features & NETIF_F_V6_CSUM && + !exthdrlen) + csummode = CHECKSUM_PARTIAL; /* * Let's try using as much space as possible. * Use MTU if total length of the message fits into the MTU. @@ -1395,7 +1404,7 @@ alloc_new_skb: * Fill in the control structures */ skb->protocol = htons(ETH_P_IPV6); - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = csummode; skb->csum = 0; /* reserve for fragmentation and ipsec header */ skb_reserve(skb, hh_len + sizeof(struct frag_hdr) + |