/*
- * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
#include "vis.h"
static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
-static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file;
-static struct proc_dir_entry *proc_transt_local_file;
-static struct proc_dir_entry *proc_transt_global_file;
+static struct proc_dir_entry *proc_orig_interval_file;
static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file;
-static struct proc_dir_entry *proc_aggr_file;
static int proc_interfaces_read(struct seq_file *seq, void *offset)
{
rcu_read_lock();
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 ?
"active" : "inactive"),
batman_if->dev,
size_t count, loff_t *data)
{
char *if_string, *colon_ptr = NULL, *cr_ptr = NULL;
- int not_copied = 0, if_num = 0;
+ int not_copied = 0, if_num = 0, add_success;
struct batman_if *batman_if = NULL;
if_string = kmalloc(count, GFP_KERNEL);
}
rcu_read_unlock();
- hardif_add_interface(if_string, if_num);
+ add_success = hardif_add_interface(if_string, if_num);
+ if (add_success < 0)
+ goto end;
+
+ num_ifs = if_num + 1;
if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
(hardif_get_active_if_num() > 0))
activate_module();
- rcu_read_lock();
- if (list_empty(&if_list)) {
- rcu_read_unlock();
- goto end;
- }
- rcu_read_unlock();
-
- num_ifs = if_num + 1;
return count;
-
end:
kfree(if_string);
return count;
return single_open(file, proc_orig_interval_read, NULL);
}
-static int proc_originators_read(struct seq_file *seq, void *offset)
-{
- HASHIT(hashit);
- struct orig_node *orig_node;
- struct neigh_node *neigh_node;
- int batman_count = 0;
- char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
- unsigned long flags;
-
- rcu_read_lock();
- if (list_empty(&if_list)) {
- rcu_read_unlock();
- seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
- goto end;
- }
-
- if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
- rcu_read_unlock();
- seq_printf(seq, "BATMAN disabled - primary interface not active \n");
- goto end;
- }
-
- seq_printf(seq,
- " %-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",
- "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
- ((struct batman_if *)if_list.next)->dev,
- ((struct batman_if *)if_list.next)->addr_str);
-
- rcu_read_unlock();
- spin_lock_irqsave(&orig_hash_lock, flags);
-
- while (hash_iterate(orig_hash, &hashit)) {
-
- orig_node = hashit.bucket->data;
-
- if (!orig_node->router)
- continue;
-
- if (orig_node->router->tq_avg == 0)
- continue;
-
- batman_count++;
-
- addr_to_string(orig_str, orig_node->orig);
- addr_to_string(router_str, orig_node->router->addr);
-
- seq_printf(seq, "%-17s (%3i) %17s [%10s]:",
- orig_str, orig_node->router->tq_avg,
- router_str, orig_node->router->if_incoming->dev);
-
- list_for_each_entry(neigh_node, &orig_node->neigh_list, list) {
- addr_to_string(orig_str, neigh_node->addr);
- seq_printf(seq, " %17s (%3i)",
- orig_str, neigh_node->tq_avg);
- }
-
- seq_printf(seq, "\n");
-
- }
-
- spin_unlock_irqrestore(&orig_hash_lock, flags);
-
- if (batman_count == 0)
- seq_printf(seq, "No batman nodes in range ... \n");
-
-end:
- return 0;
-}
-
-static int proc_originators_open(struct inode *inode, struct file *file)
-{
- return single_open(file, proc_originators_read, NULL);
-}
-
-static int proc_transt_local_read(struct seq_file *seq, void *offset)
-{
- char *buf;
-
- buf = kmalloc(4096, GFP_KERNEL);
- if (!buf)
- return 0;
-
- rcu_read_lock();
- if (list_empty(&if_list)) {
- rcu_read_unlock();
- seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
- goto end;
- }
-
- rcu_read_unlock();
-
- seq_printf(seq, "Locally retrieved addresses (from %s) announced via HNA:\n", soft_device->name);
-
- hna_local_fill_buffer_text(buf, 4096);
- seq_printf(seq, "%s", buf);
-
-end:
- kfree(buf);
- return 0;
-}
-
-static int proc_transt_local_open(struct inode *inode, struct file *file)
-{
- return single_open(file, proc_transt_local_read, NULL);
-}
-
-static int proc_transt_global_read(struct seq_file *seq, void *offset)
-{
- char *buf;
-
- buf = kmalloc(4096, GFP_KERNEL);
- if (!buf)
- return 0;
-
- rcu_read_lock();
- if (list_empty(&if_list)) {
- rcu_read_unlock();
- seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
- goto end;
- }
- rcu_read_unlock();
-
-
- seq_printf(seq, "Globally announced HNAs received via the mesh (translation table):\n");
-
- hna_global_fill_buffer_text(buf, 4096);
- seq_printf(seq, "%s", buf);
-
-end:
- kfree(buf);
- return 0;
-}
-
-static int proc_transt_global_open(struct inode *inode, struct file *file)
-{
- return single_open(file, proc_transt_global_read, NULL);
-}
-
/* setting the mode of the vis server by the user */
static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer,
size_t count, loff_t *ppos)
if ((strcmp(vis_mode_string, "client") == 0) ||
(strcmp(vis_mode_string, "disabled") == 0)) {
printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n");
- vis_set_mode(VIS_TYPE_CLIENT_UPDATE);
+ atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
} else if ((strcmp(vis_mode_string, "server") == 0) ||
(strcmp(vis_mode_string, "enabled") == 0)) {
printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n");
- vis_set_mode(VIS_TYPE_SERVER_SYNC);
+ atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC);
} else
printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n",
vis_mode_string);
static int proc_vis_srv_read(struct seq_file *seq, void *offset)
{
- int vis_server = is_vis_server();
+ int vis_server = atomic_read(&vis_mode);
- seq_printf(seq, "[%c] client mode (server disabled) \n",
- (!vis_server) ? 'x' : ' ');
- seq_printf(seq, "[%c] server mode (server enabled) \n",
- (vis_server) ? 'x' : ' ');
+ seq_printf(seq, "[%c] client mode (server disabled)\n",
+ (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' ');
+ seq_printf(seq, "[%c] server mode (server enabled)\n",
+ (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' ');
return 0;
}
struct vis_info *info;
struct vis_info_entry *entries;
HLIST_HEAD(vis_if_list);
+ struct if_list_entry *entry;
+ struct hlist_node *pos, *n;
int i;
char tmp_addr_str[ETH_STR_LEN];
unsigned long flags;
+ int vis_server = atomic_read(&vis_mode);
rcu_read_lock();
- if (list_empty(&if_list) || (!is_vis_server())) {
+ if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) {
rcu_read_unlock();
goto end;
}
info = hashit.bucket->data;
entries = (struct vis_info_entry *)
((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++) {
- proc_vis_read_entry(seq, &entries[i], &vis_if_list,
- info->packet.vis_orig);
+ if (entries[i].quality == 0)
+ continue;
+ proc_vis_insert_interface(entries[i].src, &vis_if_list,
+ compare_orig(entries[i].src,
+ info->packet.vis_orig));
}
- /* add primary/secondary records */
- proc_vis_read_prim_sec(seq, &vis_if_list);
- seq_printf(seq, "\n");
+ 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 */
+ if (compare_orig(entry->addr, info->packet.vis_orig))
+ proc_vis_read_prim_sec(seq, &vis_if_list);
+
+ 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);
return single_open(file, proc_vis_data_read, NULL);
}
-static int proc_aggr_read(struct seq_file *seq, void *offset)
-{
- seq_printf(seq, "%i\n", atomic_read(&aggregation_enabled));
-
- return 0;
-}
-
-static ssize_t proc_aggr_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- char *aggr_string;
- int not_copied = 0;
- unsigned long aggregation_enabled_tmp;
- int retval;
-
- aggr_string = kmalloc(count, GFP_KERNEL);
-
- if (!aggr_string)
- return -ENOMEM;
-
- not_copied = copy_from_user(aggr_string, buffer, count);
- aggr_string[count - not_copied - 1] = 0;
-
- retval = strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp);
-
- if (retval || aggregation_enabled_tmp > 1) {
- printk(KERN_ERR "batman-adv:Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
- } else {
- printk(KERN_INFO "batman-adv:Changing aggregation from: %s (%i) to: %s (%li)\n",
- (atomic_read(&aggregation_enabled) == 1 ?
- "enabled" : "disabled"),
- atomic_read(&aggregation_enabled),
- (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
- aggregation_enabled_tmp);
- atomic_set(&aggregation_enabled,
- (unsigned)aggregation_enabled_tmp);
- }
-
- kfree(aggr_string);
- return count;
-}
-
-static int proc_aggr_open(struct inode *inode, struct file *file)
-{
- return single_open(file, proc_aggr_read, NULL);
-}
-
/* satisfying different prototypes ... */
static ssize_t proc_dummy_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
return count;
}
-static const struct file_operations proc_aggr_fops = {
- .owner = THIS_MODULE,
- .open = proc_aggr_open,
- .read = seq_read,
- .write = proc_aggr_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
static const struct file_operations proc_vis_srv_fops = {
.owner = THIS_MODULE,
.open = proc_vis_srv_open,
.release = single_release,
};
-static const struct file_operations proc_originators_fops = {
- .owner = THIS_MODULE,
- .open = proc_originators_open,
- .read = seq_read,
- .write = proc_dummy_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations proc_transt_local_fops = {
- .owner = THIS_MODULE,
- .open = proc_transt_local_open,
- .read = seq_read,
- .write = proc_dummy_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations proc_transt_global_fops = {
- .owner = THIS_MODULE,
- .open = proc_transt_global_open,
- .read = seq_read,
- .write = proc_dummy_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
static const struct file_operations proc_interfaces_fops = {
.owner = THIS_MODULE,
.open = proc_interfaces_open,
void cleanup_procfs(void)
{
- if (proc_transt_global_file)
- remove_proc_entry(PROC_FILE_TRANST_GLOBAL, proc_batman_dir);
-
- if (proc_transt_local_file)
- remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir);
-
- if (proc_originators_file)
- remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir);
-
if (proc_orig_interval_file)
remove_proc_entry(PROC_FILE_ORIG_INTERVAL, proc_batman_dir);
if (proc_vis_srv_file)
remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir);
- if (proc_aggr_file)
- remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir);
-
if (proc_batman_dir)
#ifdef __NET_NET_NAMESPACE_H
remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net);
return -EFAULT;
}
- proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS,
- S_IRUGO, proc_batman_dir);
- if (proc_originators_file) {
- proc_originators_file->proc_fops = &proc_originators_fops;
- } else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_ORIGINATORS);
- cleanup_procfs();
- return -EFAULT;
- }
-
- proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL,
- S_IRUGO, proc_batman_dir);
- if (proc_transt_local_file) {
- proc_transt_local_file->proc_fops = &proc_transt_local_fops;
- } else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_TRANST_LOCAL);
- cleanup_procfs();
- return -EFAULT;
- }
-
- proc_transt_global_file = create_proc_entry(PROC_FILE_TRANST_GLOBAL,
- S_IRUGO, proc_batman_dir);
- if (proc_transt_global_file) {
- proc_transt_global_file->proc_fops = &proc_transt_global_fops;
- } else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_TRANST_GLOBAL);
- cleanup_procfs();
- return -EFAULT;
- }
-
proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV,
S_IWUSR | S_IRUGO,
proc_batman_dir);
return -EFAULT;
}
- proc_aggr_file = create_proc_entry(PROC_FILE_AGGR, S_IWUSR | S_IRUGO,
- proc_batman_dir);
- if (proc_aggr_file) {
- proc_aggr_file->proc_fops = &proc_aggr_fops;
- } else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_AGGR);
- cleanup_procfs();
- return -EFAULT;
- }
-
return 0;
}
-
-