Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / staging / batman-adv / icmp_socket.c
index 3ae7dd2..48856ca 100644 (file)
@@ -45,6 +45,8 @@ static int bat_socket_open(struct inode *inode, struct file *file)
        unsigned int i;
        struct socket_client *socket_client;
 
+       nonseekable_open(inode, file);
+
        socket_client = kmalloc(sizeof(struct socket_client), GFP_KERNEL);
 
        if (!socket_client)
@@ -154,7 +156,9 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
 {
        struct socket_client *socket_client = file->private_data;
        struct bat_priv *bat_priv = socket_client->bat_priv;
-       struct icmp_packet_rr icmp_packet;
+       struct sk_buff *skb;
+       struct icmp_packet_rr *icmp_packet;
+
        struct orig_node *orig_node;
        struct batman_if *batman_if;
        size_t packet_len = sizeof(struct icmp_packet);
@@ -174,40 +178,54 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
        if (len >= sizeof(struct icmp_packet_rr))
                packet_len = sizeof(struct icmp_packet_rr);
 
-       if (!access_ok(VERIFY_READ, buff, packet_len))
-               return -EFAULT;
+       skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
+       if (!skb)
+               return -ENOMEM;
 
-       if (__copy_from_user(&icmp_packet, buff, packet_len))
-               return -EFAULT;
+       skb_reserve(skb, sizeof(struct ethhdr));
+       icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
+
+       if (!access_ok(VERIFY_READ, buff, packet_len)) {
+               len = -EFAULT;
+               goto free_skb;
+       }
+
+       if (__copy_from_user(icmp_packet, buff, packet_len)) {
+               len = -EFAULT;
+               goto free_skb;
+       }
 
-       if (icmp_packet.packet_type != BAT_ICMP) {
+       if (icmp_packet->packet_type != BAT_ICMP) {
                bat_dbg(DBG_BATMAN, bat_priv,
                        "Error - can't send packet from char device: "
                        "got bogus packet type (expected: BAT_ICMP)\n");
-               return -EINVAL;
+               len = -EINVAL;
+               goto free_skb;
        }
 
-       if (icmp_packet.msg_type != ECHO_REQUEST) {
+       if (icmp_packet->msg_type != ECHO_REQUEST) {
                bat_dbg(DBG_BATMAN, bat_priv,
                        "Error - can't send packet from char device: "
                        "got bogus message type (expected: ECHO_REQUEST)\n");
-               return -EINVAL;
+               len = -EINVAL;
+               goto free_skb;
        }
 
-       icmp_packet.uid = socket_client->index;
+       icmp_packet->uid = socket_client->index;
 
-       if (icmp_packet.version != COMPAT_VERSION) {
-               icmp_packet.msg_type = PARAMETER_PROBLEM;
-               icmp_packet.ttl = COMPAT_VERSION;
-               bat_socket_add_packet(socket_client, &icmp_packet, packet_len);
-               goto out;
+       if (icmp_packet->version != COMPAT_VERSION) {
+               icmp_packet->msg_type = PARAMETER_PROBLEM;
+               icmp_packet->ttl = COMPAT_VERSION;
+               bat_socket_add_packet(socket_client, icmp_packet, packet_len);
+               goto free_skb;
        }
 
-       if (atomic_read(&module_state) != MODULE_ACTIVE)
+       if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
                goto dst_unreach;
 
-       spin_lock_irqsave(&orig_hash_lock, flags);
-       orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
+       spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+       orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
+                                                  icmp_packet->dst));
 
        if (!orig_node)
                goto unlock;
@@ -218,7 +236,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
        batman_if = orig_node->router->if_incoming;
        memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
 
-       spin_unlock_irqrestore(&orig_hash_lock, flags);
+       spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
 
        if (!batman_if)
                goto dst_unreach;
@@ -226,22 +244,24 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
        if (batman_if->if_status != IF_ACTIVE)
                goto dst_unreach;
 
-       memcpy(icmp_packet.orig,
+       memcpy(icmp_packet->orig,
               bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
 
        if (packet_len == sizeof(struct icmp_packet_rr))
-               memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN);
+               memcpy(icmp_packet->rr, batman_if->net_dev->dev_addr, ETH_ALEN);
+
 
-       send_raw_packet((unsigned char *)&icmp_packet,
-                       packet_len, batman_if, dstaddr);
+       send_skb_packet(skb, batman_if, dstaddr);
 
        goto out;
 
 unlock:
-       spin_unlock_irqrestore(&orig_hash_lock, flags);
+       spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
 dst_unreach:
-       icmp_packet.msg_type = DESTINATION_UNREACHABLE;
-       bat_socket_add_packet(socket_client, &icmp_packet, packet_len);
+       icmp_packet->msg_type = DESTINATION_UNREACHABLE;
+       bat_socket_add_packet(socket_client, icmp_packet, packet_len);
+free_skb:
+       kfree_skb(skb);
 out:
        return len;
 }
@@ -265,6 +285,7 @@ static const struct file_operations fops = {
        .read = bat_socket_read,
        .write = bat_socket_write,
        .poll = bat_socket_poll,
+       .llseek = no_llseek,
 };
 
 int bat_socket_setup(struct bat_priv *bat_priv)