netfiltr: ipt_CLUSTERIP: simplify seq_file codeA
[safe/jmp/linux-2.6] / net / can / raw.c
index 27aab63..abca920 100644 (file)
@@ -62,6 +62,7 @@ static __initdata const char banner[] =
 MODULE_DESCRIPTION("PF_CAN raw protocol");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
+MODULE_ALIAS("can-proto-1");
 
 #define MASK_ALL 0
 
@@ -99,13 +100,14 @@ static void raw_rcv(struct sk_buff *skb, void *data)
        struct raw_sock *ro = raw_sk(sk);
        struct sockaddr_can *addr;
 
-       if (!ro->recv_own_msgs) {
-               /* check the received tx sock reference */
-               if (skb->sk == sk) {
-                       kfree_skb(skb);
-                       return;
-               }
-       }
+       /* check the received tx sock reference */
+       if (!ro->recv_own_msgs && skb->sk == sk)
+               return;
+
+       /* clone the given skb to be able to enqueue it into the rcv queue */
+       skb = skb_clone(skb, GFP_ATOMIC);
+       if (!skb)
+               return;
 
        /*
         *  Put the datagram to the queue so that raw_recvmsg() can
@@ -305,6 +307,9 @@ static int raw_release(struct socket *sock)
        ro->bound   = 0;
        ro->count   = 0;
 
+       sock_orphan(sk);
+       sock->sk = NULL;
+
        release_sock(sk);
        sock_put(sk);
 
@@ -396,6 +401,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
        if (peer)
                return -EOPNOTSUPP;
 
+       memset(addr, 0, sizeof(*addr));
        addr->can_family  = AF_CAN;
        addr->can_ifindex = ro->ifindex;
 
@@ -405,7 +411,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
 }
 
 static int raw_setsockopt(struct socket *sock, int level, int optname,
-                         char __user *optval, int optlen)
+                         char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct raw_sock *ro = raw_sk(sk);
@@ -418,8 +424,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
 
        if (level != SOL_CAN_RAW)
                return -EINVAL;
-       if (optlen < 0)
-               return -EINVAL;
 
        switch (optname) {
 
@@ -647,6 +651,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
        err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
        if (err < 0)
                goto free_skb;
+       err = sock_tx_timestamp(msg, sk, skb_tx(skb));
+       if (err < 0)
+               goto free_skb;
        skb->dev = dev;
        skb->sk  = sk;
 
@@ -693,7 +700,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
                return err;
        }
 
-       sock_recv_timestamp(msg, sk, skb);
+       sock_recv_ts_and_drops(msg, sk, skb);
 
        if (msg->msg_name) {
                msg->msg_namelen = sizeof(struct sockaddr_can);
@@ -735,7 +742,6 @@ static struct proto raw_proto __read_mostly = {
 static struct can_proto raw_can_proto __read_mostly = {
        .type       = SOCK_RAW,
        .protocol   = CAN_RAW,
-       .capability = -1,
        .ops        = &raw_ops,
        .prot       = &raw_proto,
 };