aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/batman-adv/icmp_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/batman-adv/icmp_socket.c')
-rw-r--r--drivers/staging/batman-adv/icmp_socket.c73
1 files changed, 47 insertions, 26 deletions
diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c
index 3ae7dd2d2d4d..48856ca73b6a 100644
--- a/drivers/staging/batman-adv/icmp_socket.c
+++ b/drivers/staging/batman-adv/icmp_socket.c
@@ -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)