aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/udp.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-11-07 01:43:03 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-07 01:43:03 -0500
commit9eeda9abd1faf489f3df9a1f557975f4c8650363 (patch)
tree3e0a58e25b776cfbee193195460324dccb1886c7 /net/ipv6/udp.c
parent61c9eaf90081cbe6dc4f389e0056bff76eca19ec (diff)
parent4bab0ea1d42dd1927af9df6fbf0003fc00617c50 (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.c36
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
256csum_copy_err: 264csum_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
358static struct sock *udp_v6_mcast_next(struct sock *sk, 372static 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) {