From patchwork Mon Jan 14 12:12:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Woodhouse X-Patchwork-Id: 211779 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 5504B2C0091 for ; Mon, 14 Jan 2013 23:12:40 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756079Ab3ANMMf (ORCPT ); Mon, 14 Jan 2013 07:12:35 -0500 Received: from merlin.infradead.org ([205.233.59.134]:35696 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755732Ab3ANMMe (ORCPT ); Mon, 14 Jan 2013 07:12:34 -0500 Received: from shinybook.infradead.org ([2001:8b0:10b:1:e6ce:8fff:fe1f:f2c0]) by merlin.infradead.org with esmtpsa (Exim 4.76 #1 (Red Hat Linux)) id 1Tuiu0-0001yb-Ku for netdev@vger.kernel.org; Mon, 14 Jan 2013 12:12:33 +0000 Message-ID: <1358165551.27054.64.camel@shinybook.infradead.org> Subject: [RFC PATCH 2/3] Prepare to allow for hardware checksum of ICMPv6 From: David Woodhouse To: netdev@vger.kernel.org Date: Mon, 14 Jan 2013 12:12:31 +0000 In-Reply-To: <1358165431.27054.62.camel@shinybook.infradead.org> References: <1358165431.27054.62.camel@shinybook.infradead.org> X-Mailer: Evolution 3.6.2 (3.6.2-3.fc18) Mime-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If netif_skb_features() has to filter out non-TCP and non-UDP frames anyway for devices with limited checksum support, there's no reason we shouldn't generate them in our *own* stack. This allows ICMPv6 to do so... Signed-off-by: David Woodhouse diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index b4a9fd5..e474df9 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -235,12 +235,19 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, struc icmp6h->icmp6_cksum = 0; if (skb_queue_len(&sk->sk_write_queue) == 1) { - skb->csum = csum_partial(icmp6h, - sizeof(struct icmp6hdr), skb->csum); - icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr, - &fl6->daddr, - len, fl6->flowi6_proto, - skb->csum); + if (skb->ip_summed == CHECKSUM_PARTIAL) { + skb->csum_start = skb_transport_header(skb) - skb->head; + skb->csum_offset = offsetof(struct icmp6hdr, icmp6_cksum); + icmp6h->icmp6_cksum = ~csum_ipv6_magic(&fl6->saddr, &fl6->daddr, + len, fl6->flowi6_proto, 0); + } else { + skb->csum = csum_partial(icmp6h, + sizeof(struct icmp6hdr), skb->csum); + icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr, + &fl6->daddr, + len, fl6->flowi6_proto, + skb->csum); + } } else { __wsum tmp_csum = 0;