ALSA: hda - iMac9,1 sound fixes
[safe/jmp/linux-2.6] / net / ipv4 / udp.c
index 1eaf575..c36522a 100644 (file)
@@ -95,6 +95,7 @@
 #include <linux/mm.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <net/tcp_states.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
@@ -136,12 +137,12 @@ static int udp_lib_lport_inuse(struct net *net, __u16 num,
        struct hlist_nulls_node *node;
 
        sk_nulls_for_each(sk2, node, &hslot->head)
-               if (net_eq(sock_net(sk2), net)                  &&
-                   sk2 != sk                                   &&
+               if (net_eq(sock_net(sk2), net) &&
+                   sk2 != sk &&
                    (bitmap || udp_sk(sk2)->udp_port_hash == num) &&
-                   (!sk2->sk_reuse || !sk->sk_reuse)           &&
-                   (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
-                       || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
+                   (!sk2->sk_reuse || !sk->sk_reuse) &&
+                   (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if ||
+                    sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
                    (*saddr_comp)(sk, sk2)) {
                        if (bitmap)
                                __set_bit(udp_sk(sk2)->udp_port_hash >> log,
@@ -168,12 +169,12 @@ static int udp_lib_lport_inuse2(struct net *net, __u16 num,
 
        spin_lock(&hslot2->lock);
        udp_portaddr_for_each_entry(sk2, node, &hslot2->head)
-               if (net_eq(sock_net(sk2), net)                  &&
-                   sk2 != sk                                   &&
-                   (udp_sk(sk2)->udp_port_hash == num)         &&
-                   (!sk2->sk_reuse || !sk->sk_reuse)           &&
-                   (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
-                       || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
+               if (net_eq(sock_net(sk2), net) &&
+                   sk2 != sk &&
+                   (udp_sk(sk2)->udp_port_hash == num) &&
+                   (!sk2->sk_reuse || !sk->sk_reuse) &&
+                   (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if ||
+                    sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
                    (*saddr_comp)(sk, sk2)) {
                        res = 1;
                        break;
@@ -216,9 +217,8 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
                 * force rand to be an odd multiple of UDP_HTABLE_SIZE
                 */
                rand = (rand | 1) * (udptable->mask + 1);
-               for (last = first + udptable->mask + 1;
-                    first != last;
-                    first++) {
+               last = first + udptable->mask + 1;
+               do {
                        hslot = udp_hashslot(udptable, net, first);
                        bitmap_zero(bitmap, PORTS_PER_CHAIN);
                        spin_lock_bh(&hslot->lock);
@@ -238,7 +238,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
                                snum += rand;
                        } while (snum != first);
                        spin_unlock_bh(&hslot->lock);
-               }
+               } while (++first != last);
                goto fail;
        } else {
                hslot = udp_hashslot(udptable, net, snum);
@@ -472,8 +472,8 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
                        if (hslot->count < hslot2->count)
                                goto begin;
 
-                       result = udp4_lib_lookup2(net, INADDR_ANY, sport,
-                                                 daddr, hnum, dif,
+                       result = udp4_lib_lookup2(net, saddr, sport,
+                                                 INADDR_ANY, hnum, dif,
                                                  hslot2, slot2);
                }
                rcu_read_unlock();
@@ -545,13 +545,13 @@ static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk,
        sk_nulls_for_each_from(s, node) {
                struct inet_sock *inet = inet_sk(s);
 
-               if (!net_eq(sock_net(s), net)                           ||
-                   udp_sk(s)->udp_port_hash != hnum                    ||
-                   (inet->inet_daddr && inet->inet_daddr != rmt_addr)  ||
-                   (inet->inet_dport != rmt_port && inet->inet_dport)  ||
-                   (inet->inet_rcv_saddr       &&
-                    inet->inet_rcv_saddr != loc_addr)                  ||
-                   ipv6_only_sock(s)                                   ||
+               if (!net_eq(sock_net(s), net) ||
+                   udp_sk(s)->udp_port_hash != hnum ||
+                   (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
+                   (inet->inet_dport != rmt_port && inet->inet_dport) ||
+                   (inet->inet_rcv_saddr &&
+                    inet->inet_rcv_saddr != loc_addr) ||
+                   ipv6_only_sock(s) ||
                    (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
                        continue;
                if (!ip_mc_sf_allow(s, loc_addr, rmt_addr, dif))
@@ -1118,7 +1118,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        struct inet_sock *inet = inet_sk(sk);
        struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
        struct sk_buff *skb;
-       unsigned int ulen, copied;
+       unsigned int ulen;
        int peeked;
        int err;
        int is_udplite = IS_UDPLITE(sk);
@@ -1139,10 +1139,9 @@ try_again:
                goto out;
 
        ulen = skb->len - sizeof(struct udphdr);
-       copied = len;
-       if (copied > ulen)
-               copied = ulen;
-       else if (copied < ulen)
+       if (len > ulen)
+               len = ulen;
+       else if (len < ulen)
                msg->msg_flags |= MSG_TRUNC;
 
        /*
@@ -1151,14 +1150,14 @@ try_again:
         * coverage checksum (UDP-Lite), do it before the copy.
         */
 
-       if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
+       if (len < ulen || UDP_SKB_CB(skb)->partial_cov) {
                if (udp_lib_checksum_complete(skb))
                        goto csum_copy_err;
        }
 
        if (skb_csum_unnecessary(skb))
                err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
-                                             msg->msg_iov, copied);
+                                             msg->msg_iov, len);
        else {
                err = skb_copy_and_csum_datagram_iovec(skb,
                                                       sizeof(struct udphdr),
@@ -1187,7 +1186,7 @@ try_again:
        if (inet->cmsg_flags)
                ip_cmsg_recv(msg, skb);
 
-       err = copied;
+       err = len;
        if (flags & MSG_TRUNC)
                err = ulen;
 
@@ -1373,8 +1372,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
        bh_lock_sock(sk);
        if (!sock_owned_by_user(sk))
                rc = __udp_queue_rcv_skb(sk, skb);
-       else
-               sk_add_backlog(sk, skb);
+       else if (sk_add_backlog(sk, skb)) {
+               bh_unlock_sock(sk);
+               goto drop;
+       }
        bh_unlock_sock(sk);
 
        return rc;
@@ -1526,6 +1527,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 
        uh   = udp_hdr(skb);
        ulen = ntohs(uh->len);
+       saddr = ip_hdr(skb)->saddr;
+       daddr = ip_hdr(skb)->daddr;
+
        if (ulen > skb->len)
                goto short_packet;
 
@@ -1539,9 +1543,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
        if (udp4_csum_init(skb, uh, proto))
                goto csum_error;
 
-       saddr = ip_hdr(skb)->saddr;
-       daddr = ip_hdr(skb)->daddr;
-
        if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
                return __udp4_lib_mcast_deliver(net, skb, uh,
                                saddr, daddr, udptable);
@@ -2028,12 +2029,12 @@ static struct udp_seq_afinfo udp4_seq_afinfo = {
        },
 };
 
-static int udp4_proc_init_net(struct net *net)
+static int __net_init udp4_proc_init_net(struct net *net)
 {
        return udp_proc_register(net, &udp4_seq_afinfo);
 }
 
-static void udp4_proc_exit_net(struct net *net)
+static void __net_exit udp4_proc_exit_net(struct net *net)
 {
        udp_proc_unregister(net, &udp4_seq_afinfo);
 }