[v5,1/4] batman-adv: make the GW selection class algorithm specific

Message ID 20160612041426.26339-2-a@unstable.cc (mailing list archive)
State Superseded, archived
Delegated to: Marek Lindner
Headers

Commit Message

Antonio Quartulli June 12, 2016, 4:14 a.m. UTC
  The B.A.T.M.A.N. V algorithm uses a different metric compared to its
predecessor and for this reason the logic used to compute the best
Gateway is also changed. This means that the GW selection class
fed to this logic has a semantics that depends on the algorithm being
used.

Make the parsing and printing routine of the GW selection class
routing algorithm specific. Each algorithm can now parse (and print)
this value independently.

If no API is provided by any algorithm, the default is to use the
current mechanism of considering such value like an integer between
1 and 255.

Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
 net/batman-adv/bat_v.c | 34 ++++++++++++++++++++++++++++++++++
 net/batman-adv/sysfs.c | 34 ++++++++++++++++++++++++++++++++--
 net/batman-adv/types.h | 13 +++++++++++++
 3 files changed, 79 insertions(+), 2 deletions(-)
  

Comments

Sven Eckelmann June 13, 2016, 10:45 a.m. UTC | #1
On Sunday 12 June 2016 12:14:23 Antonio Quartulli wrote:
[...]
> +	if (bat_priv->algo_ops->gw.show_sel_class)
> +		return bat_priv->algo_ops->gw.show_sel_class(bat_priv, buff);
[...]
> +	if (bat_priv->algo_ops->gw.store_sel_class)
> +		return bat_priv->algo_ops->gw.store_sel_class(bat_priv, buff,
> +							      count);
[...]
>  /**
> + * struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific)
> + * @store_sel_class: parse and stores a new GW selection class
> + * @show_sel_class: prints the current GW selection class
> + */
> +struct batadv_algo_gw_ops {
> +	ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff,
> +				   size_t count);
> +	ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff);
> +};

Looks like these two are also optional. Can someone please add the "(optional)"
string to the kernel-doc like it was done in the initial batadv_algo_ops
patches? Thanks

Same for get_best_gw_node, is_eligible and print in patch 2

Kind regards,
	Sven
  
Antonio Quartulli June 13, 2016, 4:02 p.m. UTC | #2
On Mon, Jun 13, 2016 at 12:45:17PM +0200, Sven Eckelmann wrote:
> On Sunday 12 June 2016 12:14:23 Antonio Quartulli wrote:
> [...]
> > +	if (bat_priv->algo_ops->gw.show_sel_class)
> > +		return bat_priv->algo_ops->gw.show_sel_class(bat_priv, buff);
> [...]
> > +	if (bat_priv->algo_ops->gw.store_sel_class)
> > +		return bat_priv->algo_ops->gw.store_sel_class(bat_priv, buff,
> > +							      count);
> [...]
> >  /**
> > + * struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific)
> > + * @store_sel_class: parse and stores a new GW selection class
> > + * @show_sel_class: prints the current GW selection class
> > + */
> > +struct batadv_algo_gw_ops {
> > +	ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff,
> > +				   size_t count);
> > +	ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff);
> > +};
> 
> Looks like these two are also optional. Can someone please add the "(optional)"
> string to the kernel-doc like it was done in the initial batadv_algo_ops
> patches? Thanks
> 
> Same for get_best_gw_node, is_eligible and print in patch 2

Sure!

Thanks!
  

Patch

diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index 0366cbf..90fd5ee 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -21,8 +21,10 @@ 
 #include <linux/atomic.h>
 #include <linux/bug.h>
 #include <linux/cache.h>
+#include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/jiffies.h>
+#include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
@@ -34,6 +36,8 @@ 
 #include "bat_algo.h"
 #include "bat_v_elp.h"
 #include "bat_v_ogm.h"
+#include "gateway_client.h"
+#include "gateway_common.h"
 #include "hard-interface.h"
 #include "hash.h"
 #include "originator.h"
@@ -320,6 +324,32 @@  err_ifinfo1:
 	return ret;
 }
 
