mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
03485f2adc
commit
32dce968dd
|
@ -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,
|
||||||
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,
|
||||||
* 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) +
|
||||||
|
|
Loading…
Reference in New Issue