diff options
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r-- | net/ipv4/udp.c | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 56fcda3694ba..7187121e922d 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -5,8 +5,6 @@ | |||
5 | * | 5 | * |
6 | * The User Datagram Protocol (UDP). | 6 | * The User Datagram Protocol (UDP). |
7 | * | 7 | * |
8 | * Version: $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $ | ||
9 | * | ||
10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> | 10 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> |
@@ -136,7 +134,7 @@ static inline int __udp_lib_lport_inuse(struct net *net, __u16 num, | |||
136 | struct sock *sk; | 134 | struct sock *sk; |
137 | struct hlist_node *node; | 135 | struct hlist_node *node; |
138 | 136 | ||
139 | sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)]) | 137 | sk_for_each(sk, node, &udptable[udp_hashfn(net, num)]) |
140 | if (net_eq(sock_net(sk), net) && sk->sk_hash == num) | 138 | if (net_eq(sock_net(sk), net) && sk->sk_hash == num) |
141 | return 1; | 139 | return 1; |
142 | return 0; | 140 | return 0; |
@@ -176,7 +174,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
176 | for (i = 0; i < UDP_HTABLE_SIZE; i++) { | 174 | for (i = 0; i < UDP_HTABLE_SIZE; i++) { |
177 | int size = 0; | 175 | int size = 0; |
178 | 176 | ||
179 | head = &udptable[rover & (UDP_HTABLE_SIZE - 1)]; | 177 | head = &udptable[udp_hashfn(net, rover)]; |
180 | if (hlist_empty(head)) | 178 | if (hlist_empty(head)) |
181 | goto gotit; | 179 | goto gotit; |
182 | 180 | ||
@@ -213,7 +211,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
213 | gotit: | 211 | gotit: |
214 | snum = rover; | 212 | snum = rover; |
215 | } else { | 213 | } else { |
216 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; | 214 | head = &udptable[udp_hashfn(net, snum)]; |
217 | 215 | ||
218 | sk_for_each(sk2, node, head) | 216 | sk_for_each(sk2, node, head) |
219 | if (sk2->sk_hash == snum && | 217 | if (sk2->sk_hash == snum && |
@@ -229,7 +227,7 @@ gotit: | |||
229 | inet_sk(sk)->num = snum; | 227 | inet_sk(sk)->num = snum; |
230 | sk->sk_hash = snum; | 228 | sk->sk_hash = snum; |
231 | if (sk_unhashed(sk)) { | 229 | if (sk_unhashed(sk)) { |
232 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; | 230 | head = &udptable[udp_hashfn(net, snum)]; |
233 | sk_add_node(sk, head); | 231 | sk_add_node(sk, head); |
234 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 232 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
235 | } | 233 | } |
@@ -266,7 +264,7 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, | |||
266 | int badness = -1; | 264 | int badness = -1; |
267 | 265 | ||
268 | read_lock(&udp_hash_lock); | 266 | read_lock(&udp_hash_lock); |
269 | sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { | 267 | sk_for_each(sk, node, &udptable[udp_hashfn(net, hnum)]) { |
270 | struct inet_sock *inet = inet_sk(sk); | 268 | struct inet_sock *inet = inet_sk(sk); |
271 | 269 | ||
272 | if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && | 270 | if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && |
@@ -528,7 +526,8 @@ out: | |||
528 | up->len = 0; | 526 | up->len = 0; |
529 | up->pending = 0; | 527 | up->pending = 0; |
530 | if (!err) | 528 | if (!err) |
531 | UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite); | 529 | UDP_INC_STATS_USER(sock_net(sk), |
530 | UDP_MIB_OUTDATAGRAMS, is_udplite); | ||
532 | return err; | 531 | return err; |
533 | } | 532 | } |
534 | 533 | ||
@@ -727,7 +726,8 @@ out: | |||
727 | * seems like overkill. | 726 | * seems like overkill. |
728 | */ | 727 | */ |
729 | if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { | 728 | if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { |
730 | UDP_INC_STATS_USER(UDP_MIB_SNDBUFERRORS, is_udplite); | 729 | UDP_INC_STATS_USER(sock_net(sk), |
730 | UDP_MIB_SNDBUFERRORS, is_udplite); | ||
731 | } | 731 | } |
732 | return err; | 732 | return err; |
733 | 733 | ||
@@ -890,7 +890,8 @@ try_again: | |||
890 | goto out_free; | 890 | goto out_free; |
891 | 891 | ||
892 | if (!peeked) | 892 | if (!peeked) |
893 | UDP_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite); | 893 | UDP_INC_STATS_USER(sock_net(sk), |
894 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
894 | 895 | ||
895 | sock_recv_timestamp(msg, sk, skb); | 896 | sock_recv_timestamp(msg, sk, skb); |
896 | 897 | ||
@@ -919,7 +920,7 @@ out: | |||
919 | csum_copy_err: | 920 | csum_copy_err: |
920 | lock_sock(sk); | 921 | lock_sock(sk); |
921 | if (!skb_kill_datagram(sk, skb, flags)) | 922 | if (!skb_kill_datagram(sk, skb, flags)) |
922 | UDP_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite); | 923 | UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
923 | release_sock(sk); | 924 | release_sock(sk); |
924 | 925 | ||
925 | if (noblock) | 926 | if (noblock) |
@@ -990,7 +991,8 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
990 | 991 | ||
991 | ret = (*up->encap_rcv)(sk, skb); | 992 | ret = (*up->encap_rcv)(sk, skb); |
992 | if (ret <= 0) { | 993 | if (ret <= 0) { |
993 | UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, | 994 | UDP_INC_STATS_BH(sock_net(sk), |
995 | UDP_MIB_INDATAGRAMS, | ||
994 | is_udplite); | 996 | is_udplite); |
995 | return -ret; | 997 | return -ret; |
996 | } | 998 | } |
@@ -1042,15 +1044,18 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
1042 | 1044 | ||
1043 | if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { | 1045 | if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { |
1044 | /* Note that an ENOMEM error is charged twice */ | 1046 | /* Note that an ENOMEM error is charged twice */ |
1045 | if (rc == -ENOMEM) | 1047 | if (rc == -ENOMEM) { |
1046 | UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite); | 1048 | UDP_INC_STATS_BH(sock_net(sk), |
1049 | UDP_MIB_RCVBUFERRORS, is_udplite); | ||
1050 | atomic_inc(&sk->sk_drops); | ||
1051 | } | ||
1047 | goto drop; | 1052 | goto drop; |
1048 | } | 1053 | } |
1049 | 1054 | ||
1050 | return 0; | 1055 | return 0; |
1051 | 1056 | ||
1052 | drop: | 1057 | drop: |
1053 | UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite); | 1058 | UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
1054 | kfree_skb(skb); | 1059 | kfree_skb(skb); |
1055 | return -1; | 1060 | return -1; |
1056 | } | 1061 | } |
@@ -1061,7 +1066,7 @@ drop: | |||
1061 | * Note: called only from the BH handler context, | 1066 | * Note: called only from the BH handler context, |
1062 | * so we don't need to lock the hashes. | 1067 | * so we don't need to lock the hashes. |
1063 | */ | 1068 | */ |
1064 | static int __udp4_lib_mcast_deliver(struct sk_buff *skb, | 1069 | static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, |
1065 | struct udphdr *uh, | 1070 | struct udphdr *uh, |
1066 | __be32 saddr, __be32 daddr, | 1071 | __be32 saddr, __be32 daddr, |
1067 | struct hlist_head udptable[]) | 1072 | struct hlist_head udptable[]) |
@@ -1070,7 +1075,7 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb, | |||
1070 | int dif; | 1075 | int dif; |
1071 | 1076 | ||
1072 | read_lock(&udp_hash_lock); | 1077 | read_lock(&udp_hash_lock); |
1073 | sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); | 1078 | sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); |
1074 | dif = skb->dev->ifindex; | 1079 | dif = skb->dev->ifindex; |
1075 | sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); | 1080 | sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); |
1076 | if (sk) { | 1081 | if (sk) { |
@@ -1158,6 +1163,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
1158 | struct rtable *rt = (struct rtable*)skb->dst; | 1163 | struct rtable *rt = (struct rtable*)skb->dst; |
1159 | __be32 saddr = ip_hdr(skb)->saddr; | 1164 | __be32 saddr = ip_hdr(skb)->saddr; |
1160 | __be32 daddr = ip_hdr(skb)->daddr; | 1165 | __be32 daddr = ip_hdr(skb)->daddr; |
1166 | struct net *net = dev_net(skb->dev); | ||
1161 | 1167 | ||
1162 | /* | 1168 | /* |
1163 | * Validate the packet. | 1169 | * Validate the packet. |
@@ -1180,9 +1186,10 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
1180 | goto csum_error; | 1186 | goto csum_error; |
1181 | 1187 | ||
1182 | if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) | 1188 | if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) |
1183 | return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); | 1189 | return __udp4_lib_mcast_deliver(net, skb, uh, |
1190 | saddr, daddr, udptable); | ||
1184 | 1191 | ||
1185 | sk = __udp4_lib_lookup(dev_net(skb->dev), saddr, uh->source, daddr, | 1192 | sk = __udp4_lib_lookup(net, saddr, uh->source, daddr, |
1186 | uh->dest, inet_iif(skb), udptable); | 1193 | uh->dest, inet_iif(skb), udptable); |
1187 | 1194 | ||
1188 | if (sk != NULL) { | 1195 | if (sk != NULL) { |
@@ -1211,7 +1218,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
1211 | if (udp_lib_checksum_complete(skb)) | 1218 | if (udp_lib_checksum_complete(skb)) |
1212 | goto csum_error; | 1219 | goto csum_error; |
1213 | 1220 | ||
1214 | UDP_INC_STATS_BH(UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); | 1221 | UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); |
1215 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); | 1222 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); |
1216 | 1223 | ||
1217 | /* | 1224 | /* |
@@ -1245,7 +1252,7 @@ csum_error: | |||
1245 | ntohs(uh->dest), | 1252 | ntohs(uh->dest), |
1246 | ulen); | 1253 | ulen); |
1247 | drop: | 1254 | drop: |
1248 | UDP_INC_STATS_BH(UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); | 1255 | UDP_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); |
1249 | kfree_skb(skb); | 1256 | kfree_skb(skb); |
1250 | return 0; | 1257 | return 0; |
1251 | } | 1258 | } |
@@ -1255,12 +1262,11 @@ int udp_rcv(struct sk_buff *skb) | |||
1255 | return __udp4_lib_rcv(skb, udp_hash, IPPROTO_UDP); | 1262 | return __udp4_lib_rcv(skb, udp_hash, IPPROTO_UDP); |
1256 | } | 1263 | } |
1257 | 1264 | ||
1258 | int udp_destroy_sock(struct sock *sk) | 1265 | void udp_destroy_sock(struct sock *sk) |
1259 | { | 1266 | { |
1260 | lock_sock(sk); | 1267 | lock_sock(sk); |
1261 | udp_flush_pending_frames(sk); | 1268 | udp_flush_pending_frames(sk); |
1262 | release_sock(sk); | 1269 | release_sock(sk); |
1263 | return 0; | ||
1264 | } | 1270 | } |
1265 | 1271 | ||
1266 | /* | 1272 | /* |
@@ -1453,7 +1459,8 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
1453 | spin_lock_bh(&rcvq->lock); | 1459 | spin_lock_bh(&rcvq->lock); |
1454 | while ((skb = skb_peek(rcvq)) != NULL && | 1460 | while ((skb = skb_peek(rcvq)) != NULL && |
1455 | udp_lib_checksum_complete(skb)) { | 1461 | udp_lib_checksum_complete(skb)) { |
1456 | UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_lite); | 1462 | UDP_INC_STATS_BH(sock_net(sk), |
1463 | UDP_MIB_INERRORS, is_lite); | ||
1457 | __skb_unlink(skb, rcvq); | 1464 | __skb_unlink(skb, rcvq); |
1458 | kfree_skb(skb); | 1465 | kfree_skb(skb); |
1459 | } | 1466 | } |
@@ -1629,12 +1636,13 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, | |||
1629 | __u16 srcp = ntohs(inet->sport); | 1636 | __u16 srcp = ntohs(inet->sport); |
1630 | 1637 | ||
1631 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" | 1638 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
1632 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p%n", | 1639 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n", |
1633 | bucket, src, srcp, dest, destp, sp->sk_state, | 1640 | bucket, src, srcp, dest, destp, sp->sk_state, |
1634 | atomic_read(&sp->sk_wmem_alloc), | 1641 | atomic_read(&sp->sk_wmem_alloc), |
1635 | atomic_read(&sp->sk_rmem_alloc), | 1642 | atomic_read(&sp->sk_rmem_alloc), |
1636 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), | 1643 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), |
1637 | atomic_read(&sp->sk_refcnt), sp, len); | 1644 | atomic_read(&sp->sk_refcnt), sp, |
1645 | atomic_read(&sp->sk_drops), len); | ||
1638 | } | 1646 | } |
1639 | 1647 | ||
1640 | int udp4_seq_show(struct seq_file *seq, void *v) | 1648 | int udp4_seq_show(struct seq_file *seq, void *v) |
@@ -1643,7 +1651,7 @@ int udp4_seq_show(struct seq_file *seq, void *v) | |||
1643 | seq_printf(seq, "%-127s\n", | 1651 | seq_printf(seq, "%-127s\n", |
1644 | " sl local_address rem_address st tx_queue " | 1652 | " sl local_address rem_address st tx_queue " |
1645 | "rx_queue tr tm->when retrnsmt uid timeout " | 1653 | "rx_queue tr tm->when retrnsmt uid timeout " |
1646 | "inode"); | 1654 | "inode ref pointer drops"); |
1647 | else { | 1655 | else { |
1648 | struct udp_iter_state *state = seq->private; | 1656 | struct udp_iter_state *state = seq->private; |
1649 | int len; | 1657 | int len; |