+static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv,
+					char *buff, size_t count)
+{
+	u32 old_class, class;
+
+	if (!batadv_parse_throughput(bat_priv->soft_iface, buff,
+				     "B.A.T.M.A.N. V GW selection class",
+				     &class))
+		return -EINVAL;
+
+	old_class = atomic_read(&bat_priv->gw.sel_class);
+	atomic_set(&bat_priv->gw.sel_class, class);
+
+	if (old_class != class)
+		batadv_gw_reselect(bat_priv);
+
+	return count;
+}
+
+static ssize_t batadv_v_show_sel_class(struct batadv_priv *bat_priv, char *buff)
+{
+	u32 class = atomic_read(&bat_priv->gw.sel_class);
+
+	return sprintf(buff, "%u.%u MBit\n", class / 10, class % 10);
+}
+
 static struct batadv_algo_ops batadv_batman_v __read_mostly = {
 	.name = "BATMAN_V",
 	.iface = {
@@ -338,6 +368,10 @@  static struct batadv_algo_ops batadv_batman_v __read_mostly = {
 	.orig = {
 		.print = batadv_v_orig_print,
 	},
+	.gw = {
+		.store_sel_class = batadv_v_store_sel_class,
+		.show_sel_class = batadv_v_show_sel_class,
+	},
 };
 
 /**
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index fe9ca94..bb43742 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -514,6 +514,36 @@  static ssize_t batadv_store_gw_mode(struct kobject *kobj,
 	return count;
 }
 
+static ssize_t batadv_show_gw_sel_class(struct kobject *kobj,
+					struct attribute *attr, char *buff)
+{
+	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
+
+	if (bat_priv->algo_ops->gw.show_sel_class)
+		return bat_priv->algo_ops->gw.show_sel_class(bat_priv, buff);
+
+	return sprintf(buff, "%i\n", atomic_read(&bat_priv->gw.sel_class));
+}
+
+static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
+					 struct attribute *attr, char *buff,
+					 size_t count)
+{
+	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
+
+	if (buff[count - 1] == '\n')
+		buff[count - 1] = '\0';
+
+	if (bat_priv->algo_ops->gw.store_sel_class)
+		return bat_priv->algo_ops->gw.store_sel_class(bat_priv, buff,
+							      count);
+
+	return __batadv_store_uint_attr(buff, count, 1, BATADV_TQ_MAX_VALUE,
+					batadv_post_gw_reselect, attr,
+					&bat_priv->gw.sel_class,
+					bat_priv->soft_iface);
+}
+
 static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
 				     struct attribute *attr, char *buff)
 {
@@ -625,8 +655,8 @@  BATADV_ATTR_SIF_UINT(orig_interval, orig_interval, S_IRUGO | S_IWUSR,
 		     2 * BATADV_JITTER, INT_MAX, NULL);
 BATADV_ATTR_SIF_UINT(hop_penalty, hop_penalty, S_IRUGO | S_IWUSR, 0,
 		     BATADV_TQ_MAX_VALUE, NULL);
-BATADV_ATTR_SIF_UINT(gw_sel_class, gw.sel_class, S_IRUGO | S_IWUSR, 1,
-		     BATADV_TQ_MAX_VALUE, batadv_post_gw_reselect);
+static BATADV_ATTR(gw_sel_class, S_IRUGO | S_IWUSR, batadv_show_gw_sel_class,
+		   batadv_store_gw_sel_class);
 static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
 		   batadv_store_gw_bwidth);
 #ifdef CONFIG_BATMAN_ADV_MCAST
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 43db7b6..f24d93d 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1448,12 +1448,24 @@  struct batadv_algo_orig_ops {
 };
 
 /**
+ * struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific)
+ * @store_sel_class: parse and stores a new GW selection class
+ * @show_sel_class: prints the current GW selection class
+ */
+struct batadv_algo_gw_ops {
+	ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff,
+				   size_t count);
+	ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff);
+};
+
+/**
  * struct batadv_algo_ops - mesh algorithm callbacks
  * @list: list node for the batadv_algo_list
  * @name: name of the algorithm
  * @iface: callbacks related to interface handling
  * @neigh: callbacks related to neighbors handling
  * @orig: callbacks related to originators handling
+ * @gw: callbacks related to GW mode
  */
 struct batadv_algo_ops {
 	struct hlist_node list;
@@ -1461,6 +1473,7 @@  struct batadv_algo_ops {
 	struct batadv_algo_iface_ops iface;
 	struct batadv_algo_neigh_ops neigh;
 	struct batadv_algo_orig_ops orig;
+	struct batadv_algo_gw_ops gw;
 };
 
 /**