xfs: remove nr_to_write writeback windup.
[safe/jmp/linux-2.6] / net / ipv4 / ip_sockglue.c
index c602d98..ce23178 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/icmp.h>
 #include <linux/inetdevice.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
@@ -286,12 +287,8 @@ int ip_ra_control(struct sock *sk, unsigned char on,
 void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
                   __be16 port, u32 info, u8 *payload)
 {
-       struct inet_sock *inet = inet_sk(sk);
        struct sock_exterr_skb *serr;
 
-       if (!inet->recverr)
-               return;
-
        skb = skb_clone(skb, GFP_ATOMIC);
        if (!skb)
                return;
@@ -451,7 +448,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                             (1<<IP_TTL) | (1<<IP_HDRINCL) |
                             (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
                             (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
-                            (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
+                            (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
+                            (1<<IP_MINTTL))) ||
            optname == IP_MULTICAST_TTL ||
            optname == IP_MULTICAST_ALL ||
            optname == IP_MULTICAST_LOOP ||
@@ -480,7 +478,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        case IP_OPTIONS:
        {
                struct ip_options *opt = NULL;
-               if (optlen > 40 || optlen < 0)
+               if (optlen > 40)
                        goto e_inval;
                err = ip_options_get_from_user(sock_net(sk), &opt,
                                               optval, optlen);
@@ -575,7 +573,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                inet->hdrincl = val ? 1 : 0;
                break;
        case IP_MTU_DISCOVER:
-               if (val < 0 || val > 3)
+               if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_PROBE)
                        goto e_inval;
                inet->pmtudisc = val;
                break;
@@ -634,17 +632,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                                break;
                        }
                        dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr);
-                       if (dev) {
+                       if (dev)
                                mreq.imr_ifindex = dev->ifindex;
-                               dev_put(dev);
-                       }
                } else
-                       dev = __dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
+                       dev = dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
 
 
                err = -EADDRNOTAVAIL;
                if (!dev)
                        break;
+               dev_put(dev);
 
                err = -EINVAL;
                if (sk->sk_bound_dev_if &&
@@ -937,6 +934,14 @@ mc_msf_out:
                inet->transparent = !!val;
                break;
 
+       case IP_MINTTL:
+               if (optlen < 1)
+                       goto e_inval;
+               if (val < 0 || val > 255)
+                       goto e_inval;
+               inet->min_ttl = val;
+               break;
+
        default:
                err = -ENOPROTOOPT;
                break;
@@ -949,6 +954,22 @@ e_inval:
        return -EINVAL;
 }
 
+/**
+ * ip_queue_rcv_skb - Queue an skb into sock receive queue
+ * @sk: socket
+ * @skb: buffer
+ *
+ * Queues an skb into socket receive queue. If IP_CMSG_PKTINFO option
+ * is not set, we drop skb dst entry now, while dst cache line is hot.
+ */
+int ip_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+       if (!(inet_sk(sk)->cmsg_flags & IP_CMSG_PKTINFO))
+               skb_dst_drop(skb);
+       return sock_queue_rcv_skb(sk, skb);
+}
+EXPORT_SYMBOL(ip_queue_rcv_skb);
+
 int ip_setsockopt(struct sock *sk, int level,
                int optname, char __user *optval, unsigned int optlen)
 {
@@ -1199,6 +1220,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        case IP_TRANSPARENT:
                val = inet->transparent;
                break;
+       case IP_MINTTL:
+               val = inet->min_ttl;
+               break;
        default:
                release_sock(sk);
                return -ENOPROTOOPT;