Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 314700
b: refs/heads/master
c: 28afd3c
h: refs/heads/master
v: v3
  • Loading branch information
Sven Eckelmann authored and Antonio Quartulli committed Jun 28, 2012
1 parent 780e139 commit e010b63
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 144 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3e34819e0eafaa6c873e9704bb478c0cdd6bb481
refs/heads/master: 28afd3c0756e0f052a09710c7daa0b9e27700a02
224 changes: 81 additions & 143 deletions trunk/net/batman-adv/vis.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,72 +140,117 @@ static void batadv_vis_data_insert_interface(const uint8_t *interface,
hlist_add_head(&entry->list, if_list);
}

static ssize_t batadv_vis_prim_sec(char *buff, const struct hlist_head *if_list)
static void batadv_vis_data_read_prim_sec(struct seq_file *seq,
const struct hlist_head *if_list)
{
struct if_list_entry *entry;
struct hlist_node *pos;
size_t len = 0;

hlist_for_each_entry(entry, pos, if_list, list) {
if (entry->primary)
len += sprintf(buff + len, "PRIMARY, ");
seq_printf(seq, "PRIMARY, ");
else
len += sprintf(buff + len, "SEC %pM, ", entry->addr);
seq_printf(seq, "SEC %pM, ", entry->addr);
}
}

/* read an entry */
static ssize_t batadv_vis_data_read_entry(struct seq_file *seq,
const struct vis_info_entry *entry,
const uint8_t *src, bool primary)
{
if (primary && entry->quality == 0)
return seq_printf(seq, "TT %pM, ", entry->dest);
else if (batadv_compare_eth(entry->src, src))
return seq_printf(seq, "TQ %pM %d, ", entry->dest,
entry->quality);

return 0;
}

static void batadv_vis_data_insert_interfaces(struct hlist_head *list,
struct vis_packet *packet,
struct vis_info_entry *entries)
{
int i;

for (i = 0; i < packet->entries; i++) {
if (entries[i].quality == 0)
continue;

return len;
if (batadv_compare_eth(entries[i].src, packet->vis_orig))
continue;

batadv_vis_data_insert_interface(entries[i].src, list, false);
}
}

static size_t batadv_vis_cnt_prim_sec(struct hlist_head *if_list)
static void batadv_vis_data_read_entries(struct seq_file *seq,
struct hlist_head *list,
struct vis_packet *packet,
struct vis_info_entry *entries)
{
int i;
struct if_list_entry *entry;
struct hlist_node *pos;
size_t count = 0;

hlist_for_each_entry(entry, pos, if_list, list) {
if (entry->primary)
count += 9;
else
count += 23;
}
hlist_for_each_entry(entry, pos, list, list) {
seq_printf(seq, "%pM,", entry->addr);

for (i = 0; i < packet->entries; i++)
batadv_vis_data_read_entry(seq, &entries[i],
entry->addr, entry->primary);

return count;
/* add primary/secondary records */
if (batadv_compare_eth(entry->addr, packet->vis_orig))
batadv_vis_data_read_prim_sec(seq, list);

seq_printf(seq, "\n");
}
}

