]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/ipv4/ip_sockglue.c
Merge branches 'acpi-dock', 'acpi-ec' and 'acpi-scan'
[karo-tx-linux.git] / net / ipv4 / ip_sockglue.c
index 5cd99271d3a6a07c17a915fddde7a5a0c8a86618..7cfb0893f2636bcc87537da3014643362f72b10f 100644 (file)
@@ -351,7 +351,7 @@ int ip_ra_control(struct sock *sk, unsigned char on,
                        return 0;
                }
        }
-       if (new_ra == NULL) {
+       if (!new_ra) {
                spin_unlock_bh(&ip_ra_lock);
                return -ENOBUFS;
        }
@@ -387,7 +387,7 @@ void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
                                   skb_network_header(skb);
        serr->port = port;
 
-       if (skb_pull(skb, payload - skb->data) != NULL) {
+       if (skb_pull(skb, payload - skb->data)) {
                skb_reset_transport_header(skb);
                if (sock_queue_err_skb(sk, skb) == 0)
                        return;
@@ -482,7 +482,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
 
        err = -EAGAIN;
        skb = sock_dequeue_err_skb(sk);
-       if (skb == NULL)
+       if (!skb)
                goto out;
 
        copied = skb->len;
@@ -536,12 +536,34 @@ out:
  *     Socket option code for IP. This is the end of the line after any
  *     TCP,UDP etc options on an IP socket.
  */
+static bool setsockopt_needs_rtnl(int optname)
+{
+       switch (optname) {
+       case IP_ADD_MEMBERSHIP:
+       case IP_ADD_SOURCE_MEMBERSHIP:
+       case IP_BLOCK_SOURCE:
+       case IP_DROP_MEMBERSHIP:
+       case IP_DROP_SOURCE_MEMBERSHIP:
+       case IP_MSFILTER:
+       case IP_UNBLOCK_SOURCE:
+       case MCAST_BLOCK_SOURCE:
+       case MCAST_MSFILTER:
+       case MCAST_JOIN_GROUP:
+       case MCAST_JOIN_SOURCE_GROUP:
+       case MCAST_LEAVE_GROUP:
+       case MCAST_LEAVE_SOURCE_GROUP:
+       case MCAST_UNBLOCK_SOURCE:
+               return true;
+       }
+       return false;
+}
 
 static int do_ip_setsockopt(struct sock *sk, int level,
                            int optname, char __user *optval, unsigned int optlen)
 {
        struct inet_sock *inet = inet_sk(sk);
        int val = 0, err;
+       bool needs_rtnl = setsockopt_needs_rtnl(optname);
 
        switch (optname) {
        case IP_PKTINFO:
@@ -584,6 +606,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                return ip_mroute_setsockopt(sk, optname, optval, optlen);
 
        err = 0;
+       if (needs_rtnl)
+               rtnl_lock();
        lock_sock(sk);
 
        switch (optname) {
@@ -1118,10 +1142,14 @@ mc_msf_out:
                break;
        }
        release_sock(sk);
+       if (needs_rtnl)
+               rtnl_unlock();
        return err;
 
 e_inval:
        release_sock(sk);
+       if (needs_rtnl)
+               rtnl_unlock();
        return -EINVAL;
 }