Commit 516651ae authored by David S. Miller's avatar David S. Miller

Merge nuts.davemloft.net:/disk1/BK/network-2.6

into nuts.davemloft.net:/disk1/BK/net-2.6
parents 37433f98 d6523d64
...@@ -283,7 +283,8 @@ void rawv6_err(struct sock *sk, struct sk_buff *skb, ...@@ -283,7 +283,8 @@ void rawv6_err(struct sock *sk, struct sk_buff *skb,
static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
{ {
if (sk->sk_filter && skb->ip_summed != CHECKSUM_UNNECESSARY) { if ((raw6_sk(sk)->checksum || sk->sk_filter) &&
skb->ip_summed != CHECKSUM_UNNECESSARY) {
if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) { if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
/* FIXME: increment a raw6 drops counter here */ /* FIXME: increment a raw6 drops counter here */
kfree_skb(skb); kfree_skb(skb);
...@@ -452,6 +453,10 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct r ...@@ -452,6 +453,10 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct r
struct sk_buff *skb; struct sk_buff *skb;
int err = 0; int err = 0;
u16 *csum; u16 *csum;
u32 tmp_csum;
if (!opt->checksum)
goto send;
if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
goto out; goto out;
...@@ -463,29 +468,32 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct r ...@@ -463,29 +468,32 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct r
goto out; goto out;
} }
/* should be check HW csum miyazawa */
if (skb_queue_len(&sk->sk_write_queue) == 1) { if (skb_queue_len(&sk->sk_write_queue) == 1) {
/* /*
* Only one fragment on the socket. * Only one fragment on the socket.
*/ */
/* should be check HW csum miyazawa */ tmp_csum = skb->csum;
*csum = csum_ipv6_magic(&fl->fl6_src,
&fl->fl6_dst,
len, fl->proto, skb->csum);
} else { } else {
u32 tmp_csum = 0; tmp_csum = 0;
skb_queue_walk(&sk->sk_write_queue, skb) { skb_queue_walk(&sk->sk_write_queue, skb) {
tmp_csum = csum_add(tmp_csum, skb->csum); tmp_csum = csum_add(tmp_csum, skb->csum);
} }
}
tmp_csum = csum_ipv6_magic(&fl->fl6_src, /* in case cksum was not initialized */
if (unlikely(*csum))
tmp_csum = csum_sub(tmp_csum, *csum);
*csum = csum_ipv6_magic(&fl->fl6_src,
&fl->fl6_dst, &fl->fl6_dst,
len, fl->proto, tmp_csum); len, fl->proto, tmp_csum);
*csum = tmp_csum;
}
if (*csum == 0) if (*csum == 0)
*csum = -1; *csum = -1;
ip6_push_pending_frames(sk); send:
err = ip6_push_pending_frames(sk);
out: out:
return err; return err;
} }
...@@ -702,13 +710,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -702,13 +710,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
if (err) if (err)
ip6_flush_pending_frames(sk); ip6_flush_pending_frames(sk);
else if (!(msg->msg_flags & MSG_MORE)) { else if (!(msg->msg_flags & MSG_MORE))
if (raw_opt->checksum) {
err = rawv6_push_pending_frames(sk, &fl, raw_opt, len); err = rawv6_push_pending_frames(sk, &fl, raw_opt, len);
} else {
err = ip6_push_pending_frames(sk);
}
}
} }
done: done:
ip6_dst_store(sk, dst, ip6_dst_store(sk, dst,
......
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