/* read an entry */
static ssize_t batadv_vis_data_read_entry(char *buff,
const struct vis_info_entry *entry,
const uint8_t *src, bool primary)
static void batadv_vis_seq_print_text_bucket(struct seq_file *seq,
const struct hlist_head *head)
{
/* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
if (primary && entry->quality == 0)
return sprintf(buff, "TT %pM, ", entry->dest);
else if (batadv_compare_eth(entry->src, src))
return sprintf(buff, "TQ %pM %d, ", entry->dest,
entry->quality);
struct hlist_node *node;
struct vis_info *info;
struct vis_packet *packet;
uint8_t *entries_pos;
struct vis_info_entry *entries;
struct if_list_entry *entry;
struct hlist_node *pos, *n;

return 0;
HLIST_HEAD(vis_if_list);

hlist_for_each_entry_rcu(info, node, head, hash_entry) {
packet = (struct vis_packet *)info->skb_packet->data;
entries_pos = (uint8_t *)packet + sizeof(*packet);
entries = (struct vis_info_entry *)entries_pos;

batadv_vis_data_insert_interface(packet->vis_orig, &vis_if_list,
true);
batadv_vis_data_insert_interfaces(&vis_if_list, packet,
entries);
batadv_vis_data_read_entries(seq, &vis_if_list, packet,
entries);

hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
hlist_del(&entry->list);
kfree(entry);
}
}
}

int batadv_vis_seq_print_text(struct seq_file *seq, void *offset)
{
struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
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);
struct hashtable_t *hash = bat_priv->vis_hash;
HLIST_HEAD(vis_if_list);
struct if_list_entry *entry;
struct hlist_node *pos, *n;
uint32_t i;
int j, ret = 0;
int ret = 0;
int vis_server = atomic_read(&bat_priv->vis_mode);
size_t buff_pos, buf_size;
char *buff;

primary_if = batadv_primary_if_get_selected(bat_priv);
if (!primary_if)
Expand All @@ -214,120 +259,13 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset)
if (vis_server == VIS_TYPE_CLIENT_UPDATE)
goto out;

buf_size = 1;
/* Estimate length */
spin_lock_bh(&bat_priv->vis_hash_lock);
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];

rcu_read_lock();
hlist_for_each_entry_rcu(info, node, head, hash_entry) {
packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
((char *)packet + sizeof(*packet));

batadv_vis_data_insert_interface(packet->vis_orig,
&vis_if_list, true);

for (j = 0; j < packet->entries; j++) {
if (entries[j].quality == 0)
continue;
if (batadv_compare_eth(entries[j].src,
packet->vis_orig))
continue;
batadv_vis_data_insert_interface(entries[j].src,
&vis_if_list,
false);
}

hlist_for_each_entry(entry, pos, &vis_if_list, list) {
buf_size += 18 + 26 * packet->entries;

/* add primary/secondary records */
if (batadv_compare_eth(entry->addr,
packet->vis_orig))
buf_size +=
batadv_vis_cnt_prim_sec(&vis_if_list);

buf_size += 1;
}

hlist_for_each_entry_safe(entry, pos, n, &vis_if_list,
list) {
hlist_del(&entry->list);
kfree(entry);
}
}
rcu_read_unlock();
batadv_vis_seq_print_text_bucket(seq, head);
}

buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
spin_unlock_bh(&bat_priv->vis_hash_lock);
ret = -ENOMEM;
goto out;
}
buff[0] = '\0';
buff_pos = 0;

for (i = 0; i < hash->size; i++) {
head = &hash->table[i];

rcu_read_lock();
hlist_for_each_entry_rcu(info, node, head, hash_entry) {
packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
((char *)packet + sizeof(*packet));

batadv_vis_data_insert_interface(packet->vis_orig,
&vis_if_list, true);

for (j = 0; j < packet->entries; j++) {
if (entries[j].quality == 0)
continue;
if (batadv_compare_eth(entries[j].src,
packet->vis_orig))
continue;
batadv_vis_data_insert_interface(entries[j].src,
&vis_if_list,
false);
}

hlist_for_each_entry(entry, pos, &vis_if_list, list) {
buff_pos += sprintf(buff + buff_pos, "%pM,",
entry->addr);

for (j = 0; j < packet->entries; j++)
buff_pos += batadv_vis_data_read_entry(
buff + buff_pos,
&entries[j],
entry->addr,
entry->primary);

/* add primary/secondary records */
if (batadv_compare_eth(entry->addr,
packet->vis_orig))
buff_pos +=
batadv_vis_prim_sec(buff + buff_pos,
&vis_if_list);

buff_pos += sprintf(buff + buff_pos, "\n");
}

hlist_for_each_entry_safe(entry, pos, n, &vis_if_list,
list) {
hlist_del(&entry->list);
kfree(entry);
}
}
rcu_read_unlock();
}

spin_unlock_bh(&bat_priv->vis_hash_lock);

seq_printf(seq, "%s", buff);
kfree(buff);

out:
if (primary_if)
batadv_hardif_free_ref(primary_if);
Expand Down

0 comments on commit e010b63

Please sign in to comment.