Commit 32dce968 authored by Vlad Yasevich's avatar Vlad Yasevich Committed by David S. Miller

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: default avatarVladislav Yasevich <vyasevic@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 03485f2a
...@@ -1227,6 +1227,7 @@ static int __ip6_append_data(struct sock *sk, ...@@ -1227,6 +1227,7 @@ static int __ip6_append_data(struct sock *sk,
u32 tskey = 0; u32 tskey = 0;
struct rt6_info *rt = (struct rt6_info *)cork->dst; struct rt6_info *rt = (struct rt6_info *)cork->dst;
struct ipv6_txoptions *opt = v6_cork->opt; struct ipv6_txoptions *opt = v6_cork->opt;
int csummode = CHECKSUM_NONE;
skb = skb_peek_tail(queue); skb = skb_peek_tail(queue);
if (!skb) { if (!skb) {
...@@ -1283,6 +1284,14 @@ static int __ip6_append_data(struct sock *sk, ...@@ -1283,6 +1284,14 @@ static int __ip6_append_data(struct sock *sk,
tskey = sk->sk_tskey++; 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. * Let's try using as much space as possible.
* Use MTU if total length of the message fits into the MTU. * Use MTU if total length of the message fits into the MTU.
...@@ -1395,7 +1404,7 @@ static int __ip6_append_data(struct sock *sk, ...@@ -1395,7 +1404,7 @@ static int __ip6_append_data(struct sock *sk,
* Fill in the control structures * Fill in the control structures
*/ */
skb->protocol = htons(ETH_P_IPV6); skb->protocol = htons(ETH_P_IPV6);
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = csummode;
skb->csum = 0; skb->csum = 0;
/* reserve for fragmentation and ipsec header */ /* reserve for fragmentation and ipsec header */
skb_reserve(skb, hh_len + sizeof(struct frag_hdr) + skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment