All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Haley <brian.haley@hp.com>
To: David Miller <davem@davemloft.net>
Cc: viro@ftp.linux.org.uk, netdev@vger.kernel.org
Subject: [PATCH] IPv6: optimize echo reply checksum calculation
Date: Fri, 10 Nov 2006 11:25:53 -0500	[thread overview]
Message-ID: <4554A811.5060402@hp.com> (raw)
In-Reply-To: <20061109.151402.15590179.davem@davemloft.net>

[-- Attachment #1: Type: text/plain, Size: 269 bytes --]

Since the only difference between echo requests and echo replies is the 
ICMPv6 type value (which is a difference of 1), just subtracting one 
from the request checksum will result in the correct checksum for the reply.

Signed-off-by: Brian Haley <brian.haley@hp.com>

[-- Attachment #2: no.cksum.echo.diff --]
[-- Type: text/x-patch, Size: 2414 bytes --]

diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index dbb9b1f..ee04610 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -212,7 +212,7 @@ static __inline__ int opt_unrec(struct s
 	return (*op & 0xC0) == 0x80;
 }
 
-static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len)
+static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len, int cksum_needed)
 {
 	struct sk_buff *skb;
 	struct icmp6hdr *icmp6h;
@@ -223,7 +223,9 @@ static int icmpv6_push_pending_frames(st
 
 	icmp6h = (struct icmp6hdr*) skb->h.raw;
 	memcpy(icmp6h, thdr, sizeof(struct icmp6hdr));
-	icmp6h->icmp6_cksum = 0;
+
+	if (!cksum_needed)
+		goto sendit;
 
 	if (skb_queue_len(&sk->sk_write_queue) == 1) {
 		skb->csum = csum_partial((char *)icmp6h,
@@ -246,6 +248,7 @@ static int icmpv6_push_pending_frames(st
 					   len, fl->proto, tmp_csum);
 		icmp6h->icmp6_cksum = tmp_csum;
 	}
+sendit:
 	ip6_push_pending_frames(sk);
 out:
 	return err;
@@ -451,7 +454,7 @@ void icmpv6_send(struct sk_buff *skb, in
 		ip6_flush_pending_frames(sk);
 		goto out_put;
 	}
-	err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
+	err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr), 1);
 
 	if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
 		ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_OUTDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
@@ -489,6 +492,14 @@ static void icmpv6_echo_reply(struct sk_
 	memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
 	tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
 
+	/*
+	 * The only difference between echo requests and echo replies is the
+	 * ICMPv6 type value (which is a difference of 1).  So if we subtract
+	 * one from the request checksum, it will result in the correct
+	 * checksum for the reply.
+	 */
+	tmp_hdr.icmp6_cksum--;
+
 	memset(&fl, 0, sizeof(fl));
 	fl.proto = IPPROTO_ICMPV6;
 	ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
@@ -540,7 +551,7 @@ static void icmpv6_echo_reply(struct sk_
 		ip6_flush_pending_frames(sk);
 		goto out_put;
 	}
-	err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
+	err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr), 0);
 
         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTECHOREPLIES);
         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);

  parent reply	other threads:[~2006-11-10 16:25 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-11-08 22:13 why do we mangle checksums for v6 ICMP? Al Viro
2006-11-08 22:28 ` Al Viro
2006-11-09 17:32 ` Brian Haley
2006-11-09 23:14   ` David Miller
2006-11-10 16:24     ` [PATCH] IPv6: only modify checksum for UDP Brian Haley
2006-11-10 17:54       ` David Stevens
2006-11-14  0:50         ` David Miller
2006-11-14  1:18           ` Al Viro
2006-11-14  1:44           ` David Stevens
2006-11-14  1:52             ` Al Viro
2006-11-10 22:55       ` David Miller
2006-11-10 23:17         ` Nivedita Singhvi
2006-11-10 23:26           ` David Miller
2006-11-10 23:36             ` Nivedita Singhvi
2006-11-12  1:30             ` Brian Haley
2006-11-10 16:25     ` Brian Haley [this message]
2006-11-10 17:34       ` [PATCH] IPv6: optimize echo reply checksum calculation Al Viro
2006-11-10 17:51         ` Brian Haley
2006-11-10 18:05           ` Al Viro
2006-11-10 18:20             ` Al Viro
2006-11-10 19:04               ` Brian Haley
2006-11-10 19:17                 ` Al Viro
2006-11-10 21:06                   ` Brian Haley
2006-11-11  1:45                     ` Al Viro
2006-11-11 18:07     ` why do we mangle checksums for v6 ICMP? Bill Fink
2006-11-13  7:04       ` David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4554A811.5060402@hp.com \
    --to=brian.haley@hp.com \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    --cc=viro@ftp.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.