Commit 837b8248 authored by Linus Luessing's avatar Linus Luessing Committed by Greg Kroah-Hartman

Staging: batman-adv: atomic variable for vis-srv activation

This fixes the bug discovered by Marek Lindner which did not allow
turning on the vis-server before an interface has been added. With this
patch we are using a global atomic variable for activating and
deactiating the vis-server-mode, which can be used before
inserting an interface.
Signed-off-by: default avatarLinus Luessing <linus.luessing@web.de>
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent bc0ad071
...@@ -43,6 +43,7 @@ DEFINE_SPINLOCK(forw_bcast_list_lock); ...@@ -43,6 +43,7 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t originator_interval; atomic_t originator_interval;
atomic_t vis_interval; atomic_t vis_interval;
atomic_t vis_mode;
atomic_t aggregation_enabled; atomic_t aggregation_enabled;
int16_t num_hna; int16_t num_hna;
int16_t num_ifs; int16_t num_ifs;
...@@ -83,6 +84,7 @@ int init_module(void) ...@@ -83,6 +84,7 @@ int init_module(void)
atomic_set(&originator_interval, 1000); atomic_set(&originator_interval, 1000);
atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
* for debugging now. */ * for debugging now. */
atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
atomic_set(&aggregation_enabled, 1); atomic_set(&aggregation_enabled, 1);
/* the name should not be longer than 10 chars - see /* the name should not be longer than 10 chars - see
......
...@@ -130,6 +130,7 @@ extern spinlock_t forw_bcast_list_lock; ...@@ -130,6 +130,7 @@ extern spinlock_t forw_bcast_list_lock;
extern atomic_t originator_interval; extern atomic_t originator_interval;
extern atomic_t vis_interval; extern atomic_t vis_interval;
extern atomic_t vis_mode;
extern atomic_t aggregation_enabled; extern atomic_t aggregation_enabled;
extern int16_t num_hna; extern int16_t num_hna;
extern int16_t num_ifs; extern int16_t num_ifs;
......
...@@ -338,11 +338,11 @@ static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer, ...@@ -338,11 +338,11 @@ static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer,
if ((strcmp(vis_mode_string, "client") == 0) || if ((strcmp(vis_mode_string, "client") == 0) ||
(strcmp(vis_mode_string, "disabled") == 0)) { (strcmp(vis_mode_string, "disabled") == 0)) {
printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n"); 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) || } else if ((strcmp(vis_mode_string, "server") == 0) ||
(strcmp(vis_mode_string, "enabled") == 0)) { (strcmp(vis_mode_string, "enabled") == 0)) {
printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n"); 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 } else
printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n", printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n",
vis_mode_string); vis_mode_string);
...@@ -353,12 +353,12 @@ static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer, ...@@ -353,12 +353,12 @@ static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer,
static int proc_vis_srv_read(struct seq_file *seq, void *offset) 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", seq_printf(seq, "[%c] client mode (server disabled) \n",
(!vis_server) ? '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) ? 'x' : ' '); (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' ');
return 0; return 0;
} }
...@@ -377,9 +377,10 @@ static int proc_vis_data_read(struct seq_file *seq, void *offset) ...@@ -377,9 +377,10 @@ static int proc_vis_data_read(struct seq_file *seq, void *offset)
int i; int i;
char tmp_addr_str[ETH_STR_LEN]; char tmp_addr_str[ETH_STR_LEN];
unsigned long flags; unsigned long flags;
int vis_server = atomic_read(&vis_mode);
rcu_read_lock(); 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(); rcu_read_unlock();
goto end; goto end;
} }
...@@ -672,5 +673,3 @@ int setup_procfs(void) ...@@ -672,5 +673,3 @@ int setup_procfs(void)
return 0; return 0;
} }
...@@ -248,6 +248,7 @@ void schedule_own_packet(struct batman_if *batman_if) ...@@ -248,6 +248,7 @@ void schedule_own_packet(struct batman_if *batman_if)
{ {
unsigned long send_time; unsigned long send_time;
struct batman_packet *batman_packet; struct batman_packet *batman_packet;
int vis_server = atomic_read(&vis_mode);
/** /**
* the interface gets activated here to avoid race conditions between * the interface gets activated here to avoid race conditions between
...@@ -272,7 +273,7 @@ void schedule_own_packet(struct batman_if *batman_if) ...@@ -272,7 +273,7 @@ void schedule_own_packet(struct batman_if *batman_if)
/* change sequence number to network order */ /* change sequence number to network order */
batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno)); batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
if (is_vis_server()) if (vis_server == VIS_TYPE_SERVER_SYNC)
batman_packet->flags = VIS_SERVER; batman_packet->flags = VIS_SERVER;
else else
batman_packet->flags = 0; batman_packet->flags = 0;
......
...@@ -48,41 +48,6 @@ static void free_info(void *data) ...@@ -48,41 +48,6 @@ static void free_info(void *data)
kfree(info); kfree(info);
} }
/* set the mode of the visualization to client or server */
void vis_set_mode(int mode)
{
unsigned long flags;
spin_lock_irqsave(&vis_hash_lock, flags);
if (my_vis_info != NULL)
my_vis_info->packet.vis_type = mode;
spin_unlock_irqrestore(&vis_hash_lock, flags);
}
/* is_vis_server(), locked outside */
static int is_vis_server_locked(void)
{
if (my_vis_info != NULL)
if (my_vis_info->packet.vis_type == VIS_TYPE_SERVER_SYNC)
return 1;
return 0;
}
/* get the current set mode */
int is_vis_server(void)
{
int ret = 0;
unsigned long flags;
spin_lock_irqsave(&vis_hash_lock, flags);
ret = is_vis_server_locked();
spin_unlock_irqrestore(&vis_hash_lock, flags);
return ret;
}
/* Compare two vis packets, used by the hashing algorithm */ /* Compare two vis packets, used by the hashing algorithm */
static int vis_info_cmp(void *data1, void *data2) static int vis_info_cmp(void *data1, void *data2)
{ {
...@@ -271,6 +236,7 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len) ...@@ -271,6 +236,7 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
struct vis_info *info; struct vis_info *info;
int is_new; int is_new;
unsigned long flags; unsigned long flags;
int vis_server = atomic_read(&vis_mode);
spin_lock_irqsave(&vis_hash_lock, flags); spin_lock_irqsave(&vis_hash_lock, flags);
info = add_packet(vis_packet, vis_info_len, &is_new); info = add_packet(vis_packet, vis_info_len, &is_new);
...@@ -279,7 +245,7 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len) ...@@ -279,7 +245,7 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
/* only if we are server ourselves and packet is newer than the one in /* only if we are server ourselves and packet is newer than the one in
* hash.*/ * hash.*/
if (is_vis_server_locked() && is_new) { if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) {
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
if (list_empty(&info->send_list)) if (list_empty(&info->send_list))
list_add_tail(&info->send_list, &send_list); list_add_tail(&info->send_list, &send_list);
...@@ -295,6 +261,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet, ...@@ -295,6 +261,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
struct vis_info *info; struct vis_info *info;
int is_new; int is_new;
unsigned long flags; unsigned long flags;
int vis_server = atomic_read(&vis_mode);
/* clients shall not broadcast. */ /* clients shall not broadcast. */
if (is_bcast(vis_packet->target_orig)) if (is_bcast(vis_packet->target_orig))
...@@ -308,7 +275,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet, ...@@ -308,7 +275,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
/* send only if we're the target server or ... */ /* send only if we're the target server or ... */
if (is_vis_server_locked() && if (vis_server == VIS_TYPE_SERVER_SYNC &&
is_my_mac(info->packet.target_orig) && is_my_mac(info->packet.target_orig) &&
is_new) { is_new) {
info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
...@@ -372,6 +339,7 @@ static int generate_vis_packet(void) ...@@ -372,6 +339,7 @@ static int generate_vis_packet(void)
unsigned long flags; unsigned long flags;
info->first_seen = jiffies; info->first_seen = jiffies;
info->packet.vis_type = atomic_read(&vis_mode);
spin_lock_irqsave(&orig_hash_lock, flags); spin_lock_irqsave(&orig_hash_lock, flags);
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
...@@ -379,7 +347,7 @@ static int generate_vis_packet(void) ...@@ -379,7 +347,7 @@ static int generate_vis_packet(void)
info->packet.seqno++; info->packet.seqno++;
info->packet.entries = 0; info->packet.entries = 0;
if (!is_vis_server_locked()) { if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
best_tq = find_best_vis_server(info); best_tq = find_best_vis_server(info);
if (best_tq < 0) { if (best_tq < 0) {
spin_unlock_irqrestore(&orig_hash_lock, flags); spin_unlock_irqrestore(&orig_hash_lock, flags);
...@@ -577,7 +545,6 @@ int vis_init(void) ...@@ -577,7 +545,6 @@ int vis_init(void)
INIT_LIST_HEAD(&my_vis_info->send_list); INIT_LIST_HEAD(&my_vis_info->send_list);
my_vis_info->packet.version = COMPAT_VERSION; my_vis_info->packet.version = COMPAT_VERSION;
my_vis_info->packet.packet_type = BAT_VIS; my_vis_info->packet.packet_type = BAT_VIS;
my_vis_info->packet.vis_type = VIS_TYPE_CLIENT_UPDATE;
my_vis_info->packet.ttl = TTL; my_vis_info->packet.ttl = TTL;
my_vis_info->packet.seqno = 0; my_vis_info->packet.seqno = 0;
my_vis_info->packet.entries = 0; my_vis_info->packet.entries = 0;
...@@ -628,4 +595,3 @@ static void start_vis_timer(void) ...@@ -628,4 +595,3 @@ static void start_vis_timer(void)
queue_delayed_work(bat_event_workqueue, &vis_timer_wq, queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
(atomic_read(&vis_interval) * HZ) / 1000); (atomic_read(&vis_interval) * HZ) / 1000);
} }
...@@ -48,8 +48,6 @@ struct recvlist_node { ...@@ -48,8 +48,6 @@ 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 vis_set_mode(int mode);
int is_vis_server(void);
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, struct hlist_head *if_list,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment