diff options
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r-- | net/ipv6/udp.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index dd309626ae9a..d1477b350f76 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -7,8 +7,6 @@ | |||
7 | * | 7 | * |
8 | * Based on linux/ipv4/udp.c | 8 | * Based on linux/ipv4/udp.c |
9 | * | 9 | * |
10 | * $Id: udp.c,v 1.65 2002/02/01 22:01:04 davem Exp $ | ||
11 | * | ||
12 | * Fixes: | 10 | * Fixes: |
13 | * Hideaki YOSHIFUJI : sin6_scope_id support | 11 | * Hideaki YOSHIFUJI : sin6_scope_id support |
14 | * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which | 12 | * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which |
@@ -67,7 +65,7 @@ static struct sock *__udp6_lib_lookup(struct net *net, | |||
67 | int badness = -1; | 65 | int badness = -1; |
68 | 66 | ||
69 | read_lock(&udp_hash_lock); | 67 | read_lock(&udp_hash_lock); |
70 | sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { | 68 | sk_for_each(sk, node, &udptable[udp_hashfn(net, hnum)]) { |
71 | struct inet_sock *inet = inet_sk(sk); | 69 | struct inet_sock *inet = inet_sk(sk); |
72 | 70 | ||
73 | if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && | 71 | if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && |
@@ -168,7 +166,8 @@ try_again: | |||
168 | goto out_free; | 166 | goto out_free; |
169 | 167 | ||
170 | if (!peeked) | 168 | if (!peeked) |
171 | UDP6_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite); | 169 | UDP6_INC_STATS_USER(sock_net(sk), |
170 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
172 | 171 | ||
173 | sock_recv_timestamp(msg, sk, skb); | 172 | sock_recv_timestamp(msg, sk, skb); |
174 | 173 | ||
@@ -215,7 +214,7 @@ out: | |||
215 | csum_copy_err: | 214 | csum_copy_err: |
216 | lock_sock(sk); | 215 | lock_sock(sk); |
217 | if (!skb_kill_datagram(sk, skb, flags)) | 216 | if (!skb_kill_datagram(sk, skb, flags)) |
218 | UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite); | 217 | UDP6_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
219 | release_sock(sk); | 218 | release_sock(sk); |
220 | 219 | ||
221 | if (flags & MSG_DONTWAIT) | 220 | if (flags & MSG_DONTWAIT) |
@@ -299,14 +298,17 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
299 | 298 | ||
300 | if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { | 299 | if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { |
301 | /* Note that an ENOMEM error is charged twice */ | 300 | /* Note that an ENOMEM error is charged twice */ |
302 | if (rc == -ENOMEM) | 301 | if (rc == -ENOMEM) { |
303 | UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite); | 302 | UDP6_INC_STATS_BH(sock_net(sk), |
303 | UDP_MIB_RCVBUFERRORS, is_udplite); | ||
304 | atomic_inc(&sk->sk_drops); | ||
305 | } | ||
304 | goto drop; | 306 | goto drop; |
305 | } | 307 | } |
306 | 308 | ||
307 | return 0; | 309 | return 0; |
308 | drop: | 310 | drop: |
309 | UDP6_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite); | 311 | UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
310 | kfree_skb(skb); | 312 | kfree_skb(skb); |
311 | return -1; | 313 | return -1; |
312 | } | 314 | } |
@@ -355,15 +357,16 @@ static struct sock *udp_v6_mcast_next(struct sock *sk, | |||
355 | * Note: called only from the BH handler context, | 357 | * Note: called only from the BH handler context, |
356 | * so we don't need to lock the hashes. | 358 | * so we don't need to lock the hashes. |
357 | */ | 359 | */ |
358 | static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr, | 360 | static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, |
359 | struct in6_addr *daddr, struct hlist_head udptable[]) | 361 | struct in6_addr *saddr, struct in6_addr *daddr, |
362 | struct hlist_head udptable[]) | ||
360 | { | 363 | { |
361 | struct sock *sk, *sk2; | 364 | struct sock *sk, *sk2; |
362 | const struct udphdr *uh = udp_hdr(skb); | 365 | const struct udphdr *uh = udp_hdr(skb); |
363 | int dif; | 366 | int dif; |
364 | 367 | ||
365 | read_lock(&udp_hash_lock); | 368 | read_lock(&udp_hash_lock); |
366 | sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); | 369 | sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); |
367 | dif = inet6_iif(skb); | 370 | dif = inet6_iif(skb); |
368 | sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); | 371 | sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); |
369 | if (!sk) { | 372 | if (!sk) { |
@@ -437,6 +440,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
437 | struct net_device *dev = skb->dev; | 440 | struct net_device *dev = skb->dev; |
438 | struct in6_addr *saddr, *daddr; | 441 | struct in6_addr *saddr, *daddr; |
439 | u32 ulen = 0; | 442 | u32 ulen = 0; |
443 | struct net *net = dev_net(skb->dev); | ||
440 | 444 | ||
441 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) | 445 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) |
442 | goto short_packet; | 446 | goto short_packet; |
@@ -475,7 +479,8 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
475 | * Multicast receive code | 479 | * Multicast receive code |
476 | */ | 480 | */ |
477 | if (ipv6_addr_is_multicast(daddr)) | 481 | if (ipv6_addr_is_multicast(daddr)) |
478 | return __udp6_lib_mcast_deliver(skb, saddr, daddr, udptable); | 482 | return __udp6_lib_mcast_deliver(net, skb, |
483 | saddr, daddr, udptable); | ||
479 | 484 | ||
480 | /* Unicast */ | 485 | /* Unicast */ |
481 | 486 | ||
@@ -483,7 +488,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
483 | * check socket cache ... must talk to Alan about his plans | 488 | * check socket cache ... must talk to Alan about his plans |
484 | * for sock caches... i'll skip this for now. | 489 | * for sock caches... i'll skip this for now. |
485 | */ | 490 | */ |
486 | sk = __udp6_lib_lookup(dev_net(skb->dev), saddr, uh->source, | 491 | sk = __udp6_lib_lookup(net, saddr, uh->source, |
487 | daddr, uh->dest, inet6_iif(skb), udptable); | 492 | daddr, uh->dest, inet6_iif(skb), udptable); |
488 | 493 | ||
489 | if (sk == NULL) { | 494 | if (sk == NULL) { |
@@ -492,7 +497,8 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
492 | 497 | ||
493 | if (udp_lib_checksum_complete(skb)) | 498 | if (udp_lib_checksum_complete(skb)) |
494 | goto discard; | 499 | goto discard; |
495 | UDP6_INC_STATS_BH(UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); | 500 | UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, |
501 | proto == IPPROTO_UDPLITE); | ||
496 | 502 | ||
497 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); | 503 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); |
498 | 504 | ||
@@ -517,7 +523,7 @@ short_packet: | |||
517 | ulen, skb->len); | 523 | ulen, skb->len); |
518 | 524 | ||
519 | discard: | 525 | discard: |
520 | UDP6_INC_STATS_BH(UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); | 526 | UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); |
521 | kfree_skb(skb); | 527 | kfree_skb(skb); |
522 | return 0; | 528 | return 0; |
523 | } | 529 | } |
@@ -587,7 +593,8 @@ out: | |||
587 | up->len = 0; | 593 | up->len = 0; |
588 | up->pending = 0; | 594 | up->pending = 0; |
589 | if (!err) | 595 | if (!err) |
590 | UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite); | 596 | UDP6_INC_STATS_USER(sock_net(sk), |
597 | UDP_MIB_OUTDATAGRAMS, is_udplite); | ||
591 | return err; | 598 | return err; |
592 | } | 599 | } |
593 | 600 | ||
@@ -869,7 +876,8 @@ out: | |||
869 | * seems like overkill. | 876 | * seems like overkill. |
870 | */ | 877 | */ |
871 | if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { | 878 | if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { |
872 | UDP6_INC_STATS_USER(UDP_MIB_SNDBUFERRORS, is_udplite); | 879 | UDP6_INC_STATS_USER(sock_net(sk), |
880 | UDP_MIB_SNDBUFERRORS, is_udplite); | ||
873 | } | 881 | } |
874 | return err; | 882 | return err; |
875 | 883 | ||
@@ -881,15 +889,13 @@ do_confirm: | |||
881 | goto out; | 889 | goto out; |
882 | } | 890 | } |
883 | 891 | ||
884 | int udpv6_destroy_sock(struct sock *sk) | 892 | void udpv6_destroy_sock(struct sock *sk) |
885 | { | 893 | { |
886 | lock_sock(sk); | 894 | lock_sock(sk); |
887 | udp_v6_flush_pending_frames(sk); | 895 | udp_v6_flush_pending_frames(sk); |
888 | release_sock(sk); | 896 | release_sock(sk); |
889 | 897 | ||
890 | inet6_destroy_sock(sk); | 898 | inet6_destroy_sock(sk); |
891 | |||
892 | return 0; | ||
893 | } | 899 | } |
894 | 900 | ||
895 | /* | 901 | /* |
@@ -955,7 +961,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket | |||
955 | srcp = ntohs(inet->sport); | 961 | srcp = ntohs(inet->sport); |
956 | seq_printf(seq, | 962 | seq_printf(seq, |
957 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " | 963 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " |
958 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p\n", | 964 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", |
959 | bucket, | 965 | bucket, |
960 | src->s6_addr32[0], src->s6_addr32[1], | 966 | src->s6_addr32[0], src->s6_addr32[1], |
961 | src->s6_addr32[2], src->s6_addr32[3], srcp, | 967 | src->s6_addr32[2], src->s6_addr32[3], srcp, |
@@ -967,7 +973,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket | |||
967 | 0, 0L, 0, | 973 | 0, 0L, 0, |
968 | sock_i_uid(sp), 0, | 974 | sock_i_uid(sp), 0, |
969 | sock_i_ino(sp), | 975 | sock_i_ino(sp), |
970 | atomic_read(&sp->sk_refcnt), sp); | 976 | atomic_read(&sp->sk_refcnt), sp, |
977 | atomic_read(&sp->sk_drops)); | ||
971 | } | 978 | } |
972 | 979 | ||
973 | int udp6_seq_show(struct seq_file *seq, void *v) | 980 | int udp6_seq_show(struct seq_file *seq, void *v) |
@@ -978,7 +985,7 @@ int udp6_seq_show(struct seq_file *seq, void *v) | |||
978 | "local_address " | 985 | "local_address " |
979 | "remote_address " | 986 | "remote_address " |
980 | "st tx_queue rx_queue tr tm->when retrnsmt" | 987 | "st tx_queue rx_queue tr tm->when retrnsmt" |
981 | " uid timeout inode\n"); | 988 | " uid timeout inode ref pointer drops\n"); |
982 | else | 989 | else |
983 | udp6_sock_seq_show(seq, v, ((struct udp_iter_state *)seq->private)->bucket); | 990 | udp6_sock_seq_show(seq, v, ((struct udp_iter_state *)seq->private)->bucket); |
984 | return 0; | 991 | return 0; |