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: Linus Luessing <linus.luessing@web.de> Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
bc0ad071a7
commit
837b8248f6
@ -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)
|
|||||||
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;
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
/* 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,
|
|||||||
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,
|
|||||||
|
|
||||||
|
|
||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user