Staging: batman-adv: Fix VIS output bug for secondary interfaces

TQ and HNA records for originators on secondary interfaces were
wrongly being included on the primary interface. Ensure we output a
line for each source interface on every node, so we correctly separate
primary and secondary interface records.

Signed-off-by: Linus Lüssing <linus.luessing@web.de>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Linus Lüssing 2010-03-22 22:46:14 +01:00 коммит произвёл Greg Kroah-Hartman
Родитель 107c32fe68
Коммит f6497e38fd
3 изменённых файлов: 49 добавлений и 34 удалений

Просмотреть файл

@ -41,7 +41,7 @@ static int proc_interfaces_read(struct seq_file *seq, void *offset)
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) { list_for_each_entry_rcu(batman_if, &if_list, list) {
seq_printf(seq, "[%8s] %s %s \n", seq_printf(seq, "[%8s] %s %s\n",
(batman_if->if_active == IF_ACTIVE ? (batman_if->if_active == IF_ACTIVE ?
"active" : "inactive"), "active" : "inactive"),
batman_if->dev, batman_if->dev,
@ -188,18 +188,18 @@ static int proc_originators_read(struct seq_file *seq, void *offset)
rcu_read_lock(); rcu_read_lock();
if (list_empty(&if_list)) { if (list_empty(&if_list)) {
rcu_read_unlock(); rcu_read_unlock();
seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n"); seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n");
goto end; goto end;
} }
if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
rcu_read_unlock(); rcu_read_unlock();
seq_printf(seq, "BATMAN disabled - primary interface not active \n"); seq_printf(seq, "BATMAN disabled - primary interface not active\n");
goto end; goto end;
} }
seq_printf(seq, seq_printf(seq,
" %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n", " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s]\n",
"Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
"Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
((struct batman_if *)if_list.next)->dev, ((struct batman_if *)if_list.next)->dev,
@ -240,7 +240,7 @@ static int proc_originators_read(struct seq_file *seq, void *offset)
spin_unlock_irqrestore(&orig_hash_lock, flags); spin_unlock_irqrestore(&orig_hash_lock, flags);
if (batman_count == 0) if (batman_count == 0)
seq_printf(seq, "No batman nodes in range ... \n"); seq_printf(seq, "No batman nodes in range ...\n");
end: end:
return 0; return 0;
@ -262,7 +262,7 @@ static int proc_transt_local_read(struct seq_file *seq, void *offset)
rcu_read_lock(); rcu_read_lock();
if (list_empty(&if_list)) { if (list_empty(&if_list)) {
rcu_read_unlock(); rcu_read_unlock();
seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n"); seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n");
goto end; goto end;
} }
@ -294,7 +294,7 @@ static int proc_transt_global_read(struct seq_file *seq, void *offset)
rcu_read_lock(); rcu_read_lock();
if (list_empty(&if_list)) { if (list_empty(&if_list)) {
rcu_read_unlock(); rcu_read_unlock();
seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n"); seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n");
goto end; goto end;
} }
rcu_read_unlock(); rcu_read_unlock();
@ -350,9 +350,9 @@ static int proc_vis_srv_read(struct seq_file *seq, void *offset)
{ {
int vis_server = atomic_read(&vis_mode); int vis_server = atomic_read(&vis_mode);
seq_printf(seq, "[%c] client mode (server disabled) \n", seq_printf(seq, "[%c] client mode (server disabled)\n",
(vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' '); (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' ');
seq_printf(seq, "[%c] server mode (server enabled) \n", seq_printf(seq, "[%c] server mode (server enabled)\n",
(vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' '); (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' ');
return 0; return 0;
@ -369,6 +369,8 @@ static int proc_vis_data_read(struct seq_file *seq, void *offset)
struct vis_info *info; struct vis_info *info;
struct vis_info_entry *entries; struct vis_info_entry *entries;
HLIST_HEAD(vis_if_list); HLIST_HEAD(vis_if_list);
struct if_list_entry *entry;
struct hlist_node *pos, *n;
int i; int i;
char tmp_addr_str[ETH_STR_LEN]; char tmp_addr_str[ETH_STR_LEN];
unsigned long flags; unsigned long flags;
@ -387,18 +389,35 @@ static int proc_vis_data_read(struct seq_file *seq, void *offset)
info = hashit.bucket->data; info = hashit.bucket->data;
entries = (struct vis_info_entry *) entries = (struct vis_info_entry *)
((char *)info + sizeof(struct vis_info)); ((char *)info + sizeof(struct vis_info));
addr_to_string(tmp_addr_str, info->packet.vis_orig);
seq_printf(seq, "%s,", tmp_addr_str);
for (i = 0; i < info->packet.entries; i++) { for (i = 0; i < info->packet.entries; i++) {
proc_vis_read_entry(seq, &entries[i], &vis_if_list, if (entries[i].quality == 0)
info->packet.vis_orig); continue;
proc_vis_insert_interface(entries[i].src, &vis_if_list,
compare_orig(entries[i].src,
info->packet.vis_orig));
} }
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
addr_to_string(tmp_addr_str, entry->addr);
seq_printf(seq, "%s,", tmp_addr_str);
for (i = 0; i < info->packet.entries; i++)
proc_vis_read_entry(seq, &entries[i],
entry->addr, entry->primary);
/* add primary/secondary records */ /* add primary/secondary records */
if (compare_orig(entry->addr, info->packet.vis_orig))
proc_vis_read_prim_sec(seq, &vis_if_list); proc_vis_read_prim_sec(seq, &vis_if_list);
seq_printf(seq, "\n"); seq_printf(seq, "\n");
} }
hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
hlist_del(&entry->list);
kfree(entry);
}
}
spin_unlock_irqrestore(&vis_hash_lock, flags); spin_unlock_irqrestore(&vis_hash_lock, flags);
end: end:

Просмотреть файл

@ -86,7 +86,7 @@ static int vis_info_choose(void *data, int size)
/* insert interface to the list of interfaces of one originator, if it /* insert interface to the list of interfaces of one originator, if it
* does not already exist in the list */ * does not already exist in the list */
static void proc_vis_insert_interface(const uint8_t *interface, void proc_vis_insert_interface(const uint8_t *interface,
struct hlist_head *if_list, struct hlist_head *if_list,
bool primary) bool primary)
{ {
@ -111,39 +111,32 @@ void proc_vis_read_prim_sec(struct seq_file *seq,
struct hlist_head *if_list) struct hlist_head *if_list)
{ {
struct if_list_entry *entry; struct if_list_entry *entry;
struct hlist_node *pos, *n; struct hlist_node *pos;
char tmp_addr_str[ETH_STR_LEN]; char tmp_addr_str[ETH_STR_LEN];
hlist_for_each_entry_safe(entry, pos, n, if_list, list) { hlist_for_each_entry(entry, pos, if_list, list) {
if (entry->primary) { if (entry->primary)
seq_printf(seq, "PRIMARY, "); seq_printf(seq, "PRIMARY, ");
} else { else {
addr_to_string(tmp_addr_str, entry->addr); addr_to_string(tmp_addr_str, entry->addr);
seq_printf(seq, "SEC %s, ", tmp_addr_str); seq_printf(seq, "SEC %s, ", tmp_addr_str);
} }
hlist_del(&entry->list);
kfree(entry);
} }
} }
/* read an entry */ /* read an entry */
void proc_vis_read_entry(struct seq_file *seq, void proc_vis_read_entry(struct seq_file *seq,
struct vis_info_entry *entry, struct vis_info_entry *entry,
struct hlist_head *if_list, uint8_t *src,
uint8_t *vis_orig) bool primary)
{ {
char to[40]; char to[40];
addr_to_string(to, entry->dest); addr_to_string(to, entry->dest);
if (entry->quality == 0) { if (primary && entry->quality == 0)
proc_vis_insert_interface(vis_orig, if_list, true);
seq_printf(seq, "HNA %s, ", to); seq_printf(seq, "HNA %s, ", to);
} else { else if (compare_orig(entry->src, src))
proc_vis_insert_interface(entry->src, if_list,
compare_orig(entry->src, vis_orig));
seq_printf(seq, "TQ %s %d, ", to, entry->quality); seq_printf(seq, "TQ %s %d, ", to, entry->quality);
}
} }
/* add the info packet to the send list, if it was not /* add the info packet to the send list, if it was not

Просмотреть файл

@ -49,10 +49,13 @@ struct recvlist_node {
extern struct hashtable_t *vis_hash; extern struct hashtable_t *vis_hash;
extern spinlock_t vis_hash_lock; extern spinlock_t vis_hash_lock;
void proc_vis_insert_interface(const uint8_t *interface,
struct hlist_head *if_list,
bool primary);
void proc_vis_read_entry(struct seq_file *seq, void proc_vis_read_entry(struct seq_file *seq,
struct vis_info_entry *entry, struct vis_info_entry *entry,
struct hlist_head *if_list, uint8_t *src,
uint8_t *vis_orig); bool primary);
void proc_vis_read_prim_sec(struct seq_file *seq, void proc_vis_read_prim_sec(struct seq_file *seq,
struct hlist_head *if_list); struct hlist_head *if_list);
void receive_server_sync_packet(struct vis_packet *vis_packet, void receive_server_sync_packet(struct vis_packet *vis_packet,