This commit adds the needed configurable variables in bat_priv and
according user interfaces in sysfs for the future multicast
optimizations.

Signed-off-by: Linus Lüssing <[email protected]>
---
 Makefile.kbuild  |    1 +
 bat_sysfs.c      |  160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 multicast.c      |  121 +++++++++++++++++++++++++++++++++++++++++
 multicast.h      |   30 ++++++++++
 packet.h         |    4 ++
 soft-interface.c |    4 ++
 types.h          |    4 ++
 7 files changed, 324 insertions(+), 0 deletions(-)
 create mode 100644 multicast.c
 create mode 100644 multicast.h

diff --git a/batman-adv/Makefile.kbuild b/batman-adv/Makefile.kbuild
index 0a35006..1272d0d 100644
--- a/batman-adv/Makefile.kbuild
+++ b/batman-adv/Makefile.kbuild
@@ -49,5 +49,6 @@ batman-adv-y += send.o
 batman-adv-y += soft-interface.o
 batman-adv-y += translation-table.o
 batman-adv-y += unicast.o
+batman-adv-y += multicast.o
 batman-adv-y += vis.o
 batman-adv-y += bat_printk.o
diff --git a/batman-adv/bat_sysfs.c b/batman-adv/bat_sysfs.c
index f7b93a0..67adb35 100644
--- a/batman-adv/bat_sysfs.c
+++ b/batman-adv/bat_sysfs.c
@@ -27,6 +27,7 @@
 #include "gateway_common.h"
 #include "gateway_client.h"
 #include "vis.h"
+#include "multicast.h"
 
 #define to_dev(obj)            container_of(obj, struct device, kobj)
 #define kobj_to_netdev(obj)    to_net_dev(to_dev(obj->parent))
@@ -356,6 +357,153 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, 
struct attribute *attr,
        return gw_bandwidth_set(net_dev, buff, count);
 }
 
+static ssize_t show_mcast_mode(struct kobject *kobj, struct attribute *attr,
+                                char *buff)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+       int mcast_mode = atomic_read(&bat_priv->mcast_mode);
+       int ret;
+
+       switch (mcast_mode) {
+       case MCAST_MODE_CLASSIC_FLOODING:
+               ret = sprintf(buff, "classic_flooding\n");
+               break;
+       case MCAST_MODE_PROACT_TRACKING:
+               ret = sprintf(buff, "proactive_tracking\n");
+               break;
+       default:
+               ret = -1;
+               break;
+       }
+
+       return ret;
+}
+
+static ssize_t store_mcast_mode(struct kobject *kobj, struct attribute *attr,
+                             char *buff, size_t count)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct net_device *net_dev = to_net_dev(dev);
+       struct bat_priv *bat_priv = netdev_priv(net_dev);
+       unsigned long val;
+       int ret, mcast_mode_tmp = -1;
+
+       ret = strict_strtoul(buff, 10, &val);
+
+       if (((count == 2) && (!ret) && (val == MCAST_MODE_CLASSIC_FLOODING)) ||
+           (strncmp(buff, "classic_flooding", 16) == 0))
+               mcast_mode_tmp = MCAST_MODE_CLASSIC_FLOODING;
+
+       if (((count == 2) && (!ret) && (val == MCAST_MODE_PROACT_TRACKING)) ||
+           (strncmp(buff, "proact_tracking", 15) == 0))
+               mcast_mode_tmp = MCAST_MODE_PROACT_TRACKING;
+
+       if (mcast_mode_tmp < 0) {
+               if (buff[count - 1] == '\n')
+                       buff[count - 1] = '\0';
+
+               bat_info(net_dev,
+                        "Invalid parameter for 'mcast mode' setting received: "
+                        "%s\n", buff);
+               return -EINVAL;
+       }
+
+       if (atomic_read(&bat_priv->mcast_mode) == mcast_mode_tmp)
+               return count;
+
+       bat_info(net_dev, "Changing mcast mode from: %s to: %s\n",
+                atomic_read(&bat_priv->mcast_mode) ==
+                       MCAST_MODE_CLASSIC_FLOODING ?
+                "classic_flooding" : "proact_tracking",
+                mcast_mode_tmp == MCAST_MODE_CLASSIC_FLOODING ?
+                "classic_flooding" : "proact_tracking");
+
+       atomic_set(&bat_priv->mcast_mode, (unsigned)mcast_mode_tmp);
+       return count;
+}
+
+static ssize_t show_mcast_tracker_interval(struct kobject *kobj,
+                       struct attribute *attr, char *buff)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+       int tracker_interval = atomic_read(&bat_priv->mcast_tracker_interval);
+
+       if (!tracker_interval)
+               return sprintf(buff, "auto\n");
+       else
+               return sprintf(buff, "%i\n", tracker_interval);
+}
+
+static ssize_t store_mcast_tracker_interval(struct kobject *kobj,
+                       struct attribute *attr, char *buff, size_t count)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct net_device *net_dev = to_net_dev(dev);
+
+       return mcast_tracker_interval_set(net_dev, buff, count);
+}
+
+static ssize_t show_mcast_tracker_timeout(struct kobject *kobj,
+                       struct attribute *attr, char *buff)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+       int tracker_timeout = atomic_read(&bat_priv->mcast_tracker_timeout);
+
+       if (!tracker_timeout)
+               return sprintf(buff, "auto\n");
+       else
+               return sprintf(buff, "%i\n", tracker_timeout);
+}
+
+static ssize_t store_mcast_tracker_timeout(struct kobject *kobj,
+                       struct attribute *attr, char *buff, size_t count)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct net_device *net_dev = to_net_dev(dev);
+
+       return mcast_tracker_timeout_set(net_dev, buff, count);
+}
+
+static ssize_t show_mcast_fanout(struct kobject *kobj,
+                       struct attribute *attr, char *buff)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+
+       return sprintf(buff, "%i\n",
+                      atomic_read(&bat_priv->mcast_fanout));
+}
+
+static ssize_t store_mcast_fanout(struct kobject *kobj,
+                       struct attribute *attr, char *buff, size_t count)
+{
+       struct device *dev = to_dev(kobj->parent);
+       struct net_device *net_dev = to_net_dev(dev);
+       struct bat_priv *bat_priv = netdev_priv(net_dev);
+       unsigned long mcast_fanout_tmp;
+       int ret;
+
+       ret = strict_strtoul(buff, 10, &mcast_fanout_tmp);
+       if (ret) {
+               bat_info(net_dev, "Invalid parameter for 'mcast_fanout' "
+                        "setting received: %s\n", buff);
+               return -EINVAL;
+       }
+
+       if (atomic_read(&bat_priv->mcast_fanout) == mcast_fanout_tmp)
+               return count;
+
+       bat_info(net_dev, "Changing mcast fanout interval from: %i to: %li\n",
+                atomic_read(&bat_priv->mcast_fanout),
+                mcast_fanout_tmp);
+
+       atomic_set(&bat_priv->mcast_fanout, mcast_fanout_tmp);
+       return 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);
@@ -367,6 +515,14 @@ 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);
+static BAT_ATTR(mcast_mode, S_IRUGO | S_IWUSR,
+               show_mcast_mode, store_mcast_mode);
+static BAT_ATTR(mcast_tracker_interval, S_IRUGO | S_IWUSR,
+               show_mcast_tracker_interval, store_mcast_tracker_interval);
+static BAT_ATTR(mcast_tracker_timeout, S_IRUGO | S_IWUSR,
+               show_mcast_tracker_timeout, store_mcast_tracker_timeout);
+static BAT_ATTR(mcast_fanout, S_IRUGO | S_IWUSR,
+               show_mcast_fanout, store_mcast_fanout);
 #ifdef CONFIG_BATMAN_ADV_DEBUG
 BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL);
 #endif
