]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/ipv6/raw.c
Merge branch 'master' into tk71
[mv-sheeva.git] / net / ipv6 / raw.c
index e677937a07fc2e4e4a28cd6b3ac044a808d3d355..c5b0915d106bfe788cdf6d691e1c6c371831c86c 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/skbuff.h>
+#include <linux/compat.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 
@@ -373,7 +374,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
 
 static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
 {
-       if ((raw6_sk(sk)->checksum || sk->sk_filter) &&
+       if ((raw6_sk(sk)->checksum || rcu_dereference_raw(sk->sk_filter)) &&
            skb_checksum_complete(skb)) {
                atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
@@ -764,7 +765,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
                        return -EINVAL;
 
                if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
-                       return(-EAFNOSUPPORT);
+                       return -EAFNOSUPPORT;
 
                /* port is the proto value [0..255] carried in nexthdr */
                proto = ntohs(sin6->sin6_port);
@@ -772,10 +773,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
                if (!proto)
                        proto = inet->inet_num;
                else if (proto != inet->inet_num)
-                       return(-EINVAL);
+                       return -EINVAL;
 
                if (proto > 255)
-                       return(-EINVAL);
+                       return -EINVAL;
 
                daddr = &sin6->sin6_addr;
                if (np->sndflow) {
@@ -985,7 +986,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
                        /* You may get strange result with a positive odd offset;
                           RFC2292bis agrees with me. */
                        if (val > 0 && (val&1))
-                               return(-EINVAL);
+                               return -EINVAL;
                        if (val < 0) {
                                rp->checksum = 0;
                        } else {
@@ -997,7 +998,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
                        break;
 
                default:
-                       return(-ENOPROTOOPT);
+                       return -ENOPROTOOPT;
        }
 }
 
@@ -1157,6 +1158,23 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
        }
 }
 
+#ifdef CONFIG_COMPAT
+static int compat_rawv6_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
+{
+       switch (cmd) {
+       case SIOCOUTQ:
+       case SIOCINQ:
+               return -ENOIOCTLCMD;
+       default:
+#ifdef CONFIG_IPV6_MROUTE
+               return ip6mr_compat_ioctl(sk, cmd, compat_ptr(arg));
+#else
+               return -ENOIOCTLCMD;
+#endif
+       }
+}
+#endif
+
 static void rawv6_close(struct sock *sk, long timeout)
 {
        if (inet_sk(sk)->inet_num == IPPROTO_RAW)
@@ -1190,7 +1208,7 @@ static int rawv6_init_sk(struct sock *sk)
        default:
                break;
        }
-       return(0);
+       return 0;
 }
 
 struct proto rawv6_prot = {
@@ -1215,6 +1233,7 @@ struct proto rawv6_prot = {
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_rawv6_setsockopt,
        .compat_getsockopt = compat_rawv6_getsockopt,
+       .compat_ioctl      = compat_rawv6_ioctl,
 #endif
 };