[B.A.T.M.A.N.] [PATCH] batman-adv: Only copy skb data for multiple broadcasts
by Sven Eckelmann
batman-adv tries to resend broadcasts on all interfaces up to three
times. For each round and each interface it must provide a skb which
gets consumed by the sending function.
It is unnecessary to copy the data of each broadcast because the actual
data is either not shared or already copied by add_bcast_packet_to_list.
So it is enough to just copy the skb control data
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
---
batman-adv/send.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/batman-adv/send.c b/batman-adv/send.c
index cd6be2b..934bd8a 100644
--- a/batman-adv/send.c
+++ b/batman-adv/send.c
@@ -476,7 +476,7 @@ static void send_outstanding_bcast_packet(struct work_struct *work)
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
/* send a copy of the saved skb */
- skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
+ skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
if (skb1)
send_skb_packet(skb1,
batman_if, broadcast_addr);
--
1.7.1
12 years, 6 months
[B.A.T.M.A.N.] [PATCH] batman-adv: Directly prepare icmp packets in socket buffer
by Sven Eckelmann
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(a)gmx.de>
---
batman-adv/icmp_socket.c | 58 +++++++++++++++++++++++++++++----------------
1 files changed, 37 insertions(+), 21 deletions(-)
diff --git a/batman-adv/icmp_socket.c b/batman-adv/icmp_socket.c
index 6a014a3..181e7f5 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))
+ skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
+ if (!skb)
return -EFAULT;
- 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)
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
12 years, 6 months
[B.A.T.M.A.N.] [PATCH] batman-adv: Remove unnecessary casts of private_data
by Sven Eckelmann
From: Joe Perches <joe(a)perches.com>
Signed-off-by: Joe Perches <joe(a)perches.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)suse.de>
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
---
This patch is already added to maint. Please also apply it to trunk.
batman-adv/bat_debugfs.c | 4 ++--
batman-adv/icmp_socket.c | 12 ++++--------
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/batman-adv/bat_debugfs.c b/batman-adv/bat_debugfs.c
index 83ec177..c73ce4a 100644
--- a/batman-adv/bat_debugfs.c
+++ b/batman-adv/bat_debugfs.c
@@ -107,7 +107,7 @@ static int log_release(struct inode *inode, struct file *file)
static ssize_t log_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- struct bat_priv *bat_priv = (struct bat_priv *)file->private_data;
+ struct bat_priv *bat_priv = file->private_data;
struct debug_log *debug_log = bat_priv->debug_log;
int error, i = 0;
char c;
@@ -161,7 +161,7 @@ static ssize_t log_read(struct file *file, char __user *buf,
static unsigned int log_poll(struct file *file, poll_table *wait)
{
- struct bat_priv *bat_priv = (struct bat_priv *)file->private_data;
+ struct bat_priv *bat_priv = file->private_data;
struct debug_log *debug_log = bat_priv->debug_log;
poll_wait(file, &debug_log->queue_wait, wait);
diff --git a/batman-adv/icmp_socket.c b/batman-adv/icmp_socket.c
index a84e84d..6a014a3 100644
--- a/batman-adv/icmp_socket.c
+++ b/batman-adv/icmp_socket.c
@@ -80,8 +80,7 @@ static int bat_socket_open(struct inode *inode, struct file *file)
static int bat_socket_release(struct inode *inode, struct file *file)
{
- struct socket_client *socket_client =
- (struct socket_client *)file->private_data;
+ struct socket_client *socket_client = file->private_data;
struct socket_packet *socket_packet;
struct list_head *list_pos, *list_pos_tmp;
unsigned long flags;
@@ -109,8 +108,7 @@ static int bat_socket_release(struct inode *inode, struct file *file)
static ssize_t bat_socket_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- struct socket_client *socket_client =
- (struct socket_client *)file->private_data;
+ struct socket_client *socket_client = file->private_data;
struct socket_packet *socket_packet;
size_t packet_len;
int error;
@@ -157,8 +155,7 @@ 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 =
- (struct socket_client *)file->private_data;
+ struct socket_client *socket_client = file->private_data;
struct icmp_packet_rr icmp_packet;
struct orig_node *orig_node;
struct batman_if *batman_if;
@@ -249,8 +246,7 @@ out:
static unsigned int bat_socket_poll(struct file *file, poll_table *wait)
{
- struct socket_client *socket_client =
- (struct socket_client *)file->private_data;
+ struct socket_client *socket_client = file->private_data;
poll_wait(file, &socket_client->queue_wait, wait);
--
1.7.1
12 years, 6 months
[B.A.T.M.A.N.] multiple mesh clouds (3)
by Marek Lindner
Hi,
I improved the patchset a bit more:
* batctl crash fixed
* batctl man page update
* crash in find_routers()
* cash when forwarding broadcasts
* one forgotten global variable eliminated
Thanks for the (off-list) feedback I received so far. I will submit these
patches if nobody objects during the coming days.
Regards,
Marek
12 years, 6 months
[B.A.T.M.A.N.] [PATCH] batman-adv: Prepare vis packets directly inside a skb
by Sven Eckelmann
The vis information structure is used in a way that it can be transfered
directly as packet. It still had to be copied into an skb because of an
extra buffer used for the actual preparation of the data. This is
unnecessary and can be replaced by a simple clone instead of an full
copy before each send.
This makes also the send_raw_packet function obsolete.
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
---
batman-adv/send.c | 17 -----
batman-adv/send.h | 2 -
batman-adv/vis.c | 206 ++++++++++++++++++++++++++++++++++-------------------
batman-adv/vis.h | 2 +-
4 files changed, 133 insertions(+), 94 deletions(-)
diff --git a/batman-adv/send.c b/batman-adv/send.c
index 09a87c6..19b1962 100644
--- a/batman-adv/send.c
+++ b/batman-adv/send.c
@@ -105,23 +105,6 @@ send_skb_err:
return NET_XMIT_DROP;
}
-/* sends a raw packet. */
-void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
- struct batman_if *batman_if, uint8_t *dst_addr)
-{
- struct sk_buff *skb;
- char *data;
-
- skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
- if (!skb)
- return;
- data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
- memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
- /* pull back to the batman "network header" */
- skb_pull(skb, sizeof(struct ethhdr));
- send_skb_packet(skb, batman_if, dst_addr);
-}
-
/* Send a packet to a given interface */
static void send_packet_to_if(struct forw_packet *forw_packet,
struct batman_if *batman_if)
diff --git a/batman-adv/send.h b/batman-adv/send.h
index b64c627..0cfe027 100644
--- a/batman-adv/send.h
+++ b/batman-adv/send.h
@@ -27,8 +27,6 @@
int send_skb_packet(struct sk_buff *skb,
struct batman_if *batman_if,
uint8_t *dst_addr);
-void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
- struct batman_if *batman_if, uint8_t *dst_addr);
void schedule_own_packet(struct batman_if *batman_if);
void schedule_forward_packet(struct orig_node *orig_node,
struct ethhdr *ethhdr,
diff --git a/batman-adv/vis.c b/batman-adv/vis.c
index 5c825b5..c225e27 100644
--- a/batman-adv/vis.c
+++ b/batman-adv/vis.c
@@ -44,6 +44,8 @@
_dummy > smallest_signed_int(_dummy); })
#define seq_after(x, y) seq_before(y, x)
+#define MAX_VIS_PACKET_SIZE 1000
+
static struct hashtable_t *vis_hash;
static DEFINE_SPINLOCK(vis_hash_lock);
static DEFINE_SPINLOCK(recv_list_lock);
@@ -66,6 +68,7 @@ static void free_info(struct kref *ref)
kfree(entry);
}
spin_unlock_irqrestore(&recv_list_lock, flags);
+ kfree_skb(info->skb_packet);
kfree(info);
}
@@ -73,9 +76,12 @@ static void free_info(struct kref *ref)
static int vis_info_cmp(void *data1, void *data2)
{
struct vis_info *d1, *d2;
+ struct vis_packet *p1, *p2;
d1 = data1;
d2 = data2;
- return compare_orig(d1->packet.vis_orig, d2->packet.vis_orig);
+ p1 = (struct vis_packet *)d1->skb_packet->data;
+ p2 = (struct vis_packet *)d2->skb_packet->data;
+ return compare_orig(p1->vis_orig, p2->vis_orig);
}
/* hash function to choose an entry in a hash table of given size */
@@ -83,11 +89,13 @@ static int vis_info_cmp(void *data1, void *data2)
static int vis_info_choose(void *data, int size)
{
struct vis_info *vis_info = data;
+ struct vis_packet *packet;
unsigned char *key;
uint32_t hash = 0;
size_t i;
- key = vis_info->packet.vis_orig;
+ packet = (struct vis_packet *)vis_info->skb_packet->data;
+ key = packet->vis_orig;
for (i = 0; i < ETH_ALEN; i++) {
hash += key[i];
hash += (hash << 10);
@@ -180,6 +188,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
HASHIT(hashit);
HASHIT(hashit_count);
struct vis_info *info;
+ struct vis_packet *packet;
struct vis_info_entry *entries;
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
@@ -202,22 +211,22 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
spin_lock_irqsave(&vis_hash_lock, flags);
while (hash_iterate(vis_hash, &hashit_count)) {
info = hashit_count.bucket->data;
+ packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
- ((char *)info + sizeof(struct vis_info));
+ ((char *)packet + sizeof(struct vis_packet));
- for (i = 0; i < info->packet.entries; i++) {
+ for (i = 0; i < packet->entries; i++) {
if (entries[i].quality == 0)
continue;
vis_data_insert_interface(entries[i].src, &vis_if_list,
- compare_orig(entries[i].src,
- info->packet.vis_orig));
+ compare_orig(entries[i].src, packet->vis_orig));
}
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
- buf_size += 18 + 26 * info->packet.entries;
+ buf_size += 18 + 26 * packet->entries;
/* add primary/secondary records */
- if (compare_orig(entry->addr, info->packet.vis_orig))
+ if (compare_orig(entry->addr, packet->vis_orig))
buf_size +=
vis_data_count_prim_sec(&vis_if_list);
@@ -240,15 +249,15 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
while (hash_iterate(vis_hash, &hashit)) {
info = hashit.bucket->data;
+ packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
- ((char *)info + sizeof(struct vis_info));
+ ((char *)packet + sizeof(struct vis_packet));
- for (i = 0; i < info->packet.entries; i++) {
+ for (i = 0; i < packet->entries; i++) {
if (entries[i].quality == 0)
continue;
vis_data_insert_interface(entries[i].src, &vis_if_list,
- compare_orig(entries[i].src,
- info->packet.vis_orig));
+ compare_orig(entries[i].src, packet->vis_orig));
}
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
@@ -256,14 +265,14 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
buff_pos += sprintf(buff + buff_pos, "%s,",
tmp_addr_str);
- for (i = 0; i < info->packet.entries; i++)
+ for (i = 0; i < packet->entries; i++)
buff_pos += vis_data_read_entry(buff + buff_pos,
&entries[i],
entry->addr,
entry->primary);
/* add primary/secondary records */
- if (compare_orig(entry->addr, info->packet.vis_orig))
+ if (compare_orig(entry->addr, packet->vis_orig))
buff_pos +=
vis_data_read_prim_sec(buff + buff_pos,
&vis_if_list);
@@ -346,7 +355,9 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
int make_broadcast)
{
struct vis_info *info, *old_info;
+ struct vis_packet *search_packet, *old_packet;
struct vis_info search_elem;
+ struct vis_packet *packet;
*is_new = 0;
/* sanity check */
@@ -354,13 +365,21 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
return NULL;
/* see if the packet is already in vis_hash */
- memcpy(search_elem.packet.vis_orig, vis_packet->vis_orig, ETH_ALEN);
+ search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet));
+ if (!search_elem.skb_packet)
+ return NULL;
+ search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet,
+ sizeof(struct vis_packet));
+
+ memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
old_info = hash_find(vis_hash, &search_elem);
+ kfree_skb(search_elem.skb_packet);
if (old_info != NULL) {
+ old_packet = (struct vis_packet *)old_info->skb_packet->data;
if (!seq_after(ntohl(vis_packet->seqno),
- ntohl(old_info->packet.seqno))) {
- if (old_info->packet.seqno == vis_packet->seqno) {
+ ntohl(old_packet->seqno))) {
+ if (old_packet->seqno == vis_packet->seqno) {
recv_list_add(&old_info->recv_list,
vis_packet->sender_orig);
return old_info;
@@ -375,30 +394,39 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
kref_put(&old_info->refcount, free_info);
}
- info = kmalloc(sizeof(struct vis_info) + vis_info_len, GFP_ATOMIC);
+ info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC);
if (info == NULL)
return NULL;
+ info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) +
+ vis_info_len + sizeof(struct ethhdr));
+ if (!info->skb_packet) {
+ kfree(info);
+ return NULL;
+ }
+ skb_reserve(info->skb_packet, sizeof(struct ethhdr));
+ packet = (struct vis_packet *)skb_put(info->skb_packet,
+ sizeof(struct vis_packet) +
+ vis_info_len);
+
kref_init(&info->refcount);
INIT_LIST_HEAD(&info->send_list);
INIT_LIST_HEAD(&info->recv_list);
info->first_seen = jiffies;
- memcpy(&info->packet, vis_packet,
- sizeof(struct vis_packet) + vis_info_len);
+ memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len);
/* initialize and add new packet. */
*is_new = 1;
/* Make it a broadcast packet, if required */
if (make_broadcast)
- memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
+ memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
/* repair if entries is longer than packet. */
- if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len)
- info->packet.entries = vis_info_len /
- sizeof(struct vis_info_entry);
+ if (packet->entries * sizeof(struct vis_info_entry) > vis_info_len)
+ packet->entries = vis_info_len / sizeof(struct vis_info_entry);
- recv_list_add(&info->recv_list, info->packet.sender_orig);
+ recv_list_add(&info->recv_list, packet->sender_orig);
/* try to add it */
if (hash_add(vis_hash, info) < 0) {
@@ -441,6 +469,7 @@ void receive_client_update_packet(struct bat_priv *bat_priv,
int vis_info_len)
{
struct vis_info *info;
+ struct vis_packet *packet;
int is_new;
unsigned long flags;
int vis_server = atomic_read(&bat_priv->vis_mode);
@@ -457,20 +486,23 @@ void receive_client_update_packet(struct bat_priv *bat_priv,
spin_lock_irqsave(&vis_hash_lock, flags);
info = add_packet(vis_packet, vis_info_len, &is_new, are_target);
+
if (info == NULL)
goto end;
/* note that outdated packets will be dropped at this point. */
+ packet = (struct vis_packet *)info->skb_packet->data;
/* send only if we're the target server or ... */
if (are_target && is_new) {
- info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
+ packet->vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
send_list_add(info);
/* ... we're not the recipient (and thus need to forward). */
- } else if (!is_my_mac(info->packet.target_orig)) {
+ } else if (!is_my_mac(packet->target_orig)) {
send_list_add(info);
}
+
end:
spin_unlock_irqrestore(&vis_hash_lock, flags);
}
@@ -483,8 +515,11 @@ static int find_best_vis_server(struct vis_info *info)
{
HASHIT(hashit);
struct orig_node *orig_node;
+ struct vis_packet *packet;
int best_tq = -1;
+ packet = (struct vis_packet *)info->skb_packet->data;
+
while (hash_iterate(orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
if ((orig_node != NULL) &&
@@ -492,8 +527,7 @@ static int find_best_vis_server(struct vis_info *info)
(orig_node->flags & VIS_SERVER) &&
(orig_node->router->tq_avg > best_tq)) {
best_tq = orig_node->router->tq_avg;
- memcpy(info->packet.target_orig, orig_node->orig,
- ETH_ALEN);
+ memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
}
}
return best_tq;
@@ -502,8 +536,11 @@ static int find_best_vis_server(struct vis_info *info)
/* Return true if the vis packet is full. */
static bool vis_packet_full(struct vis_info *info)
{
- if (info->packet.entries + 1 >
- (1000 - sizeof(struct vis_info)) / sizeof(struct vis_info_entry))
+ struct vis_packet *packet;
+ packet = (struct vis_packet *)info->skb_packet->data;
+
+ if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry)
+ < packet->entries + 1)
return true;
return false;
}
@@ -516,21 +553,23 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
HASHIT(hashit_global);
struct orig_node *orig_node;
struct vis_info *info = (struct vis_info *)my_vis_info;
- struct vis_info_entry *entry, *entry_array;
+ struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
+ struct vis_info_entry *entry;
struct hna_local_entry *hna_local_entry;
int best_tq = -1;
unsigned long flags;
info->first_seen = jiffies;
- info->packet.vis_type = atomic_read(&bat_priv->vis_mode);
+ packet->vis_type = atomic_read(&bat_priv->vis_mode);
spin_lock_irqsave(&orig_hash_lock, flags);
- memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
- info->packet.ttl = TTL;
- info->packet.seqno = htonl(ntohl(info->packet.seqno) + 1);
- info->packet.entries = 0;
+ memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
+ packet->ttl = TTL;
+ packet->seqno = htonl(ntohl(packet->seqno) + 1);
+ packet->entries = 0;
+ skb_trim(info->skb_packet, sizeof(struct vis_packet));
- if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
+ if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) {
best_tq = find_best_vis_server(info);
if (best_tq < 0) {
spin_unlock_irqrestore(&orig_hash_lock, flags);
@@ -538,9 +577,6 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
}
}
- entry_array = (struct vis_info_entry *)
- ((char *)info + sizeof(struct vis_info));
-
while (hash_iterate(orig_hash, &hashit_global)) {
orig_node = hashit_global.bucket->data;
if (orig_node->router != NULL
@@ -551,13 +587,14 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
&& orig_node->router->tq_avg > 0) {
/* fill one entry into buffer. */
- entry = &entry_array[info->packet.entries];
+ entry = (struct vis_info_entry *)
+ skb_put(info->skb_packet, sizeof(*entry));
memcpy(entry->src,
orig_node->router->if_incoming->net_dev->dev_addr,
ETH_ALEN);
memcpy(entry->dest, orig_node->orig, ETH_ALEN);
entry->quality = orig_node->router->tq_avg;
- info->packet.entries++;
+ packet->entries++;
if (vis_packet_full(info)) {
spin_unlock_irqrestore(&orig_hash_lock, flags);
@@ -571,11 +608,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
spin_lock_irqsave(&hna_local_hash_lock, flags);
while (hash_iterate(hna_local_hash, &hashit_local)) {
hna_local_entry = hashit_local.bucket->data;
- entry = &entry_array[info->packet.entries];
+ entry = (struct vis_info_entry *)skb_put(info->skb_packet,
+ sizeof(*entry));
memset(entry->src, 0, ETH_ALEN);
memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
entry->quality = 0; /* 0 means HNA */
- info->packet.entries++;
+ packet->entries++;
if (vis_packet_full(info)) {
spin_unlock_irqrestore(&hna_local_hash_lock, flags);
@@ -606,15 +644,18 @@ static void purge_vis_packets(void)
}
}
-static void broadcast_vis_packet(struct vis_info *info, int packet_length)
+static void broadcast_vis_packet(struct vis_info *info)
{
HASHIT(hashit);
struct orig_node *orig_node;
+ struct vis_packet *packet;
+ struct sk_buff *skb;
unsigned long flags;
struct batman_if *batman_if;
uint8_t dstaddr[ETH_ALEN];
spin_lock_irqsave(&orig_hash_lock, flags);
+ packet = (struct vis_packet *)info->skb_packet->data;
/* send to all routers in range. */
while (hash_iterate(orig_hash, &hashit)) {
@@ -630,31 +671,35 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
if (recv_list_is_in(&info->recv_list, orig_node->orig))
continue;
- memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN);
+ memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
batman_if = orig_node->router->if_incoming;
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
spin_unlock_irqrestore(&orig_hash_lock, flags);
- send_raw_packet((unsigned char *)&info->packet,
- packet_length, batman_if, dstaddr);
+ skb = skb_clone(info->skb_packet, GFP_ATOMIC);
+ if (skb)
+ send_skb_packet(skb, batman_if, dstaddr);
spin_lock_irqsave(&orig_hash_lock, flags);
}
spin_unlock_irqrestore(&orig_hash_lock, flags);
- memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
+ memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
}
-static void unicast_vis_packet(struct vis_info *info, int packet_length)
+static void unicast_vis_packet(struct vis_info *info)
{
struct orig_node *orig_node;
+ struct sk_buff *skb;
+ struct vis_packet *packet;
unsigned long flags;
struct batman_if *batman_if;
uint8_t dstaddr[ETH_ALEN];
spin_lock_irqsave(&orig_hash_lock, flags);
- orig_node = ((struct orig_node *)
- hash_find(orig_hash, info->packet.target_orig));
+ packet = (struct vis_packet *)info->skb_packet->data;
+ orig_node = ((struct orig_node *)hash_find(orig_hash,
+ packet->target_orig));
if ((!orig_node) || (!orig_node->router))
goto out;
@@ -665,8 +710,10 @@ static void unicast_vis_packet(struct vis_info *info, int packet_length)
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
spin_unlock_irqrestore(&orig_hash_lock, flags);
- send_raw_packet((unsigned char *)&info->packet,
- packet_length, batman_if, dstaddr);
+ skb = skb_clone(info->skb_packet, GFP_ATOMIC);
+ if (skb)
+ send_skb_packet(skb, batman_if, dstaddr);
+
return;
out:
@@ -676,24 +723,22 @@ out:
/* only send one vis packet. called from send_vis_packets() */
static void send_vis_packet(struct vis_info *info)
{
- int packet_length;
+ struct vis_packet *packet;
- if (info->packet.ttl < 2) {
+ packet = (struct vis_packet *)info->skb_packet->data;
+ if (packet->ttl < 2) {
pr_warning("Error - can't send vis packet: ttl exceeded\n");
return;
}
- memcpy(info->packet.sender_orig, main_if_addr, ETH_ALEN);
- info->packet.ttl--;
+ memcpy(packet->sender_orig, main_if_addr, ETH_ALEN);
+ packet->ttl--;
- packet_length = sizeof(struct vis_packet) +
- info->packet.entries * sizeof(struct vis_info_entry);
-
- if (is_bcast(info->packet.target_orig))
- broadcast_vis_packet(info, packet_length);
+ if (is_bcast(packet->target_orig))
+ broadcast_vis_packet(info);
else
- unicast_vis_packet(info, packet_length);
- info->packet.ttl++; /* restore TTL */
+ unicast_vis_packet(info);
+ packet->ttl++; /* restore TTL */
}
/* called from timer; send (and maybe generate) vis packet. */
@@ -733,6 +778,7 @@ static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
* initialized (e.g. bat0 is initialized, interfaces have been added) */
int vis_init(void)
{
+ struct vis_packet *packet;
unsigned long flags;
if (vis_hash)
return 1;
@@ -745,27 +791,36 @@ int vis_init(void)
goto err;
}
- my_vis_info = kmalloc(1000, GFP_ATOMIC);
+ my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
if (!my_vis_info) {
pr_err("Can't initialize vis packet\n");
goto err;
}
+ my_vis_info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) +
+ MAX_VIS_PACKET_SIZE +
+ sizeof(struct ethhdr));
+ if (!my_vis_info->skb_packet)
+ goto free_info;
+ skb_reserve(my_vis_info->skb_packet, sizeof(struct ethhdr));
+ packet = (struct vis_packet *)skb_put(my_vis_info->skb_packet,
+ sizeof(struct vis_packet));
+
/* prefill the vis info */
my_vis_info->first_seen = jiffies - msecs_to_jiffies(VIS_INTERVAL);
INIT_LIST_HEAD(&my_vis_info->recv_list);
INIT_LIST_HEAD(&my_vis_info->send_list);
kref_init(&my_vis_info->refcount);
- my_vis_info->packet.version = COMPAT_VERSION;
- my_vis_info->packet.packet_type = BAT_VIS;
- my_vis_info->packet.ttl = TTL;
- my_vis_info->packet.seqno = 0;
- my_vis_info->packet.entries = 0;
+ packet->version = COMPAT_VERSION;
+ packet->packet_type = BAT_VIS;
+ packet->ttl = TTL;
+ packet->seqno = 0;
+ packet->entries = 0;
INIT_LIST_HEAD(&send_list);
- memcpy(my_vis_info->packet.vis_orig, main_if_addr, ETH_ALEN);
- memcpy(my_vis_info->packet.sender_orig, main_if_addr, ETH_ALEN);
+ memcpy(packet->vis_orig, main_if_addr, ETH_ALEN);
+ memcpy(packet->sender_orig, main_if_addr, ETH_ALEN);
if (hash_add(vis_hash, my_vis_info) < 0) {
pr_err("Can't add own vis packet into hash\n");
@@ -778,6 +833,9 @@ int vis_init(void)
start_vis_timer();
return 1;
+free_info:
+ kfree(my_vis_info);
+ my_vis_info = NULL;
err:
spin_unlock_irqrestore(&vis_hash_lock, flags);
vis_quit();
diff --git a/batman-adv/vis.h b/batman-adv/vis.h
index bb13bf1..19dc325 100644
--- a/batman-adv/vis.h
+++ b/batman-adv/vis.h
@@ -32,7 +32,7 @@ struct vis_info {
struct list_head send_list;
struct kref refcount;
/* this packet might be part of the vis send queue. */
- struct vis_packet packet;
+ struct sk_buff *skb_packet;
/* vis_info may follow here*/
} __attribute__((packed));
--
1.7.1
12 years, 6 months
[B.A.T.M.A.N.] [PATCH] batman-adv: Aggregate batman packets directly in skb
by Sven Eckelmann
All originator messages are send through aggregation buffers. Those
buffers can directly be allocated as skb to reduce the cost of
allocation an extra buffer and copying them to a new allocated skb
directly before it gets send.
Now only the skb must be cloned in case of send_packet_to_if as it gets
called by send_packet for each interface. Non-primary ogms must not
cloned at all because they will only send once and the forward_packet
structure is freed by send_outstanding_bat_packet afterwards.
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
---
batman-adv/aggregation.c | 22 ++++++++++++----------
batman-adv/send.c | 24 ++++++++++++------------
batman-adv/types.h | 1 -
3 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/batman-adv/aggregation.c b/batman-adv/aggregation.c
index d738b7a..5896cf2 100644
--- a/batman-adv/aggregation.c
+++ b/batman-adv/aggregation.c
@@ -39,7 +39,7 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
struct forw_packet *forw_packet)
{
struct batman_packet *batman_packet =
- (struct batman_packet *)forw_packet->packet_buff;
+ (struct batman_packet *)forw_packet->skb->data;
int aggregated_bytes = forw_packet->packet_len + packet_len;
/**
@@ -106,6 +106,7 @@ static void new_aggregated_packet(unsigned char *packet_buff,
{
struct forw_packet *forw_packet_aggr;
unsigned long flags;
+ unsigned char *skb_buff;
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
@@ -125,23 +126,22 @@ static void new_aggregated_packet(unsigned char *packet_buff,
return;
}
- forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES,
- GFP_ATOMIC);
- if (!forw_packet_aggr->packet_buff) {
+ forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
+ sizeof(struct ethhdr));
+ if (!forw_packet_aggr->skb) {
if (!own_packet)
atomic_inc(&bat_priv->batman_queue_left);
kfree(forw_packet_aggr);
return;
}
+ skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
INIT_HLIST_NODE(&forw_packet_aggr->list);
+ skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
forw_packet_aggr->packet_len = packet_len;
- memcpy(forw_packet_aggr->packet_buff,
- packet_buff,
- forw_packet_aggr->packet_len);
+ memcpy(skb_buff, packet_buff, packet_len);
- forw_packet_aggr->skb = NULL;
forw_packet_aggr->own = own_packet;
forw_packet_aggr->if_incoming = if_incoming;
forw_packet_aggr->num_packets = 0;
@@ -171,8 +171,10 @@ static void aggregate(struct forw_packet *forw_packet_aggr,
int packet_len,
bool direct_link)
{
- memcpy((forw_packet_aggr->packet_buff + forw_packet_aggr->packet_len),
- packet_buff, packet_len);
+ unsigned char *skb_buff;
+
+ skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
+ memcpy(skb_buff, packet_buff, packet_len);
forw_packet_aggr->packet_len += packet_len;
forw_packet_aggr->num_packets++;
diff --git a/batman-adv/send.c b/batman-adv/send.c
index 934bd8a..89e6643 100644
--- a/batman-adv/send.c
+++ b/batman-adv/send.c
@@ -132,14 +132,14 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
uint8_t packet_num;
int16_t buff_pos;
struct batman_packet *batman_packet;
+ struct sk_buff *skb;
if (batman_if->if_status != IF_ACTIVE)
return;
packet_num = 0;
buff_pos = 0;
- batman_packet = (struct batman_packet *)
- (forw_packet->packet_buff);
+ batman_packet = (struct batman_packet *)forw_packet->skb->data;
/* adjust all flags and log packets */
while (aggregated_packet(buff_pos,
@@ -171,12 +171,13 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
(batman_packet->num_hna * ETH_ALEN);
packet_num++;
batman_packet = (struct batman_packet *)
- (forw_packet->packet_buff + buff_pos);
+ (forw_packet->skb->data + buff_pos);
}
- send_raw_packet(forw_packet->packet_buff,
- forw_packet->packet_len,
- batman_if, broadcast_addr);
+ /* create clone because function is called more than once */
+ skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
+ if (skb)
+ send_skb_packet(skb, batman_if, broadcast_addr);
}
/* send a batman packet */
@@ -186,7 +187,7 @@ static void send_packet(struct forw_packet *forw_packet)
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct batman_if *batman_if;
struct batman_packet *batman_packet =
- (struct batman_packet *)(forw_packet->packet_buff);
+ (struct batman_packet *)(forw_packet->skb->data);
unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) {
@@ -212,10 +213,11 @@ static void send_packet(struct forw_packet *forw_packet)
batman_packet->ttl, forw_packet->if_incoming->dev,
forw_packet->if_incoming->addr_str);
- send_raw_packet(forw_packet->packet_buff,
- forw_packet->packet_len,
- forw_packet->if_incoming,
+ /* skb is only used once and than forw_packet is free'd */
+ send_skb_packet(forw_packet->skb, forw_packet->if_incoming,
broadcast_addr);
+ forw_packet->skb = 0;
+
return;
}
@@ -378,7 +380,6 @@ static void forw_packet_free(struct forw_packet *forw_packet)
{
if (forw_packet->skb)
kfree_skb(forw_packet->skb);
- kfree(forw_packet->packet_buff);
kfree(forw_packet);
}
@@ -437,7 +438,6 @@ int add_bcast_packet_to_list(struct sk_buff *skb)
skb_reset_mac_header(skb);
forw_packet->skb = skb;
- forw_packet->packet_buff = NULL;
/* how often did we send the bcast packet ? */
forw_packet->num_packets = 0;
diff --git a/batman-adv/types.h b/batman-adv/types.h
index e3c4d2d..4977bfb 100644
--- a/batman-adv/types.h
+++ b/batman-adv/types.h
@@ -170,7 +170,6 @@ struct forw_packet {
unsigned long send_time;
uint8_t own;
struct sk_buff *skb;
- unsigned char *packet_buff;
uint16_t packet_len;
uint32_t direct_link_flags;
uint8_t num_packets;
--
1.7.1
12 years, 6 months
[B.A.T.M.A.N.] Staging: batman-adv for 2.6.36 (5)
by Sven Eckelmann
Hi,
first thing: thanks for your help to get some review for batman-adv from davem
and the netdev ml. I've added some new points to the TODO list. They are partly
resolved or work is done to solve them, but will postpone them and get them
hopefully ready and tested for 2.6.37.
Nevertheless there are some smaller changes which want to resolve with 2.6.36.
One is to allow to build it together with dt3155 directly into the kernel and
the other one should fix that we try to change stats of a different device. The
latter one will clash with an unlucky try by the netdev guys to change the
behaviour of dev_get_stats and the batman-adv source code.
This merge conflict is quite easy to resolve. Just delete the dev_get_stats
line in hard-interface.c in batman_skb_recv and the new variable temp added by
them.
I can also provide a patch on top of linux-next instead of staging-next-2.6 if
you would prefer it in this situation. I will call it
"[PATCH-next 1/3] Staging: batman-adv: Don't increment stats of foreign device"
I hope that it doesn't create more confusion as necessary. :)
thanks,
Sven
Randy Dunlap (1):
Staging: batman-adv: don't use default init_module/cleanup_module function names
Sven Eckelmann (2):
Staging: batman-adv: Don't increment stats of foreign device
Staging: batman-adv: Update TODO with new points from review
drivers/staging/batman-adv/TODO | 9 ++++++---
drivers/staging/batman-adv/hard-interface.c | 7 -------
drivers/staging/batman-adv/main.c | 7 +++++--
3 files changed, 11 insertions(+), 12 deletions(-)
12 years, 6 months
[B.A.T.M.A.N.] [PATCH -next] staging: don't use default init_module/cleanup_module function names
by Randy Dunlap
Fromy: Randy Dunlap <randy.dunlap(a)oracle.com>
Fix two staging drivers to use module_init()/module_exit()
instead of default init_module() and cleanup_module() function names
so that there are no name conflicts when both are built-in.
drivers/staging/dt3155/built-in.o: In function `cleanup_module':
(.text+0xc0): multiple definition of `cleanup_module'
drivers/staging/batman-adv/built-in.o:(.text+0x330): first defined here
drivers/staging/dt3155/built-in.o: In function `init_module':
(.text+0xe60): multiple definition of `init_module'
drivers/staging/batman-adv/built-in.o:(.text+0x400): first defined here
Signed-off-by: Randy Dunlap <randy.dunlap(a)oracle.com>
Cc: Scott Smedley <ss(a)aao.gov.au>
Cc: Marek Lindner <lindner_marek(a)yahoo.de>
Cc: Simon Wunderlich <siwu(a)hrz.tu-chemnitz.de>
Cc: Andrew Lunn <andrew(a)lunn.ch>
Cc: b.a.t.m.a.n(a)lists.open-mesh.net
Cc: Greg Kroah-Hartman <gregkh(a)suse.de
---
drivers/staging/batman-adv/main.c | 7 +++++--
drivers/staging/dt3155/dt3155_drv.c | 23 ++++++++++-------------
2 files changed, 15 insertions(+), 15 deletions(-)
--- linux-next-20100719.orig/drivers/staging/batman-adv/main.c
+++ linux-next-20100719/drivers/staging/batman-adv/main.c
@@ -59,7 +59,7 @@ static struct packet_type batman_adv_pac
struct workqueue_struct *bat_event_workqueue;
-int init_module(void)
+int batman_init(void)
{
int retval;
@@ -131,7 +131,7 @@ end:
return -ENOMEM;
}
-void cleanup_module(void)
+void batman_exit(void)
{
deactivate_module();
@@ -273,6 +273,9 @@ int is_mcast(uint8_t *addr)
return *addr & 0x01;
}
+module_init(batman_init);
+module_exit(batman_exit);
+
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
--- linux-next-20100719.orig/drivers/staging/dt3155/dt3155_drv.c
+++ linux-next-20100719/drivers/staging/dt3155/dt3155_drv.c
@@ -47,7 +47,7 @@ MA 02111-1307 USA
+ might want to get rid of MAXboards for allocating initial buffer.
confusing and not necessary
- + in cleanup_module the MOD_IN_USE looks like it is check after it should
+ + in dt3155_exit the MOD_IN_USE looks like it is check after it should
* GFP_DMA should not be set with a PCI system (pg 291)
@@ -166,7 +166,7 @@ static void quick_stop (int minor)
*
* - looks like this isr supports IRQ sharing (or could) JML
* - Assumes irq's are disabled, via SA_INTERRUPT flag
- * being set in request_irq() call from init_module()
+ * being set in request_irq() call from dt3155_init()
*****************************************************/
static void dt3155_isr(int irq, void *dev_id, struct pt_regs *regs)
{
@@ -836,7 +836,7 @@ dt3155_unlocked_ioctl(struct file *file,
/*****************************************************
* file operations supported by DT3155 driver
- * needed by init_module
+ * needed by dt3155_init
* register_chrdev
*****************************************************/
static struct file_operations dt3155_fops = {
@@ -937,10 +937,8 @@ err:
u32 allocatorAddr = 0;
-/*****************************************************
- * init_module()
- *****************************************************/
-int init_module(void)
+
+int dt3155_init(void)
{
struct dt3155_status *dts;
int index;
@@ -1059,16 +1057,13 @@ int init_module(void)
return 0;
}
-/*****************************************************
- * cleanup_module(void)
- *
- *****************************************************/
-void cleanup_module(void)
+
+void dt3155_exit(void)
{
struct dt3155_status *dts;
int index;
- printk("DT3155: cleanup_module called\n");
+ printk("DT3155: dt3155_exit called\n");
/* removed DMA allocated with the allocator */
#ifdef STANDALONE_ALLOCATOR
@@ -1092,3 +1087,5 @@ void cleanup_module(void)
}
}
+module_init(dt3155_init);
+module_exit(dt3155_exit);
12 years, 6 months
[B.A.T.M.A.N.] [PATCH] batman-adv: Calculate hamming weight using optimized kernel functions
by Sven Eckelmann
The Kernighan algorithm is not able to calculate the number of set bits
in parallel and the compiler cannot replace it with optimized
instructions.
The kernel provides specialised functions for each cpu which can either
use a software implementation or hardware instruction depending on the
target cpu.
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
---
batman-adv/bitarray.c | 15 +++++----------
batman-adv/bitarray.h | 3 ++-
2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/batman-adv/bitarray.c b/batman-adv/bitarray.c
index dd4193c..9dbaf1e 100644
--- a/batman-adv/bitarray.c
+++ b/batman-adv/bitarray.c
@@ -22,6 +22,8 @@
#include "main.h"
#include "bitarray.h"
+#include <linux/bitops.h>
+
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
@@ -187,21 +189,14 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
}
/* count the hamming weight, how many good packets did we receive? just count
- * the 1's. The inner loop uses the Kernighan algorithm, see
- * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
+ * the 1's.
*/
int bit_packet_count(TYPE_OF_WORD *seq_bits)
{
int i, hamming = 0;
- TYPE_OF_WORD word;
- for (i = 0; i < NUM_WORDS; i++) {
- word = seq_bits[i];
+ for (i = 0; i < NUM_WORDS; i++)
+ hamming += hweight_long(seq_bits[i]);
- while (word) {
- word &= word-1;
- hamming++;
- }
- }
return hamming;
}
diff --git a/batman-adv/bitarray.h b/batman-adv/bitarray.h
index 01897d6..c0c1730 100644
--- a/batman-adv/bitarray.h
+++ b/batman-adv/bitarray.h
@@ -22,7 +22,8 @@
#ifndef _NET_BATMAN_ADV_BITARRAY_H_
#define _NET_BATMAN_ADV_BITARRAY_H_
-/* you should choose something big, if you don't want to waste cpu */
+/* you should choose something big, if you don't want to waste cpu
+ and keep the type in sync with bit_packet_count */
#define TYPE_OF_WORD unsigned long
#define WORD_BIT_SIZE (sizeof(TYPE_OF_WORD) * 8)
--
1.7.1
12 years, 6 months
[B.A.T.M.A.N.] [PATCH] batman-adv: Don't increment stats of foreign device
by Sven Eckelmann
The receive hook for batman-adv ethernet frames tried to get the last
device which processed the skb before us. It only used that information
to update the rx_bytes and rx_packets stat of that foreign device which
already has updated it using its own receive functions.
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
---
batman-adv/compat.h | 8 --------
batman-adv/hard-interface.c | 8 --------
2 files changed, 0 insertions(+), 16 deletions(-)
diff --git a/batman-adv/compat.h b/batman-adv/compat.h
index 103593d..09016c8 100644
--- a/batman-adv/compat.h
+++ b/batman-adv/compat.h
@@ -249,12 +249,4 @@ static inline struct net_device_stats *dev_get_stats(struct net_device *dev)
#endif /* < KERNEL_VERSION(2, 6, 29) */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
-
-#define dev_get_stats(x, y) dev_get_stats(x)
-
-#define rtnl_link_stats64 rtnl_link_stats __attribute__((unused))
-
-#endif /* < KERNEL_VERSION(2, 6, 36) */
-
#endif /* _NET_BATMAN_ADV_COMPAT_H_ */
diff --git a/batman-adv/hard-interface.c b/batman-adv/hard-interface.c
index a072c3d..fdabe4f 100644
--- a/batman-adv/hard-interface.c
+++ b/batman-adv/hard-interface.c
@@ -471,8 +471,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct batman_packet *batman_packet;
struct batman_if *batman_if;
- struct net_device_stats *stats;
- struct rtnl_link_stats64 temp;
int ret;
skb = skb_share_check(skb, GFP_ATOMIC);
@@ -508,12 +506,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
if (batman_if->if_status != IF_ACTIVE)
goto err_free;
- stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp);
- if (stats) {
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
- }
-
batman_packet = (struct batman_packet *)skb->data;
if (batman_packet->version != COMPAT_VERSION) {
--
1.7.1
12 years, 6 months