]> err.no Git - linux-2.6/blobdiff - net/ipv4/udp.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / net / ipv4 / udp.c
index 3bbf6fb6e4f51f1cd43d7956964827a9afd169f7..383d17359d01f1a81080df5aabef22266c1dd1c4 100644 (file)
  *     Snmp MIB for the UDP layer
  */
 
-DEFINE_SNMP_STAT(struct udp_mib, udp_statistics) __read_mostly;
-EXPORT_SYMBOL(udp_statistics);
-
 DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
 EXPORT_SYMBOL(udp_stats_in6);
 
@@ -354,11 +351,12 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
        struct sock *sk;
        int harderr;
        int err;
+       struct net *net = dev_net(skb->dev);
 
-       sk = __udp4_lib_lookup(dev_net(skb->dev), iph->daddr, uh->dest,
+       sk = __udp4_lib_lookup(net, iph->daddr, uh->dest,
                        iph->saddr, uh->source, skb->dev->ifindex, udptable);
        if (sk == NULL) {
-               ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+               ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
                return; /* No socket for error */
        }
 
@@ -526,7 +524,8 @@ out:
        up->len = 0;
        up->pending = 0;
        if (!err)
-               UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite);
+               UDP_INC_STATS_USER(sock_net(sk),
+                               UDP_MIB_OUTDATAGRAMS, is_udplite);
        return err;
 }
 
@@ -654,11 +653,13 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                    .uli_u = { .ports =
                                               { .sport = inet->sport,
                                                 .dport = dport } } };
+               struct net *net = sock_net(sk);
+
                security_sk_classify_flow(sk, &fl);
-               err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 1);
+               err = ip_route_output_flow(net, &rt, &fl, sk, 1);
                if (err) {
                        if (err == -ENETUNREACH)
-                               IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
+                               IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
                        goto out;
                }
 
@@ -725,7 +726,8 @@ out:
         * seems like overkill.
         */
        if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
-               UDP_INC_STATS_USER(UDP_MIB_SNDBUFERRORS, is_udplite);
+               UDP_INC_STATS_USER(sock_net(sk),
+                               UDP_MIB_SNDBUFERRORS, is_udplite);
        }
        return err;
 
@@ -888,7 +890,8 @@ try_again:
                goto out_free;
 
        if (!peeked)
-               UDP_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite);
+               UDP_INC_STATS_USER(sock_net(sk),
+                               UDP_MIB_INDATAGRAMS, is_udplite);
 
        sock_recv_timestamp(msg, sk, skb);
 
@@ -917,7 +920,7 @@ out:
 csum_copy_err:
        lock_sock(sk);
        if (!skb_kill_datagram(sk, skb, flags))
-               UDP_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
+               UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
        release_sock(sk);
 
        if (noblock)
@@ -988,7 +991,8 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 
                        ret = (*up->encap_rcv)(sk, skb);
                        if (ret <= 0) {
-                               UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS,
+                               UDP_INC_STATS_BH(sock_net(sk),
+                                                UDP_MIB_INDATAGRAMS,
                                                 is_udplite);
                                return -ret;
                        }
@@ -1041,7 +1045,8 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
        if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
                /* Note that an ENOMEM error is charged twice */
                if (rc == -ENOMEM) {
-                       UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite);
+                       UDP_INC_STATS_BH(sock_net(sk),
+                                       UDP_MIB_RCVBUFERRORS, is_udplite);
                        atomic_inc(&sk->sk_drops);
                }
                goto drop;
@@ -1050,7 +1055,7 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
        return 0;
 
 drop:
-       UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
+       UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
        kfree_skb(skb);
        return -1;
 }
@@ -1158,7 +1163,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
        struct rtable *rt = (struct rtable*)skb->dst;
        __be32 saddr = ip_hdr(skb)->saddr;
        __be32 daddr = ip_hdr(skb)->daddr;
-       struct net *net;
+       struct net *net = dev_net(skb->dev);
 
        /*
         *  Validate the packet.
@@ -1180,7 +1185,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
        if (udp4_csum_init(skb, uh, proto))
                goto csum_error;
 
-       net = dev_net(skb->dev);
        if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
                return __udp4_lib_mcast_deliver(net, skb, uh,
                                saddr, daddr, udptable);
@@ -1214,7 +1218,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
        if (udp_lib_checksum_complete(skb))
                goto csum_error;
 
-       UDP_INC_STATS_BH(UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
+       UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
 
        /*
@@ -1248,7 +1252,7 @@ csum_error:
                       ntohs(uh->dest),
                       ulen);
 drop:
-       UDP_INC_STATS_BH(UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
+       UDP_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
        kfree_skb(skb);
        return 0;
 }
@@ -1321,6 +1325,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
                        return -ENOPROTOOPT;
                if (val != 0 && val < 8) /* Illegal coverage: use default (8) */
                        val = 8;
+               else if (val > USHORT_MAX)
+                       val = USHORT_MAX;
                up->pcslen = val;
                up->pcflag |= UDPLITE_SEND_CC;
                break;
@@ -1333,6 +1339,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
                        return -ENOPROTOOPT;
                if (val != 0 && val < 8) /* Avoid silly minimal values.       */
                        val = 8;
+               else if (val > USHORT_MAX)
+                       val = USHORT_MAX;
                up->pcrlen = val;
                up->pcflag |= UDPLITE_RECV_CC;
                break;
@@ -1455,7 +1463,8 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
                spin_lock_bh(&rcvq->lock);
                while ((skb = skb_peek(rcvq)) != NULL &&
                       udp_lib_checksum_complete(skb)) {
-                       UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_lite);
+                       UDP_INC_STATS_BH(sock_net(sk),
+                                       UDP_MIB_INERRORS, is_lite);
                        __skb_unlink(skb, rcvq);
                        kfree_skb(skb);
                }