From: Sven Eckelmann <sven.eckelmann@gmx.de>
To: b.a.t.m.a.n@lists.open-mesh.org
Subject: [B.A.T.M.A.N.] [PATCHv3] batman-adv: Directly prepare icmp packets in socket buffer
Date: Fri, 23 Jul 2010 22:49:24 +0200 [thread overview]
Message-ID: <1279918164-22878-1-git-send-email-sven.eckelmann@gmx.de> (raw)
In-Reply-To: <1279917512-22144-1-git-send-email-sven.eckelmann@gmx.de>
It is unnecessary to generate an icmp packet in an extra memory region
and than copying it to a new allocated skb.
This also resolved the problem that we do inform the user that we
couldn't send the packet because we couldn't allocate the socket buffer.
Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
---
Return -ENOMEM when dev_alloc_skb fails.
batman-adv/icmp_socket.c | 60 +++++++++++++++++++++++++++++-----------------
1 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/batman-adv/icmp_socket.c b/batman-adv/icmp_socket.c
index 6a014a3..8e4316c 100644
--- a/batman-adv/icmp_socket.c
+++ b/batman-adv/icmp_socket.c
@@ -156,7 +156,8 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct socket_client *socket_client = file->private_data;
- 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);
@@ -173,40 +174,53 @@ 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 (icmp_packet.packet_type != BAT_ICMP) {
+ 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) {
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)
goto dst_unreach;
spin_lock_irqsave(&orig_hash_lock, flags);
- orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
+ orig_node = (struct orig_node *)hash_find(orig_hash, icmp_packet->dst);
if (!orig_node)
goto unlock;
@@ -225,21 +239,23 @@ 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, batman_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->orig, batman_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);
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;
}
--
1.7.1
next prev parent reply other threads:[~2010-07-23 20:49 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-23 20:26 [B.A.T.M.A.N.] [PATCH] batman-adv: Directly prepare icmp packets in socket buffer Sven Eckelmann
2010-07-23 20:38 ` [B.A.T.M.A.N.] [PATCHv2] " Sven Eckelmann
2010-07-23 20:49 ` Sven Eckelmann [this message]
2010-07-24 17:56 ` [B.A.T.M.A.N.] [PATCHv3] " Marek Lindner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1279918164-22878-1-git-send-email-sven.eckelmann@gmx.de \
--to=sven.eckelmann@gmx.de \
--cc=b.a.t.m.a.n@lists.open-mesh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).