diff options
author | David S. Miller <davem@davemloft.net> | 2008-11-07 01:43:03 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-07 01:43:03 -0500 |
commit | 9eeda9abd1faf489f3df9a1f557975f4c8650363 (patch) | |
tree | 3e0a58e25b776cfbee193195460324dccb1886c7 /net/ipv6/udp.c | |
parent | 61c9eaf90081cbe6dc4f389e0056bff76eca19ec (diff) | |
parent | 4bab0ea1d42dd1927af9df6fbf0003fc00617c50 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/wireless/ath5k/base.c
net/8021q/vlan_core.c
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r-- | net/ipv6/udp.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 32d914db6c4f..8dafa36b1ba5 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -165,6 +165,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
165 | int peeked; | 165 | int peeked; |
166 | int err; | 166 | int err; |
167 | int is_udplite = IS_UDPLITE(sk); | 167 | int is_udplite = IS_UDPLITE(sk); |
168 | int is_udp4; | ||
168 | 169 | ||
169 | if (addr_len) | 170 | if (addr_len) |
170 | *addr_len=sizeof(struct sockaddr_in6); | 171 | *addr_len=sizeof(struct sockaddr_in6); |
@@ -185,6 +186,8 @@ try_again: | |||
185 | else if (copied < ulen) | 186 | else if (copied < ulen) |
186 | msg->msg_flags |= MSG_TRUNC; | 187 | msg->msg_flags |= MSG_TRUNC; |
187 | 188 | ||
189 | is_udp4 = (skb->protocol == htons(ETH_P_IP)); | ||
190 | |||
188 | /* | 191 | /* |
189 | * If checksum is needed at all, try to do it while copying the | 192 | * If checksum is needed at all, try to do it while copying the |
190 | * data. If the data is truncated, or if we only want a partial | 193 | * data. If the data is truncated, or if we only want a partial |
@@ -207,9 +210,14 @@ try_again: | |||
207 | if (err) | 210 | if (err) |
208 | goto out_free; | 211 | goto out_free; |
209 | 212 | ||
210 | if (!peeked) | 213 | if (!peeked) { |
211 | UDP6_INC_STATS_USER(sock_net(sk), | 214 | if (is_udp4) |
212 | UDP_MIB_INDATAGRAMS, is_udplite); | 215 | UDP_INC_STATS_USER(sock_net(sk), |
216 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
217 | else | ||
218 | UDP6_INC_STATS_USER(sock_net(sk), | ||
219 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
220 | } | ||
213 | 221 | ||
214 | sock_recv_timestamp(msg, sk, skb); | 222 | sock_recv_timestamp(msg, sk, skb); |
215 | 223 | ||
@@ -223,7 +231,7 @@ try_again: | |||
223 | sin6->sin6_flowinfo = 0; | 231 | sin6->sin6_flowinfo = 0; |
224 | sin6->sin6_scope_id = 0; | 232 | sin6->sin6_scope_id = 0; |
225 | 233 | ||
226 | if (skb->protocol == htons(ETH_P_IP)) | 234 | if (is_udp4) |
227 | ipv6_addr_set(&sin6->sin6_addr, 0, 0, | 235 | ipv6_addr_set(&sin6->sin6_addr, 0, 0, |
228 | htonl(0xffff), ip_hdr(skb)->saddr); | 236 | htonl(0xffff), ip_hdr(skb)->saddr); |
229 | else { | 237 | else { |
@@ -234,7 +242,7 @@ try_again: | |||
234 | } | 242 | } |
235 | 243 | ||
236 | } | 244 | } |
237 | if (skb->protocol == htons(ETH_P_IP)) { | 245 | if (is_udp4) { |
238 | if (inet->cmsg_flags) | 246 | if (inet->cmsg_flags) |
239 | ip_cmsg_recv(msg, skb); | 247 | ip_cmsg_recv(msg, skb); |
240 | } else { | 248 | } else { |
@@ -255,8 +263,14 @@ out: | |||
255 | 263 | ||
256 | csum_copy_err: | 264 | csum_copy_err: |
257 | lock_sock(sk); | 265 | lock_sock(sk); |
258 | if (!skb_kill_datagram(sk, skb, flags)) | 266 | if (!skb_kill_datagram(sk, skb, flags)) { |
259 | UDP6_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); | 267 | if (is_udp4) |
268 | UDP_INC_STATS_USER(sock_net(sk), | ||
269 | UDP_MIB_INERRORS, is_udplite); | ||
270 | else | ||
271 | UDP6_INC_STATS_USER(sock_net(sk), | ||
272 | UDP_MIB_INERRORS, is_udplite); | ||
273 | } | ||
260 | release_sock(sk); | 274 | release_sock(sk); |
261 | 275 | ||
262 | if (flags & MSG_DONTWAIT) | 276 | if (flags & MSG_DONTWAIT) |
@@ -355,7 +369,7 @@ drop: | |||
355 | return -1; | 369 | return -1; |
356 | } | 370 | } |
357 | 371 | ||
358 | static struct sock *udp_v6_mcast_next(struct sock *sk, | 372 | static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk, |
359 | __be16 loc_port, struct in6_addr *loc_addr, | 373 | __be16 loc_port, struct in6_addr *loc_addr, |
360 | __be16 rmt_port, struct in6_addr *rmt_addr, | 374 | __be16 rmt_port, struct in6_addr *rmt_addr, |
361 | int dif) | 375 | int dif) |
@@ -367,7 +381,7 @@ static struct sock *udp_v6_mcast_next(struct sock *sk, | |||
367 | sk_for_each_from(s, node) { | 381 | sk_for_each_from(s, node) { |
368 | struct inet_sock *inet = inet_sk(s); | 382 | struct inet_sock *inet = inet_sk(s); |
369 | 383 | ||
370 | if (sock_net(s) != sock_net(sk)) | 384 | if (!net_eq(sock_net(s), net)) |
371 | continue; | 385 | continue; |
372 | 386 | ||
373 | if (s->sk_hash == num && s->sk_family == PF_INET6) { | 387 | if (s->sk_hash == num && s->sk_family == PF_INET6) { |
@@ -411,14 +425,14 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
411 | spin_lock(&hslot->lock); | 425 | spin_lock(&hslot->lock); |
412 | sk = sk_head(&hslot->head); | 426 | sk = sk_head(&hslot->head); |
413 | dif = inet6_iif(skb); | 427 | dif = inet6_iif(skb); |
414 | sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); | 428 | sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); |
415 | if (!sk) { | 429 | if (!sk) { |
416 | kfree_skb(skb); | 430 | kfree_skb(skb); |
417 | goto out; | 431 | goto out; |
418 | } | 432 | } |
419 | 433 | ||
420 | sk2 = sk; | 434 | sk2 = sk; |
421 | while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr, | 435 | while ((sk2 = udp_v6_mcast_next(net, sk_next(sk2), uh->dest, daddr, |
422 | uh->source, saddr, dif))) { | 436 | uh->source, saddr, dif))) { |
423 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); | 437 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); |
424 | if (buff) { | 438 | if (buff) { |