The following commit has been merged in the master branch: commit baf8d41bdb6ed0bc037c966315a826ef47c411ed Author: Marek Lindner lindner_marek@yahoo.de Date: Sun Nov 7 12:56:59 2010 +0000
batman-adv: move gateway bandwidth into its own sysfs file
The Linux kernel guidelines require each sysfs file to have a single value / purpose, therefore it is necessary to split up the sysfs gateway files.
Signed-off-by: Marek Lindner lindner_marek@yahoo.de
diff --git a/bat_sysfs.c b/bat_sysfs.c index 0f39213..f937f6f 100644 --- a/bat_sysfs.c +++ b/bat_sysfs.c @@ -262,8 +262,7 @@ static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, { struct bat_priv *bat_priv = kobj_to_batpriv(kobj); int down, up, bytes_written; - int gw_mode = atomic_read(&bat_priv->gw_mode); - int gw_class = atomic_read(&bat_priv->gw_class); + int gw_class, gw_mode = atomic_read(&bat_priv->gw_mode);
switch (gw_mode) { case GW_MODE_CLIENT: @@ -272,7 +271,8 @@ static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, GW_MODE_CLIENT_NAME, gw_class); break; case GW_MODE_SERVER: - gw_srv_class_to_kbit(gw_class, &down, &up); + gw_class = atomic_read(&bat_priv->gw_bandwidth); + gw_bandwidth_to_kbit(gw_class, &down, &up); bytes_written = sprintf(buff, "%s (gw_class: %i " "-> propagating: %i%s/%i%s)\n", @@ -292,12 +292,38 @@ static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, }
static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) + char *buff, size_t count) { struct net_device *net_dev = kobj_to_netdev(kobj); return gw_mode_set(net_dev, buff, count); }
+static ssize_t show_gw_bwidth(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + int down, up; + int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth); + + gw_bandwidth_to_kbit(gw_bandwidth, &down, &up); + return sprintf(buff, "%i%s/%i%s\n", + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); +} + +static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + return gw_bandwidth_set(net_dev, buff, count); +} + BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); @@ -307,6 +333,8 @@ 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); +static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, + store_gw_bwidth); #ifdef CONFIG_BATMAN_ADV_DEBUG BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL); #endif @@ -320,6 +348,7 @@ static struct bat_attribute *mesh_attrs[] = { &bat_attr_orig_interval, &bat_attr_hop_penalty, &bat_attr_gw_sel_class, + &bat_attr_gw_bandwidth, #ifdef CONFIG_BATMAN_ADV_DEBUG &bat_attr_log_level, #endif diff --git a/gateway_client.c b/gateway_client.c index 56c52b0..fde1d8a 100644 --- a/gateway_client.c +++ b/gateway_client.c @@ -118,7 +118,7 @@ void gw_election(struct bat_priv *bat_priv)
switch (atomic_read(&bat_priv->gw_sel_class)) { case 1: /* fast connection */ - gw_srv_class_to_kbit(gw_node->orig_node->gw_flags, + gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
tmp_gw_factor = (gw_node->orig_node->router->tq_avg * @@ -247,7 +247,7 @@ static void gw_node_add(struct bat_priv *bat_priv, hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list); spin_unlock_bh(&bat_priv->gw_list_lock);
- gw_srv_class_to_kbit(new_gwflags, &down, &up); + gw_bandwidth_to_kbit(new_gwflags, &down, &up); bat_dbg(DBG_BATMAN, bat_priv, "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", orig_node->orig, new_gwflags, @@ -336,7 +336,7 @@ static int _write_buffer_text(struct bat_priv *bat_priv, { int down, up;
- gw_srv_class_to_kbit(gw_node->orig_node->gw_flags, &down, &up); + gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
return seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", (bat_priv->curr_gw == gw_node ? "=>" : " "), diff --git a/gateway_common.c b/gateway_common.c index 330167e..9d03e3c 100644 --- a/gateway_common.c +++ b/gateway_common.c @@ -24,7 +24,7 @@ #include "gateway_client.h"
/* calculates the gateway class from kbit */ -static void kbit_to_gw_srv_class(int down, int up, long *gw_srv_class) +static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) { int mdown = 0, tdown, tup, difference; uint8_t sbit, part; @@ -59,7 +59,7 @@ static void kbit_to_gw_srv_class(int down, int up, long *gw_srv_class) }
/* returns the up and downspeeds in kbit, calculated from the class */ -void gw_srv_class_to_kbit(uint8_t gw_srv_class, int *down, int *up) +void gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up) { char sbit = (gw_srv_class & 0x80) >> 7; char dpart = (gw_srv_class & 0x78) >> 3; @@ -113,8 +113,7 @@ static bool parse_gw_mode_tok(struct net_device *net_dev, if (strnicmp(tmp_ptr, "mbit", 4) == 0) multi = 1024;
- if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || - (multi > 1)) + if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || (multi > 1)) *tmp_ptr = '\0'; }
@@ -253,14 +252,14 @@ next: if (!up) up = down / 5;
- kbit_to_gw_srv_class(down, up, &gw_class_tmp); + kbit_to_gw_bandwidth(down, up, &gw_class_tmp);
/** * the gw class we guessed above might not match the given * speeds, hence we need to calculate it back to show the * number that is going to be propagated **/ - gw_srv_class_to_kbit((uint8_t)gw_class_tmp, + gw_bandwidth_to_kbit((uint8_t)gw_class_tmp, (int *)&down, (int *)&up);
gw_deselect(bat_priv); @@ -271,6 +270,8 @@ next: (down > 2048 ? "MBit" : "KBit"), (up > 2048 ? up / 1024 : up), (up > 2048 ? "MBit" : "KBit")); + + atomic_set(&bat_priv->gw_bandwidth, gw_class_tmp); break; default: bat_info(net_dev, "Changing gateway mode from: '%s' to: '%s'\n", @@ -279,7 +280,6 @@ next: }
atomic_set(&bat_priv->gw_mode, gw_mode_tmp); - atomic_set(&bat_priv->gw_class, gw_class_tmp);
if (gw_class_tmp == 0) gw_deselect(bat_priv); @@ -287,3 +287,104 @@ next: end: return count; } + +static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff, + long *up, long *down) +{ + int ret, multi = 1; + char *slash_ptr, *tmp_ptr; + + slash_ptr = strchr(buff, '/'); + if (slash_ptr) + *slash_ptr = 0; + + if (strlen(buff) > 4) { + tmp_ptr = buff + strlen(buff) - 4; + + if (strnicmp(tmp_ptr, "mbit", 4) == 0) + multi = 1024; + + if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || + (multi > 1)) + *tmp_ptr = '\0'; + } + + ret = strict_strtoul(buff, 10, down); + if (ret) { + bat_err(net_dev, + "Download speed of gateway mode invalid: %s\n", + buff); + return false; + } + + *down *= multi; + + /* we also got some upload info */ + if (slash_ptr) { + multi = 1; + + if (strlen(slash_ptr + 1) > 4) { + tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); + + if (strnicmp(tmp_ptr, "mbit", 4) == 0) + multi = 1024; + + if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || + (multi > 1)) + *tmp_ptr = '\0'; + } + + ret = strict_strtoul(slash_ptr + 1, 10, up); + if (ret) { + bat_err(net_dev, + "Upload speed of gateway mode invalid: " + "%s\n", slash_ptr + 1); + return false; + } + + *up *= multi; + } + + return true; +} + +ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) +{ + struct bat_priv *bat_priv = netdev_priv(net_dev); + long gw_bandwidth_tmp = 0, up = 0, down = 0; + bool ret; + + ret = parse_gw_bandwidth(net_dev, buff, &up, &down); + if (!ret) + goto end; + + if ((!down) || (down < 256)) + down = 2000; + + if (!up) + up = down / 5; + + kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); + + /** + * the gw bandwidth we guessed above might not match the given + * speeds, hence we need to calculate it back to show the number + * that is going to be propagated + **/ + gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, + (int *)&down, (int *)&up); + + gw_deselect(bat_priv); + bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' " + "(propagating: %ld%s/%ld%s)\n", + atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); + + atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp); + +end: + return count; +} diff --git a/gateway_common.h b/gateway_common.h index 8074c70..181a306 100644 --- a/gateway_common.h +++ b/gateway_common.h @@ -32,7 +32,8 @@ enum gw_modes { #define GW_MODE_CLIENT_NAME "client" #define GW_MODE_SERVER_NAME "server"
-void gw_srv_class_to_kbit(uint8_t gw_class, int *down, int *up); +void gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up); ssize_t gw_mode_set(struct net_device *net_dev, char *buff, size_t count); +ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count);
#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */ diff --git a/send.c b/send.c index 454049c..b89b9f7 100644 --- a/send.c +++ b/send.c @@ -287,7 +287,7 @@ void schedule_own_packet(struct batman_if *batman_if) if ((batman_if == bat_priv->primary_if) && (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) batman_packet->gw_flags = - (uint8_t)atomic_read(&bat_priv->gw_class); + (uint8_t)atomic_read(&bat_priv->gw_bandwidth); else batman_packet->gw_flags = 0;
diff --git a/soft-interface.c b/soft-interface.c index 7b2673c..9561433 100644 --- a/soft-interface.c +++ b/soft-interface.c @@ -592,7 +592,7 @@ struct net_device *softif_create(char *name) 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->gw_bandwidth, 0); atomic_set(&bat_priv->orig_interval, 1000); atomic_set(&bat_priv->hop_penalty, 10); atomic_set(&bat_priv->log_level, 0); diff --git a/types.h b/types.h index b68add4..1d00849 100644 --- a/types.h +++ b/types.h @@ -129,7 +129,7 @@ struct bat_priv { 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 gw_bandwidth; /* gw bandwidth */ atomic_t orig_interval; /* uint */ atomic_t hop_penalty; /* uint */ atomic_t log_level; /* uint */