@@ -381,6 +537,10 @@ static struct bat_attribute *mesh_attrs[] = {
        &bat_attr_hop_penalty,
        &bat_attr_gw_sel_class,
        &bat_attr_gw_bandwidth,
+       &bat_attr_mcast_mode,
+       &bat_attr_mcast_tracker_interval,
+       &bat_attr_mcast_tracker_timeout,
+       &bat_attr_mcast_fanout,
 #ifdef CONFIG_BATMAN_ADV_DEBUG
        &bat_attr_log_level,
 #endif
diff --git a/batman-adv/multicast.c b/batman-adv/multicast.c
new file mode 100644
index 0000000..0598873
--- /dev/null
+++ b/batman-adv/multicast.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "multicast.h"
+
+int mcast_tracker_interval_set(struct net_device *net_dev, char *buff,
+                              size_t count)
+{
+       struct bat_priv *bat_priv = netdev_priv(net_dev);
+       unsigned long new_tracker_interval;
+       int cur_tracker_interval;
+       int ret;
+
+       ret = strict_strtoul(buff, 10, &new_tracker_interval);
+
+       if (ret && !strncmp(buff, "auto", 4)) {
+               new_tracker_interval = 0;
+               goto ok;
+       }
+
+       else if (ret) {
+               bat_info(net_dev, "Invalid parameter for "
+                        "'mcast_tracker_interval' setting received: %s\n",
+                        buff);
+               return -EINVAL;
+       }
+
+       if (new_tracker_interval < JITTER) {
+               bat_info(net_dev, "New mcast tracker interval too small: %li "
+                        "(min: %i or auto)\n", new_tracker_interval, JITTER);
+               return -EINVAL;
+       }
+
+ok:
+       cur_tracker_interval = atomic_read(&bat_priv->mcast_tracker_interval);
+
+       if (cur_tracker_interval == new_tracker_interval)
+               return count;
+
+       if (!cur_tracker_interval && new_tracker_interval)
+               bat_info(net_dev, "Tracker interval change from: %s to: %li\n",
+                        "auto", new_tracker_interval);
+       else if (cur_tracker_interval && !new_tracker_interval)
+               bat_info(net_dev, "Tracker interval change from: %i to: %s\n",
+                        cur_tracker_interval, "auto");
+       else
+               bat_info(net_dev, "Tracker interval change from: %i to: %li\n",
+                        cur_tracker_interval, new_tracker_interval);
+
+       atomic_set(&bat_priv->mcast_tracker_interval, new_tracker_interval);
+
+       return count;
+}
+
+int mcast_tracker_timeout_set(struct net_device *net_dev, char *buff,
+                              size_t count)
+{
+       struct bat_priv *bat_priv = netdev_priv(net_dev);
+       unsigned long new_tracker_timeout;
+       int cur_tracker_timeout;
+       int ret;
+
+       ret = strict_strtoul(buff, 10, &new_tracker_timeout);
+
+       if (ret && !strncmp(buff, "auto", 4)) {
+               new_tracker_timeout = 0;
+               goto ok;
+       }
+
+       else if (ret) {
+               bat_info(net_dev, "Invalid parameter for "
+                        "'mcast_tracker_timeout' setting received: %s\n",
+                        buff);
+               return -EINVAL;
+       }
+
+       if (new_tracker_timeout < JITTER) {
+               bat_info(net_dev, "New mcast tracker timeout too small: %li "
+                        "(min: %i or auto)\n", new_tracker_timeout, JITTER);
+               return -EINVAL;
+       }
+
+ok:
+       cur_tracker_timeout = atomic_read(&bat_priv->mcast_tracker_timeout);
+
+       if (cur_tracker_timeout == new_tracker_timeout)
+               return count;
+
+       if (!cur_tracker_timeout && new_tracker_timeout)
+               bat_info(net_dev, "Tracker timeout change from: %s to: %li\n",
+                        "auto", new_tracker_timeout);
+       else if (cur_tracker_timeout && !new_tracker_timeout)
+               bat_info(net_dev, "Tracker timeout change from: %i to: %s\n",
+                        cur_tracker_timeout, "auto");
+       else
+               bat_info(net_dev, "Tracker timeout change from: %i to: %li\n",
+                        cur_tracker_timeout, new_tracker_timeout);
+
+       atomic_set(&bat_priv->mcast_tracker_timeout, new_tracker_timeout);
+
+       return count;
+}
diff --git a/batman-adv/multicast.h b/batman-adv/multicast.h
new file mode 100644
index 0000000..12a3376
--- /dev/null
+++ b/batman-adv/multicast.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_MULTICAST_H_
+#define _NET_BATMAN_ADV_MULTICAST_H_
+
+int mcast_tracker_interval_set(struct net_device *net_dev, char *buff,
+                              size_t count);
+int mcast_tracker_timeout_set(struct net_device *net_dev, char *buff,
+                              size_t count);
+
+#endif /* _NET_BATMAN_ADV_MULTICAST_H_ */
diff --git a/batman-adv/packet.h b/batman-adv/packet.h
index e757187..eef5371 100644
--- a/batman-adv/packet.h
+++ b/batman-adv/packet.h
@@ -48,6 +48,10 @@
 #define VIS_TYPE_SERVER_SYNC           0
 #define VIS_TYPE_CLIENT_UPDATE         1
 
+/* mcast defines */
+#define MCAST_MODE_CLASSIC_FLOODING    0
+#define MCAST_MODE_PROACT_TRACKING     1
+
 /* fragmentation defines */
 #define UNI_FRAG_HEAD 0x01
 #define UNI_FRAG_LARGETAIL 0x02
diff --git a/batman-adv/soft-interface.c b/batman-adv/soft-interface.c
index 145e0f7..f25fe9d 100644
--- a/batman-adv/soft-interface.c
+++ b/batman-adv/soft-interface.c
@@ -597,6 +597,10 @@ struct net_device *softif_create(char *name)
        atomic_set(&bat_priv->gw_bandwidth, 41);
        atomic_set(&bat_priv->orig_interval, 1000);
        atomic_set(&bat_priv->hop_penalty, 10);
+       atomic_set(&bat_priv->mcast_mode, MCAST_MODE_CLASSIC_FLOODING);
+       atomic_set(&bat_priv->mcast_tracker_interval, 0);       /* = auto */
+       atomic_set(&bat_priv->mcast_tracker_timeout, 0);        /* = auto */
+       atomic_set(&bat_priv->mcast_fanout, 2);
        atomic_set(&bat_priv->log_level, 0);
        atomic_set(&bat_priv->fragmentation, 1);
        atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN);
diff --git a/batman-adv/types.h b/batman-adv/types.h
index e4a0462..47490fa 100644
--- a/batman-adv/types.h
+++ b/batman-adv/types.h
@@ -139,6 +139,10 @@ struct bat_priv {
        atomic_t gw_bandwidth;          /* gw bandwidth */
        atomic_t orig_interval;         /* uint */
        atomic_t hop_penalty;           /* uint */
+       atomic_t mcast_mode;            /* MCAST_MODE_* */
+       atomic_t mcast_tracker_interval;/* uint, auto */
+       atomic_t mcast_tracker_timeout; /* uint, auto */
+       atomic_t mcast_fanout;          /* uint */
        atomic_t log_level;             /* uint */
        atomic_t bcast_seqno;
        atomic_t bcast_queue_left;
-- 
1.7.2.3

Reply via email to