@@ -165,10 +165,10 @@ static void aggregate(struct forw_packet *forw_packet_aggr,
(1 << forw_packet_aggr->num_packets);
}
-void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
+void add_bat_packet_to_list(struct bat_priv *bat_priv,
+ unsigned char *packet_buff, int packet_len,
struct batman_if *if_incoming, char own_packet,
- unsigned long send_time,
- struct bat_priv *bat_priv)
+ unsigned long send_time)
{
/**
* _aggr -> pointer to the packet we want to aggregate with
@@ -30,9 +30,9 @@ static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna)
(next_buff_pos <= MAX_AGGREGATION_BYTES);
}
-void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
- struct batman_if *if_outgoing, char own_packet,
- unsigned long send_time,
- struct bat_priv *bat_priv);
+void add_bat_packet_to_list(struct bat_priv *bat_priv,
+ unsigned char *packet_buff, int packet_len,
+ struct batman_if *if_incoming, char own_packet,
+ unsigned long send_time);
void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
int packet_len, struct batman_if *if_incoming);
@@ -24,6 +24,7 @@
#include "translation-table.h"
#include "originator.h"
#include "hard-interface.h"
+#include "vis.h"
#define to_dev(obj) container_of(obj, struct device, kobj)
@@ -99,11 +100,66 @@ static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr,
return count;
}
+static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
+ char *buff)
+{
+ struct device *dev = to_dev(kobj->parent);
+ struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+ int vis_mode = atomic_read(&bat_priv->vis_mode);
+
+ return sprintf(buff, "status: %s\ncommands: client, server, %d, %d \n",
+ vis_mode == VIS_TYPE_CLIENT_UPDATE ?
+ "client" : "server",
+ VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE);
+}
+
+static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
+ char *buff, size_t count)
+{
+ struct device *dev = to_dev(kobj->parent);
+ struct net_device *net_dev = to_net_dev(dev);
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ unsigned long val;
+ int ret, vis_mode_tmp = -1;
+
+ ret = strict_strtoul(buff, 10, &val);
+
+ if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) ||
+ (strncmp(buff, "client", 6) == 0))
+ vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE;
+
+ if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) ||
+ (strncmp(buff, "server", 6) == 0))
+ vis_mode_tmp = VIS_TYPE_SERVER_SYNC;
+
+ if (vis_mode_tmp < 0) {
+ if (buff[count - 1] == '\n')
+ buff[count - 1] = '\0';
+
+ printk(KERN_INFO "batman-adv:Invalid parameter for 'vis mode' setting on mesh %s received: %s\n",
+ net_dev->name, buff);
+ return -EINVAL;
+ }
+
+ if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
+ return count;
+
+ printk(KERN_INFO "batman-adv:Changing vis mode from: %s to: %s on mesh: %s\n",
+ atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ?
+ "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ?
+ "client" : "server", net_dev->name);
+
+ atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp);
+ return count;
+}
+
static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR,
show_aggr_ogm, store_aggr_ogm);
+static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
static struct bat_attribute *mesh_attrs[] = {
&bat_attr_aggregate_ogm,
+ &bat_attr_vis_mode,
NULL,
};
@@ -114,19 +170,6 @@ static ssize_t transtable_local_read(struct kobject *kobj,
struct device *dev = to_dev(kobj->parent);
struct net_device *net_dev = to_net_dev(dev);
- rcu_read_lock();
- if (list_empty(&if_list)) {
- rcu_read_unlock();
-
- if (off == 0)
- return sprintf(buff,
- "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
- net_dev->name);
-
- return 0;
- }
- rcu_read_unlock();
-
return hna_local_fill_buffer_text(net_dev, buff, count, off);
}
@@ -137,19 +180,6 @@ static ssize_t transtable_global_read(struct kobject *kobj,
struct device *dev = to_dev(kobj->parent);
struct net_device *net_dev = to_net_dev(dev);
- rcu_read_lock();
- if (list_empty(&if_list)) {
- rcu_read_unlock();
-
- if (off == 0)
- return sprintf(buff,
- "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
- net_dev->name);
-
- return 0;
- }
- rcu_read_unlock();
-
return hna_global_fill_buffer_text(net_dev, buff, count, off);
}
@@ -157,45 +187,32 @@ static ssize_t originators_read(struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buff, loff_t off, size_t count)
{
- /* FIXME: orig table should exist per batif */
struct device *dev = to_dev(kobj->parent);
struct net_device *net_dev = to_net_dev(dev);
- rcu_read_lock();
- if (list_empty(&if_list)) {
- rcu_read_unlock();
-
- if (off == 0)
- return sprintf(buff,
- "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
- net_dev->name);
-
- return 0;
- }
-
- if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
- rcu_read_unlock();
-
- if (off == 0)
- return sprintf(buff,
- "BATMAN mesh %s disabled - primary interface not active\n",
- net_dev->name);
+ return orig_fill_buffer_text(net_dev, buff, count, off);
+}
- return 0;
- }
- rcu_read_unlock();
+static ssize_t vis_data_read(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buff, loff_t off, size_t count)
+{
+ struct device *dev = to_dev(kobj->parent);
+ struct net_device *net_dev = to_net_dev(dev);
- return orig_fill_buffer_text(buff, count, off);
+ return vis_fill_buffer_text(net_dev, buff, count, off);
}
static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL);
static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL);
static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL);
+static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL);
static struct bin_attribute *mesh_bin_attrs[] = {
&bat_attr_transtable_local,
&bat_attr_transtable_global,
&bat_attr_originators,
+ &bat_attr_vis_data,
NULL,
};
@@ -210,6 +227,7 @@ int sysfs_add_meshif(struct net_device *dev)
/* FIXME: should be done in the general mesh setup
routine as soon as we have it */
atomic_set(&bat_priv->aggregation_enabled, 1);
+ atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
batif_kobject);
@@ -44,7 +44,6 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t originator_interval;
atomic_t vis_interval;
-atomic_t vis_mode;
int16_t num_hna;
int16_t num_ifs;
@@ -84,7 +83,6 @@ int init_module(void)
atomic_set(&originator_interval, 1000);
atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
* for debugging now. */
- atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
/* the name should not be longer than 10 chars - see
* http://lwn.net/Articles/23634/ */
@@ -129,7 +129,6 @@ extern spinlock_t forw_bcast_list_lock;
extern atomic_t originator_interval;
extern atomic_t vis_interval;
-extern atomic_t vis_mode;
extern int16_t num_hna;
extern int16_t num_ifs;
@@ -26,6 +26,7 @@
#include "hash.h"
#include "translation-table.h"
#include "routing.h"
+#include "hard-interface.h"
static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
@@ -205,7 +206,6 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
return neigh_purged;
}
-
static bool purge_orig_node(struct orig_node *orig_node)
{
struct neigh_node *best_neigh_node;
@@ -224,6 +224,7 @@ static bool purge_orig_node(struct orig_node *orig_node)
orig_node->hna_buff,
orig_node->hna_buff_len);
}
+
return false;
}
@@ -249,7 +250,8 @@ void purge_orig(struct work_struct *work)
start_purge_timer();
}
-ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off)
+ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
+ size_t count, loff_t off)
{
HASHIT(hashit);
struct orig_node *orig_node;
@@ -260,12 +262,35 @@ ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off)
char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
rcu_read_lock();
+ if (list_empty(&if_list)) {
+ rcu_read_unlock();
+
+ if (off == 0)
+ return sprintf(buff,
+ "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
+ net_dev->name);
+
+ return 0;
+ }
+
+ if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
+ rcu_read_unlock();
+
+ if (off == 0)
+ return sprintf(buff,
+ "BATMAN mesh %s disabled - primary interface not active\n",
+ net_dev->name);
+
+ return 0;
+ }
+
hdr_len = sprintf(buff,
- " %-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 (%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);
+ ((struct batman_if *)if_list.next)->addr_str,
+ net_dev->name);
rcu_read_unlock();
if (off < hdr_len)
@@ -28,4 +28,5 @@ struct orig_node *get_orig_node(uint8_t *addr);
struct neigh_node *
create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
uint8_t *neigh, struct batman_if *if_incoming);
-ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off);
+ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
+ size_t count, loff_t off);
@@ -30,7 +30,6 @@
static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
static struct proc_dir_entry *proc_orig_interval_file;
-static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file;
static int proc_interfaces_read(struct seq_file *seq, void *offset)
{
@@ -173,145 +172,6 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file)
return single_open(file, proc_orig_interval_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)
-{
- char *vis_mode_string;
- int not_copied = 0;
-
- vis_mode_string = kmalloc(count, GFP_KERNEL);
-
- if (!vis_mode_string)
- return -ENOMEM;
-
- not_copied = copy_from_user(vis_mode_string, buffer, count);
- vis_mode_string[count - not_copied - 1] = 0;
-
- 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");
- 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");
- atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC);
- } else
- printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n",
- vis_mode_string);
-
- kfree(vis_mode_string);
- return count;
-}
-
-static int proc_vis_srv_read(struct seq_file *seq, void *offset)
-{
- int vis_server = atomic_read(&vis_mode);
-
- 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;
-}
-
-static int proc_vis_srv_open(struct inode *inode, struct file *file)
-{
- return single_open(file, proc_vis_srv_read, NULL);
-}
-
-static int proc_vis_data_read(struct seq_file *seq, void *offset)
-{
- HASHIT(hashit);
- 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) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) {
- rcu_read_unlock();
- goto end;
- }
-
- rcu_read_unlock();
-
- spin_lock_irqsave(&vis_hash_lock, flags);
- while (hash_iterate(vis_hash, &hashit)) {
- info = hashit.bucket->data;
- entries = (struct vis_info_entry *)
- ((char *)info + sizeof(struct vis_info));
-
- for (i = 0; i < info->packet.entries; i++) {
- 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));
- }
-
- 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);
-
-end:
- return 0;
-}
-
-static int proc_vis_data_open(struct inode *inode, struct file *file)
-{
- return single_open(file, proc_vis_data_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_vis_srv_fops = {
- .owner = THIS_MODULE,
- .open = proc_vis_srv_open,
- .read = seq_read,
- .write = proc_vis_srv_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations proc_vis_data_fops = {
- .owner = THIS_MODULE,
- .open = proc_vis_data_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,
@@ -338,12 +198,6 @@ void cleanup_procfs(void)
if (proc_interface_file)
remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
- if (proc_vis_data_file)
- remove_proc_entry(PROC_FILE_VIS_DATA, proc_batman_dir);
-
- if (proc_vis_srv_file)
- remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir);
-
if (proc_batman_dir)
#ifdef __NET_NET_NAMESPACE_H
remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net);
@@ -387,26 +241,5 @@ int setup_procfs(void)
return -EFAULT;
}
- proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV,
- S_IWUSR | S_IRUGO,
- proc_batman_dir);
- if (proc_vis_srv_file) {
- proc_vis_srv_file->proc_fops = &proc_vis_srv_fops;
- } else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_SRV);
- cleanup_procfs();
- return -EFAULT;
- }
-
- proc_vis_data_file = create_proc_entry(PROC_FILE_VIS_DATA, S_IRUGO,
- proc_batman_dir);
- if (proc_vis_data_file) {
- proc_vis_data_file->proc_fops = &proc_vis_data_fops;
- } else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_DATA);
- cleanup_procfs();
- return -EFAULT;
- }
-
return 0;
}
@@ -25,11 +25,6 @@
#define PROC_ROOT_DIR "batman-adv"
#define PROC_FILE_INTERFACES "interfaces"
#define PROC_FILE_ORIG_INTERVAL "orig_interval"
-#define PROC_FILE_GATEWAYS "gateways"
-#define PROC_FILE_LOG "log"
-#define PROC_FILE_LOG_LEVEL "log_level"
-#define PROC_FILE_VIS_SRV "vis_server"
-#define PROC_FILE_VIS_DATA "vis_data"
void cleanup_procfs(void);
int setup_procfs(void);
@@ -946,6 +946,7 @@ int recv_vis_packet(struct sk_buff *skb)
{
struct vis_packet *vis_packet;
struct ethhdr *ethhdr;
+ struct bat_priv *bat_priv;
int hdr_size = sizeof(struct vis_packet);
if (skb_headlen(skb) < hdr_size)
@@ -965,15 +966,20 @@ int recv_vis_packet(struct sk_buff *skb)
if (is_my_mac(vis_packet->sender_orig))
return NET_RX_DROP;
+ /* FIXME: each batman_if will be attached to a softif */
+ bat_priv = netdev_priv(soft_device);
+
switch (vis_packet->vis_type) {
case VIS_TYPE_SERVER_SYNC:
/* TODO: handle fragmented skbs properly */
- receive_server_sync_packet(vis_packet, skb_headlen(skb));
+ receive_server_sync_packet(bat_priv, vis_packet,
+ skb_headlen(skb));
break;
case VIS_TYPE_CLIENT_UPDATE:
/* TODO: handle fragmented skbs properly */
- receive_client_update_packet(vis_packet, skb_headlen(skb));
+ receive_client_update_packet(bat_priv, vis_packet,
+ skb_headlen(skb));
break;
default: /* ignore unknown packet */
@@ -243,7 +243,7 @@ void schedule_own_packet(struct batman_if *batman_if)
struct bat_priv *bat_priv = netdev_priv(soft_device);
unsigned long send_time;
struct batman_packet *batman_packet;
- int vis_server = atomic_read(&vis_mode);
+ int vis_server = atomic_read(&bat_priv->vis_mode);
/**
* the interface gets activated here to avoid race conditions between
@@ -271,17 +271,17 @@ void schedule_own_packet(struct batman_if *batman_if)
if (vis_server == VIS_TYPE_SERVER_SYNC)
batman_packet->flags = VIS_SERVER;
else
- batman_packet->flags = 0;
+ batman_packet->flags &= ~VIS_SERVER;
/* could be read by receive_bat_packet() */
atomic_inc(&batman_if->seqno);
slide_own_bcast_window(batman_if);
send_time = own_send_time();
- add_bat_packet_to_list(batman_if->packet_buff,
+ add_bat_packet_to_list(bat_priv,
+ batman_if->packet_buff,
batman_if->packet_len,
- batman_if, 1, send_time,
- bat_priv);
+ batman_if, 1, send_time);
}
void schedule_forward_packet(struct orig_node *orig_node,
@@ -336,10 +336,10 @@ void schedule_forward_packet(struct orig_node *orig_node,
batman_packet->flags &= ~DIRECTLINK;
send_time = forward_send_time(bat_priv);
- add_bat_packet_to_list((unsigned char *)batman_packet,
+ add_bat_packet_to_list(bat_priv,
+ (unsigned char *)batman_packet,
sizeof(struct batman_packet) + hna_buff_len,
- if_incoming, 0, send_time,
- bat_priv);
+ if_incoming, 0, send_time);
}
static void forw_packet_free(struct forw_packet *forw_packet)
@@ -182,6 +182,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct bat_priv *priv = netdev_priv(dev);
struct batman_if *batman_if;
+ struct bat_priv *bat_priv;
uint8_t dstaddr[6];
int data_len = skb->len;
unsigned long flags;
@@ -189,6 +190,9 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
if (atomic_read(&module_state) != MODULE_ACTIVE)
goto dropped;
+ /* FIXME: each batman_if will be attached to a softif */
+ bat_priv = netdev_priv(soft_device);
+
dev->trans_start = jiffies;
/* TODO: check this for locks */
hna_local_add(ethhdr->h_source);
@@ -165,6 +165,19 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
unsigned long flags;
size_t hdr_len;
+ rcu_read_lock();
+ if (list_empty(&if_list)) {
+ rcu_read_unlock();
+
+ if (off == 0)
+ return sprintf(buff,
+ "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
+ net_dev->name);
+
+ return 0;
+ }
+ rcu_read_unlock();
+
hdr_len = sprintf(buff,
"Locally retrieved addresses (from %s) announced via HNA:\n",
net_dev->name);
@@ -369,6 +382,19 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
unsigned long flags;
size_t hdr_len;
+ rcu_read_lock();
+ if (list_empty(&if_list)) {
+ rcu_read_unlock();
+
+ if (off == 0)
+ return sprintf(buff,
+ "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
+ net_dev->name);
+
+ return 0;
+ }
+ rcu_read_unlock();
+
hdr_len = sprintf(buff,
"Globally announced HNAs received via the mesh %s (translation table):\n",
net_dev->name);
@@ -83,6 +83,7 @@ struct neigh_node {
struct bat_priv {
struct net_device_stats stats;
atomic_t aggregation_enabled;
+ atomic_t vis_mode;
struct kobject *mesh_obj;
};
@@ -102,7 +102,7 @@ static int vis_info_choose(void *data, int size)
/* insert interface to the list of interfaces of one originator, if it
* does not already exist in the list */
-void proc_vis_insert_interface(const uint8_t *interface,
+static void vis_data_insert_interface(const uint8_t *interface,
struct hlist_head *if_list,
bool primary)
{
@@ -123,36 +123,119 @@ void proc_vis_insert_interface(const uint8_t *interface,
hlist_add_head(&entry->list, if_list);
}
-void proc_vis_read_prim_sec(struct seq_file *seq,
- struct hlist_head *if_list)
+static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list)
{
struct if_list_entry *entry;
struct hlist_node *pos;
char tmp_addr_str[ETH_STR_LEN];
+ size_t len = 0;
hlist_for_each_entry(entry, pos, if_list, list) {
if (entry->primary)
- seq_printf(seq, "PRIMARY, ");
+ len += sprintf(buff + len, "PRIMARY, ");
else {
addr_to_string(tmp_addr_str, entry->addr);
- seq_printf(seq, "SEC %s, ", tmp_addr_str);
+ len += sprintf(buff + len, "SEC %s, ", tmp_addr_str);
}
}
+
+ return len;
}
/* read an entry */
-void proc_vis_read_entry(struct seq_file *seq,
- struct vis_info_entry *entry,
- uint8_t *src,
- bool primary)
+static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
+ uint8_t *src, bool primary)
{
char to[40];
addr_to_string(to, entry->dest);
if (primary && entry->quality == 0)
- seq_printf(seq, "HNA %s, ", to);
+ return sprintf(buff, "HNA %s, ", to);
else if (compare_orig(entry->src, src))
- seq_printf(seq, "TQ %s %d, ", to, entry->quality);
+ return sprintf(buff, "TQ %s %d, ", to, entry->quality);
+
+ return 0;
+}
+
+ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
+ size_t count, loff_t off)
+{
+ HASHIT(hashit);
+ struct vis_info *info;
+ struct vis_info_entry *entries;
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ HLIST_HEAD(vis_if_list);
+ struct if_list_entry *entry;
+ struct hlist_node *pos, *n;
+ size_t hdr_len, tmp_len;
+ int i, bytes_written = 0;
+ char tmp_addr_str[ETH_STR_LEN];
+ unsigned long flags;
+ int vis_server = atomic_read(&bat_priv->vis_mode);
+
+ rcu_read_lock();
+ if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) {
+ rcu_read_unlock();
+ return 0;
+ }
+
+ rcu_read_unlock();
+ hdr_len = 0;
+
+ spin_lock_irqsave(&vis_hash_lock, flags);
+ while (hash_iterate(vis_hash, &hashit)) {
+ info = hashit.bucket->data;
+ entries = (struct vis_info_entry *)
+ ((char *)info + sizeof(struct vis_info));
+
+ /* estimated line length */
+ if (count < bytes_written + 200)
+ break;
+
+ for (i = 0; i < info->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));
+ }
+
+ hlist_for_each_entry(entry, pos, &vis_if_list, list) {
+ addr_to_string(tmp_addr_str, entry->addr);
+ tmp_len = sprintf(buff + bytes_written,
+ "%s,", tmp_addr_str);
+
+ for (i = 0; i < info->packet.entries; i++)
+ tmp_len += vis_data_read_entry(
+ buff + bytes_written + tmp_len,
+ &entries[i], entry->addr,
+ entry->primary);
+
+ /* add primary/secondary records */
+ if (compare_orig(entry->addr, info->packet.vis_orig))
+ tmp_len += vis_data_read_prim_sec(
+ buff + bytes_written + tmp_len,
+ &vis_if_list);
+
+ tmp_len += sprintf(buff + bytes_written + tmp_len,
+ "\n");
+
+ hdr_len += tmp_len;
+
+ if (off >= hdr_len)
+ continue;
+
+ bytes_written += tmp_len;
+ }
+
+ 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 bytes_written;
}
/* add the info packet to the send list, if it was not
@@ -280,12 +363,14 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
}
/* handle the server sync packet, forward if needed. */
-void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
+void receive_server_sync_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
+ int vis_info_len)
{
struct vis_info *info;
int is_new, make_broadcast;
unsigned long flags;
- int vis_server = atomic_read(&vis_mode);
+ int vis_server = atomic_read(&bat_priv->vis_mode);
make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC);
@@ -303,13 +388,14 @@ end:
}
/* handle an incoming client update packet and schedule forward if needed. */
-void receive_client_update_packet(struct vis_packet *vis_packet,
+void receive_client_update_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
int vis_info_len)
{
struct vis_info *info;
int is_new;
unsigned long flags;
- int vis_server = atomic_read(&vis_mode);
+ int vis_server = atomic_read(&bat_priv->vis_mode);
int are_target = 0;
/* clients shall not broadcast. */
@@ -376,7 +462,7 @@ static bool vis_packet_full(struct vis_info *info)
/* generates a packet of own vis data,
* returns 0 on success, -1 if no packet could be generated */
-static int generate_vis_packet(void)
+static int generate_vis_packet(struct bat_priv *bat_priv)
{
HASHIT(hashit_local);
HASHIT(hashit_global);
@@ -388,7 +474,7 @@ static int generate_vis_packet(void)
unsigned long flags;
info->first_seen = jiffies;
- info->packet.vis_type = atomic_read(&vis_mode);
+ info->packet.vis_type = atomic_read(&bat_priv->vis_mode);
spin_lock_irqsave(&orig_hash_lock, flags);
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
@@ -568,12 +654,14 @@ static void send_vis_packets(struct work_struct *work)
{
struct vis_info *info, *temp;
unsigned long flags;
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
spin_lock_irqsave(&vis_hash_lock, flags);
purge_vis_packets();
- if (generate_vis_packet() == 0) {
+ if (generate_vis_packet(bat_priv) == 0) {
/* schedule if generation was successful */
send_list_add(my_vis_info);
}
@@ -47,18 +47,13 @@ struct recvlist_node {
extern struct hashtable_t *vis_hash;
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,
- struct vis_info_entry *entry,
- uint8_t *src,
- bool primary);
-void proc_vis_read_prim_sec(struct seq_file *seq,
- struct hlist_head *if_list);
-void receive_server_sync_packet(struct vis_packet *vis_packet,
+ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
+ size_t count, loff_t off);
+void receive_server_sync_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
int vis_info_len);
-void receive_client_update_packet(struct vis_packet *vis_packet,
+void receive_client_update_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
int vis_info_len);
int vis_init(void);
void vis_quit(void);