diff -u linux-2.6.18/net/ipv4/ping.c linux-2.6.18/net/ipv4/ping.c --- linux-2.6.18/net/ipv4/ping.c 2011-02-10 18:44:33 +0000 +++ linux-2.6.18/net/ipv4/ping.c 2011-03-06 11:12:31 +0000 @@ -485,10 +485,6 @@ &pfh->wcheck)) return -EFAULT; - pfh->wcheck = csum_partial((char *)&pfh->icmph, - sizeof(struct icmphdr), pfh->wcheck); - pfh->icmph.checksum = csum_fold(pfh->wcheck); - memcpy(to, &pfh->icmph, sizeof(struct icmphdr)); return 0; } if (offset < sizeof(struct icmphdr)) @@ -500,6 +496,19 @@ return 0; } +static int ping_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh) +{ + struct sk_buff *skb = skb_peek(&sk->sk_write_queue); + + pfh->wcheck = csum_partial((char *)&pfh->icmph, + sizeof(struct icmphdr), pfh->wcheck); + pfh->icmph.checksum = csum_fold(pfh->wcheck); + memcpy(skb->h.icmph, &pfh->icmph, sizeof(struct icmphdr)); + skb->ip_summed = CHECKSUM_NONE; + + return ip_push_pending_frames(sk); +} + int ping_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len) { @@ -642,7 +651,7 @@ if (err) ip_flush_pending_frames(sk); else - err = ip_push_pending_frames(sk); + err = ping_push_pending_frames(sk, &pfh); release_sock(sk); out: reverted: