]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/udp.c
[NETFILTER]: x_tables: replace IPv4 DSCP target by address family independent version
[linux-2.6-omap-h63xx.git] / net / ipv4 / udp.c
index f136cec96d959c2f94c18078ae35b62a68985099..514c1e9ae81036b90d93fedb38a61000edcae2c7 100644 (file)
@@ -429,7 +429,7 @@ static int udp_push_pending_frames(struct sock *sk, struct udp_sock *up)
                /*
                 * Only one fragment on the socket.
                 */
-               if (skb->ip_summed == CHECKSUM_HW) {
+               if (skb->ip_summed == CHECKSUM_PARTIAL) {
                        skb->csum = offsetof(struct udphdr, check);
                        uh->check = ~csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
                                        up->len, IPPROTO_UDP, 0);
@@ -448,7 +448,7 @@ static int udp_push_pending_frames(struct sock *sk, struct udp_sock *up)
                 * fragments on the socket so that all csums of sk_buffs
                 * should be together.
                 */
-               if (skb->ip_summed == CHECKSUM_HW) {
+               if (skb->ip_summed == CHECKSUM_PARTIAL) {
                        int offset = (unsigned char *)uh - skb->data;
                        skb->csum = skb_checksum(skb, offset, skb->len - offset, 0);
 
@@ -603,6 +603,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                    .uli_u = { .ports =
                                               { .sport = inet->sport,
                                                 .dport = dport } } };
+               security_sk_classify_flow(sk, &fl);
                err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
                if (err)
                        goto out;
@@ -661,6 +662,16 @@ out:
                UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS);
                return len;
        }
+       /*
+        * ENOBUFS = no kernel mem, SOCK_NOSPACE = no sndbuf space.  Reporting
+        * ENOBUFS might not be good (it's not tunable per se), but otherwise
+        * we don't have a good statistic (IpOutDiscards but it can be too many
+        * things).  We could add another new stat but at least for now that
+        * seems like overkill.
+        */
+       if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
+               UDP_INC_STATS_USER(UDP_MIB_SNDBUFERRORS);
+       }
        return err;
 
 do_confirm:
@@ -980,6 +991,7 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
 static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 {
        struct udp_sock *up = udp_sk(sk);
+       int rc;
 
        /*
         *      Charge it to the socket, dropping if the queue is full.
@@ -1026,7 +1038,10 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
                skb->ip_summed = CHECKSUM_UNNECESSARY;
        }
 
-       if (sock_queue_rcv_skb(sk,skb)<0) {
+       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);
                UDP_INC_STATS_BH(UDP_MIB_INERRORS);
                kfree_skb(skb);
                return -1;
@@ -1087,7 +1102,7 @@ static void udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
 {
        if (uh->check == 0) {
                skb->ip_summed = CHECKSUM_UNNECESSARY;
-       } else if (skb->ip_summed == CHECKSUM_HW) {
+       } else if (skb->ip_summed == CHECKSUM_COMPLETE) {
                if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
        }