@@ -251,6 +251,12 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
return count;
}
+static void post_gw_deselect(struct net_device *net_dev)
+{
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ gw_deselect(bat_priv);
+}
+
static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr,
char *buff)
{
@@ -261,6 +267,7 @@ static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr,
switch (gw_mode) {
case GW_MODE_CLIENT:
+ gw_class = atomic_read(&bat_priv->gw_sel_class);
bytes_written = sprintf(buff, "%s (gw_class: %i)\n",
GW_MODE_CLIENT_NAME, gw_class);
break;
@@ -298,6 +305,8 @@ static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode);
BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL);
BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL);
+BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
+ post_gw_deselect);
#ifdef CONFIG_BATMAN_ADV_DEBUG
BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL);
#endif
@@ -310,6 +319,7 @@ static struct bat_attribute *mesh_attrs[] = {
&bat_attr_gw_mode,
&bat_attr_orig_interval,
&bat_attr_hop_penalty,
+ &bat_attr_gw_sel_class,
#ifdef CONFIG_BATMAN_ADV_DEBUG
&bat_attr_log_level,
#endif
@@ -116,7 +116,7 @@ void gw_election(struct bat_priv *bat_priv)
if (gw_node->deleted)
continue;
- switch (atomic_read(&bat_priv->gw_class)) {
+ switch (atomic_read(&bat_priv->gw_sel_class)) {
case 1: /* fast connection */
gw_srv_class_to_kbit(gw_node->orig_node->gw_flags,
&down, &up);
@@ -215,8 +215,8 @@ void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
* if the routing class is greater than 3 the value tells us how much
* greater the TQ value of the new gateway must be
**/
- if ((atomic_read(&bat_priv->gw_class) > 3) &&
- (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_class)))
+ if ((atomic_read(&bat_priv->gw_sel_class) > 3) &&
+ (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class)))
return;
bat_dbg(DBG_BATMAN, bat_priv,
@@ -236,12 +236,15 @@ next:
switch (gw_mode_tmp) {
case GW_MODE_CLIENT:
+ gw_class_tmp = atomic_read(&bat_priv->gw_sel_class);
if ((gw_mode_tmp == GW_MODE_CLIENT) && (!gw_class_tmp))
gw_class_tmp = 20;
bat_info(net_dev, "Changing gateway mode from: '%s' to: '%s' "
- "(gw_class: %ld)\n",
+ "(gw_sel_class: %ld)\n",
gw_mode_curr_str, gw_mode_tmp_str, gw_class_tmp);
+
+ atomic_set(&bat_priv->gw_sel_class, gw_class_tmp);
break;
case GW_MODE_SERVER:
if (!down)
@@ -32,6 +32,7 @@
#include "ring_buffer.h"
#include "vis.h"
#include "aggregation.h"
+#include "gateway_common.h"
#include "gateway_client.h"
#include "unicast.h"
@@ -330,7 +331,9 @@ update_gw:
orig_node->gw_flags = batman_packet->gw_flags;
/* restart gateway selection if fast or late switching was enabled */
- if ((orig_node->gw_flags) && (atomic_read(&bat_priv->gw_class) > 2))
+ if ((orig_node->gw_flags) &&
+ (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) &&
+ (atomic_read(&bat_priv->gw_sel_class) > 2))
gw_check_election(bat_priv, orig_node);
}
@@ -591,6 +591,7 @@ struct net_device *softif_create(char *name)
atomic_set(&bat_priv->bonding, 0);
atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
atomic_set(&bat_priv->gw_mode, GW_MODE_OFF);
+ atomic_set(&bat_priv->gw_sel_class, 0);
atomic_set(&bat_priv->gw_class, 0);
atomic_set(&bat_priv->orig_interval, 1000);
atomic_set(&bat_priv->hop_penalty, 10);
@@ -128,6 +128,7 @@ struct bat_priv {
atomic_t fragmentation; /* boolean */
atomic_t vis_mode; /* VIS_TYPE_* */
atomic_t gw_mode; /* GW_MODE_* */
+ atomic_t gw_sel_class; /* uint */
atomic_t gw_class; /* uint */
atomic_t orig_interval; /* uint */
atomic_t hop_penalty; /* uint */