public inbox for b.a.t.m.a.n@lists.open-mesh.org
 help / color / mirror / Atom feed
* [B.A.T.M.A.N.] batman-adv gateway support
@ 2010-01-04 15:44 Marek Lindner
  2010-01-04 15:46 ` [B.A.T.M.A.N.] [PATCH 1/3] batman-adv: adding gateway functionality Marek Lindner
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Marek Lindner @ 2010-01-04 15:44 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking


Hi,

batman-adv still lacks the well-known gateway functionality the batman daemon 
offered since quite a while. Since batman-adv works sufficiently well without it 
and due to the ongoing debate whether a layer 2 mesh protocol should interfere 
with layer 3 this topic has been neglected for a while. In multi-gateway 
environments proper gateway support is a must have. Therefore I hereby propose 
a set of patches to add this functionality. Comments welcome!

What you get:
* The first patch will add gateway announce / handling support to the protocol. 
You will have additional /proc files to switch gateway modes, get a list of 
gateways in the network and see the currently selected best gateway. 
* The second patch simply adds batctl support to conveniently configure the 
gateway setup.
* The third patch checks whether locally received packets are DHCP queries and 
forwards them via uncicast to the best gateway instead of broadcasting them.

Note:
* These patches change the routing protocol, therefore the compat version is 
increased. This (intentionally) breaks interoperability with older batman-adv 
versions!
* Only DHCP traffic gets redirected to the best gateway - no other traffic is 
affected. This is part of the compromise we achieved during the last 
discussions.
* IPv6 support is still missing but should be fairly easy to add. Any 
volunteers ?

Regards,
Marek

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [B.A.T.M.A.N.] [PATCH 1/3] batman-adv: adding gateway functionality
  2010-01-04 15:44 [B.A.T.M.A.N.] batman-adv gateway support Marek Lindner
@ 2010-01-04 15:46 ` Marek Lindner
  2010-01-04 15:46   ` [B.A.T.M.A.N.] [PATCH 2/3] batctl: add support for gateway mode Marek Lindner
  2010-01-04 16:48 ` [B.A.T.M.A.N.] batman-adv gateway support predrag balorda
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 17+ messages in thread
From: Marek Lindner @ 2010-01-04 15:46 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Via the /proc filesystem you can change the gateway mode of a node
to server or client (default is: off). Servers will announce there
bandwidth, so that clients can choose their best gateway.

Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
 batman-adv-kernelland/Makefile.kbuild  |    2 +-
 batman-adv-kernelland/gateway_client.c |  335 ++++++++++++++++++++++++++++++++
 batman-adv-kernelland/gateway_client.h |   29 +++
 batman-adv-kernelland/gateway_common.c |  276 ++++++++++++++++++++++++++
 batman-adv-kernelland/gateway_common.h |   34 ++++
 batman-adv-kernelland/main.c           |    6 +
 batman-adv-kernelland/originator.c     |    6 +-
 batman-adv-kernelland/packet.h         |    4 +-
 batman-adv-kernelland/proc.c           |  144 ++++++++++++++
 batman-adv-kernelland/proc.h           |    2 +
 batman-adv-kernelland/routing.c        |   13 ++-
 batman-adv-kernelland/send.c           |    3 +
 batman-adv-kernelland/types.h          |   14 +-
 13 files changed, 860 insertions(+), 8 deletions(-)
 create mode 100644 batman-adv-kernelland/gateway_client.c
 create mode 100644 batman-adv-kernelland/gateway_client.h
 create mode 100644 batman-adv-kernelland/gateway_common.c
 create mode 100644 batman-adv-kernelland/gateway_common.h

diff --git a/batman-adv-kernelland/Makefile.kbuild b/batman-adv-kernelland/Makefile.kbuild
index f75d4af..dc357e7 100644
--- a/batman-adv-kernelland/Makefile.kbuild
+++ b/batman-adv-kernelland/Makefile.kbuild
@@ -32,4 +32,4 @@ EXTRA_CFLAGS += -DREVISION_VERSION=\"r$(REVISION)\"
 endif
 
 obj-m += batman-adv.o
-batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o $(shell [ "2" -eq "$(VERSION)" ] && [ "6" -eq "$(PATCHLEVEL)" ] && [ "$(SUBLEVEL)" -le "28" ] && echo bat_printk.o)
+batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o gateway_common.o gateway_client.o $(shell [ "2" -eq "$(VERSION)" ] && [ "6" -eq "$(PATCHLEVEL)" ] && [ "$(SUBLEVEL)" -le "28" ] && echo bat_printk.o)
diff --git a/batman-adv-kernelland/gateway_client.c b/batman-adv-kernelland/gateway_client.c
new file mode 100644
index 0000000..55789ad
--- /dev/null
+++ b/batman-adv-kernelland/gateway_client.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2009 B.A.T.M.A.N. contributors:
+ * Marek Lindner
+ * 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 "gateway_client.h"
+#include "gateway_common.h"
+
+LIST_HEAD(gw_list);
+DEFINE_SPINLOCK(curr_gw_lock);
+DEFINE_SPINLOCK(gw_list_lock);
+atomic_t gw_clnt_class;
+static struct gw_node *curr_gateway;
+
+void gw_deselect(void)
+{
+	spin_lock(&curr_gw_lock);
+	curr_gateway = NULL;
+	spin_unlock(&curr_gw_lock);
+}
+
+void gw_election(void)
+{
+	struct gw_node *gw_node, *curr_gw_tmp = NULL;
+	uint8_t max_tq = 0;
+	uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
+	int down, up;
+
+	/**
+	 * The batman daemon checks here if we already passed a full originator
+	 * cycle in order to make sure we don't choose the first gateway we
+	 * hear about. This check is based on the daemon's uptime which we
+	 * don't have.
+	 **/
+	if (atomic_read(&gw_clnt_class) == 0)
+		return;
+
+	if (curr_gateway)
+		return;
+
+	rcu_read_lock();
+	if (list_empty(&gw_list)) {
+		rcu_read_unlock();
+
+		if (curr_gateway) {
+			bat_dbg(DBG_BATMAN,
+				"Removing selected gateway - no gateway in range\n");
+			gw_deselect();
+		}
+
+		return;
+	}
+
+	list_for_each_entry_rcu(gw_node, &gw_list, list) {
+		if (!gw_node->orig_node->router)
+			continue;
+
+		if (gw_node->deleted)
+			continue;
+
+		switch (atomic_read(&gw_clnt_class)) {
+		case 1: /* fast connection */
+			gw_srv_class_to_kbit(gw_node->orig_node->gw_flags,
+					     &down, &up);
+
+			tmp_gw_factor = (gw_node->orig_node->router->tq_avg *
+					 gw_node->orig_node->router->tq_avg *
+					 down * 100 * 100) /
+					 (TQ_LOCAL_WINDOW_SIZE *
+					 TQ_LOCAL_WINDOW_SIZE * 64);
+
+			if ((tmp_gw_factor > max_gw_factor) ||
+			    ((tmp_gw_factor == max_gw_factor) &&
+			     (gw_node->orig_node->router->tq_avg > max_tq)))
+				curr_gw_tmp = gw_node;
+			break;
+
+		default: /**
+			  * 2:  stable connection (use best statistic)
+			  * 3:  fast-switch (use best statistic but change as
+			  *     soon as a better gateway appears)
+			  * XX: late-switch (use best statistic but change as
+			  *     soon as a better gateway appears which has
+			  *     $routing_class more tq points)
+			  **/
+			if (gw_node->orig_node->router->tq_avg > max_tq)
+				curr_gw_tmp = gw_node;
+			break;
+		}
+
+		if (gw_node->orig_node->router->tq_avg > max_tq)
+			max_tq = gw_node->orig_node->router->tq_avg;
+
+		if (tmp_gw_factor > max_gw_factor)
+			max_gw_factor = tmp_gw_factor;
+	}
+	rcu_read_unlock();
+
+	spin_lock(&curr_gw_lock);
+	if (curr_gateway != curr_gw_tmp) {
+		if ((curr_gateway) && (!curr_gw_tmp))
+			bat_dbg(DBG_BATMAN,
+				"Removing selected gateway - no gateway in range\n");
+		else if ((!curr_gateway) && (curr_gw_tmp))
+			bat_dbg(DBG_BATMAN,
+				"Adding route to gateway %pM (gw_flags: %i, tq: %i)\n",
+				curr_gw_tmp->orig_node->orig,
+				curr_gw_tmp->orig_node->gw_flags,
+				curr_gw_tmp->orig_node->router->tq_avg);
+		else
+			bat_dbg(DBG_BATMAN,
+				"Changing route to gateway %pM (gw_flags: %i, tq: %i)\n",
+				curr_gw_tmp->orig_node->orig,
+				curr_gw_tmp->orig_node->gw_flags,
+				curr_gw_tmp->orig_node->router->tq_avg);
+
+		curr_gateway = curr_gw_tmp;
+	}
+	spin_unlock(&curr_gw_lock);
+}
+
+void gw_check_election(struct orig_node *orig_node)
+{
+	struct gw_node *curr_gateway_tmp;
+	uint8_t gw_tq_avg, orig_tq_avg;
+
+	spin_lock(&curr_gw_lock);
+	curr_gateway_tmp = curr_gateway;
+	spin_unlock(&curr_gw_lock);
+
+	if (!curr_gateway_tmp)
+		return;
+
+	/* this node already is the gateway */
+	if (curr_gateway_tmp->orig_node == orig_node)
+		return;
+
+	if (!orig_node->router)
+		return;
+
+	gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg;
+	orig_tq_avg = orig_node->router->tq_avg;
+
+	/* the TQ value has to be better */
+	if (orig_tq_avg < gw_tq_avg)
+		return;
+
+	/**
+	 * 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(&gw_clnt_class) > 3) &&
+	    (orig_tq_avg - gw_tq_avg < atomic_read(&gw_clnt_class)))
+		return;
+
+	bat_dbg(DBG_BATMAN,
+		"Restarting gateway selection: better gateway found (tq curr: %i, tq new: %i) \n",
+		gw_tq_avg, orig_tq_avg);
+
+	gw_deselect();
+}
+
+static void gw_node_add(struct orig_node *orig_node, uint8_t new_gwflags)
+{
+	struct gw_node *gw_node;
+	int down, up;
+
+	gw_node = kmalloc(sizeof(struct gw_node), GFP_ATOMIC);
+	if (!gw_node)
+		return;
+
+	memset(gw_node, 0, sizeof(struct gw_node));
+	INIT_LIST_HEAD(&gw_node->list);
+	gw_node->orig_node = orig_node;
+
+	list_add_tail_rcu(&gw_node->list, &gw_list);
+
+	gw_srv_class_to_kbit(new_gwflags, &down, &up);
+	bat_dbg(DBG_BATMAN,
+		"Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n",
+		orig_node->orig, new_gwflags,
+		(down > 2048 ? down / 1024 : down),
+		(down > 2048 ? "MBit" : "KBit"),
+		(up > 2048 ? up / 1024 : up),
+		(up > 2048 ? "MBit" : "KBit"));
+}
+
+void gw_node_update(struct orig_node *orig_node, uint8_t new_gwflags)
+{
+	struct gw_node *gw_node;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(gw_node, &gw_list, list) {
+		if (gw_node->orig_node != orig_node)
+			continue;
+
+		bat_dbg(DBG_BATMAN,
+			"Gateway class of originator %pM changed from %i to %i\n",
+			orig_node->orig, gw_node->orig_node->gw_flags,
+			new_gwflags);
+
+		gw_node->deleted = 0;
+
+		if (new_gwflags == 0) {
+			gw_node->deleted = jiffies;
+			bat_dbg(DBG_BATMAN,
+				"Gateway %pM removed from gateway list\n",
+				orig_node->orig);
+
+			if (gw_node == curr_gateway)
+				gw_deselect();
+		}
+
+		return;
+	}
+	rcu_read_unlock();
+
+	if (new_gwflags == 0)
+		return;
+
+	gw_node_add(orig_node, new_gwflags);
+}
+
+void gw_node_delete(struct orig_node *orig_node)
+{
+	return gw_node_update(orig_node, 0);
+}
+
+static void gw_node_free(struct rcu_head *rcu)
+{
+	struct gw_node *gw_node = container_of(rcu, struct gw_node, rcu);
+	kfree(gw_node);
+}
+
+void gw_node_purge_deleted(void)
+{
+	struct gw_node *gw_node, *gw_node_tmp;
+	unsigned long timeout = (2 * PURGE_TIMEOUT * HZ) / 1000;
+
+	spin_lock(&gw_list_lock);
+
+	list_for_each_entry_safe(gw_node, gw_node_tmp, &gw_list, list) {
+		if ((gw_node->deleted) &&
+		    (time_after(jiffies, gw_node->deleted + timeout))) {
+
+			list_del_rcu(&gw_node->list);
+			call_rcu(&gw_node->rcu, gw_node_free);
+		}
+	}
+
+	spin_unlock(&gw_list_lock);
+}
+
+void gw_node_list_free(void)
+{
+	struct gw_node *gw_node, *gw_node_tmp;
+
+	spin_lock(&gw_list_lock);
+
+	list_for_each_entry_safe(gw_node, gw_node_tmp, &gw_list, list) {
+		list_del_rcu(&gw_node->list);
+		call_rcu(&gw_node->rcu, gw_node_free);
+	}
+
+	gw_deselect();
+	spin_unlock(&gw_list_lock);
+}
+
+static int _write_buffer_text(unsigned char *buff, int bytes_written,
+			      struct gw_node *gw_node)
+{
+	int down, up;
+	char gw_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
+
+	addr_to_string(gw_str, gw_node->orig_node->orig);
+	addr_to_string(router_str, gw_node->orig_node->router->addr);
+	gw_srv_class_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
+
+	return sprintf(buff + bytes_written,
+		       "%s %-17s (%3i) %17s [%10s]: %3i - %i%s/%i%s\n",
+		       (curr_gateway == gw_node ? "=>" : "  "),
+		       gw_str,
+		       gw_node->orig_node->router->tq_avg,
+		       router_str,
+		       gw_node->orig_node->router->if_incoming->dev,
+		       gw_node->orig_node->gw_flags,
+		       (down > 2048 ? down / 1024 : down),
+		       (down > 2048 ? "MBit" : "KBit"),
+		       (up > 2048 ? up / 1024 : up),
+		       (up > 2048 ? "MBit" : "KBit"));
+}
+
+int gw_client_fill_buffer_text(unsigned char *buff, int buff_len)
+{
+	struct gw_node *gw_node;
+	int bytes_written = 0, gw_count = 0;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(gw_node, &gw_list, list) {
+		if (gw_node->deleted)
+			continue;
+
+		if (!gw_node->orig_node->router)
+			continue;
+
+		if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 30)
+			break;
+
+		bytes_written += _write_buffer_text(buff,
+						    bytes_written,
+						    gw_node);
+		gw_count++;
+	}
+	rcu_read_unlock();
+
+	if (gw_count == 0)
+		sprintf(buff, "No gateways in range ... \n");
+
+	return bytes_written;
+}
diff --git a/batman-adv-kernelland/gateway_client.h b/batman-adv-kernelland/gateway_client.h
new file mode 100644
index 0000000..5eb1e4c
--- /dev/null
+++ b/batman-adv-kernelland/gateway_client.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 B.A.T.M.A.N. contributors:
+ * Marek Lindner
+ * 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
+ *
+ */
+
+extern atomic_t gw_clnt_class;
+
+void gw_deselect(void);
+void gw_election(void);
+void gw_check_election(struct orig_node *orig_node);
+void gw_node_update(struct orig_node *orig_node, uint8_t new_gwflags);
+void gw_node_delete(struct orig_node *orig_node);
+void gw_node_purge_deleted(void);
+void gw_node_list_free(void);
+int gw_client_fill_buffer_text(unsigned char *buff, int buff_len);
diff --git a/batman-adv-kernelland/gateway_common.c b/batman-adv-kernelland/gateway_common.c
new file mode 100644
index 0000000..1d7fd2c
--- /dev/null
+++ b/batman-adv-kernelland/gateway_common.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2009 B.A.T.M.A.N. contributors:
+ * Marek Lindner
+ * 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 "gateway_common.h"
+#include "gateway_client.h"
+
+atomic_t gw_mode;
+atomic_t gw_srv_class;
+
+/* calculates the gateway class from kbit */
+void kbit_to_gw_srv_class(int down, int up, long *gw_srv_class)
+{
+	int mdown = 0, tdown, tup, difference;
+	uint8_t sbit, part;
+
+	*gw_srv_class = 0;
+	difference = 0x0FFFFFFF;
+
+	/* test all downspeeds */
+	for (sbit = 0; sbit < 2; sbit++) {
+		for (part = 0; part < 16; part++) {
+			tdown = 32 * (sbit + 2) * (1 << part);
+
+			if (abs(tdown - down) < difference) {
+				*gw_srv_class = (sbit << 7) + (part << 3);
+				difference = abs(tdown - down);
+				mdown = tdown;
+			}
+		}
+	}
+
+	/* test all upspeeds */
+	difference = 0x0FFFFFFF;
+
+	for (part = 0; part < 8; part++) {
+		tup = ((part + 1) * (mdown)) / 8;
+
+		if (abs(tup - up) < difference) {
+			*gw_srv_class = (*gw_srv_class & 0xF8) | part;
+			difference = abs(tup - up);
+		}
+	}
+}
+
+/* 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)
+{
+	char sbit = (gw_srv_class & 0x80) >> 7;
+	char dpart = (gw_srv_class & 0x7C) >> 3;
+	char upart = (gw_srv_class & 0x07);
+
+	if (!gw_srv_class) {
+		*down = 0;
+		*up = 0;
+		return;
+	}
+
+	*down = 32 * (sbit + 2) * (1 << dpart);
+	*up = ((upart + 1) * (*down)) / 8;
+}
+
+static bool parse_gw_mode_tok(char *tokptr, long *gw_mode_tmp,
+			      char **gw_mode_tmp_str, long *gw_clnt_class_tmp,
+			      long *up, long *down)
+{
+	int ret;
+	char *slash_ptr, *tmp_ptr;
+
+	switch (*gw_mode_tmp) {
+	case GW_MODE_CLIENT:
+		ret = strict_strtol(tokptr, 10, gw_clnt_class_tmp);
+		if (ret) {
+			printk(KERN_ERR "Client class of gateway mode invalid: %s\n",
+			       tokptr);
+			return false;
+		}
+
+		if (*gw_clnt_class_tmp > TQ_MAX_VALUE) {
+			printk(KERN_ERR "Client class of gateway mode greater than %i: %ld\n",
+					TQ_MAX_VALUE, *gw_clnt_class_tmp);
+			return false;
+		}
+
+		break;
+	case GW_MODE_SERVER:
+		slash_ptr = strchr(tokptr, '/');
+		if (slash_ptr)
+			*slash_ptr = 0;
+
+		ret = strict_strtol(tokptr, 10, down);
+		if (ret) {
+			printk(KERN_ERR "Download speed of gateway mode invalid: %s\n",
+			       tokptr);
+			return false;
+		}
+
+		tmp_ptr = tokptr + strlen(tokptr) - 4;
+
+		if ((strlen(tokptr) > 4) &&
+			((strncmp(tmp_ptr, "MBit", 4) == 0) ||
+			(strncmp(tmp_ptr, "mbit", 4) == 0) ||
+			(strncmp(tmp_ptr, "Mbit", 4) == 0)))
+			*down *= 1024;
+
+		/* we also got some upload info */
+		if (slash_ptr) {
+			ret = strict_strtol(slash_ptr + 1, 10, up);
+			if (ret) {
+				printk(KERN_ERR "Upload speed of gateway mode invalid: %s\n",
+				       slash_ptr + 1);
+				return false;
+			}
+
+			tmp_ptr = slash_ptr + 1 + strlen(slash_ptr + 1) - 4;
+
+			if ((strlen(slash_ptr + 1) > 4) &&
+				((strncmp(tmp_ptr, "MBit", 4) == 0) ||
+				(strncmp(tmp_ptr, "mbit", 4) == 0) ||
+				(strncmp(tmp_ptr, "Mbit", 4) == 0)))
+				*up *= 1024;
+
+			*slash_ptr = '/';
+		}
+
+		break;
+	default:
+		if (strcmp(tokptr, GW_MODE_OFF_NAME) == 0) {
+			*gw_mode_tmp = GW_MODE_OFF;
+			*gw_mode_tmp_str = GW_MODE_OFF_NAME;
+		}
+
+		if (strcmp(tokptr, GW_MODE_CLIENT_NAME) == 0) {
+			*gw_mode_tmp = GW_MODE_CLIENT;
+			*gw_mode_tmp_str = GW_MODE_CLIENT_NAME;
+		}
+
+		if (strcmp(tokptr, GW_MODE_SERVER_NAME) == 0) {
+			*gw_mode_tmp = GW_MODE_SERVER;
+			*gw_mode_tmp_str = GW_MODE_SERVER_NAME;
+		}
+	}
+
+	return true;
+}
+
+ssize_t gw_mode_set(const char __user *userbuffer, size_t count)
+{
+	char *gw_mode_string, *tokptr, *cp;
+	char *gw_mode_curr_str, *gw_mode_tmp_str = NULL;
+	int finished, not_copied = 0;
+	long gw_mode_curr, gw_mode_tmp = GW_MODE_OFF;
+	long gw_srv_class_tmp = 0, gw_clnt_class_tmp = 0, up = 0, down = 0;
+	bool ret;
+
+	gw_mode_string = kmalloc(count, GFP_KERNEL);
+
+	if (!gw_mode_string)
+		return -ENOMEM;
+
+	not_copied = copy_from_user(gw_mode_string, userbuffer, count);
+	gw_mode_string[count - not_copied - 1] = 0;
+
+	tokptr = gw_mode_string;
+	gw_mode_curr = atomic_read(&gw_mode);
+
+	for (cp = gw_mode_string, finished = 0; !finished; cp++) {
+		switch (*cp) {
+		case 0:
+			finished = 1;
+		case ' ':
+		case '\n':
+		case '\t':
+			*cp = 0;
+			ret = parse_gw_mode_tok(tokptr, &gw_mode_tmp,
+						&gw_mode_tmp_str,
+						&gw_clnt_class_tmp,
+						&up, &down);
+
+			if (!ret)
+				goto end;
+
+			tokptr = cp + 1;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (!gw_mode_tmp_str) {
+		printk(KERN_INFO "Gateway mode can only be set to: '%s', '%s' or '%s' - given value: %s\n",
+			GW_MODE_OFF_NAME, GW_MODE_CLIENT_NAME,
+			GW_MODE_SERVER_NAME, gw_mode_string);
+		goto end;
+	}
+
+	switch (gw_mode_curr) {
+	case GW_MODE_CLIENT:
+		gw_mode_curr_str = GW_MODE_CLIENT_NAME;
+		break;
+	case GW_MODE_SERVER:
+		gw_mode_curr_str = GW_MODE_SERVER_NAME;
+		break;
+	default:
+		gw_mode_curr_str = GW_MODE_OFF_NAME;
+		break;
+	}
+
+	switch (gw_mode_tmp) {
+	case GW_MODE_CLIENT:
+		if ((gw_mode_tmp == GW_MODE_CLIENT) && (!gw_clnt_class_tmp))
+			gw_clnt_class_tmp = 20;
+
+		printk(KERN_INFO "Changing gateway mode from: '%s' to: '%s' (gw_clnt_class: %ld)\n",
+			  gw_mode_curr_str, gw_mode_tmp_str,
+			  gw_clnt_class_tmp);
+		break;
+	case GW_MODE_SERVER:
+		if (!down)
+			down = 2000;
+
+		if (!up)
+			up = down / 5;
+
+		kbit_to_gw_srv_class(down, up, &gw_srv_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_srv_class_tmp,
+				     (int *)&down, (int *)&up);
+
+		printk(KERN_INFO
+			  "Changing gateway mode from: '%s' to: '%s' (gw_srv_class: %ld -> propagating: %ld%s/%ld%s)\n",
+			  gw_mode_curr_str, gw_mode_tmp_str,
+			  gw_srv_class_tmp,
+			  (down > 2048 ? down / 1024 : down),
+			  (down > 2048 ? "MBit" : "KBit"),
+			  (up > 2048 ? up / 1024 : up),
+			  (up > 2048 ? "MBit" : "KBit"));
+		break;
+	default:
+		printk(KERN_INFO "Changing gateway mode from: '%s' to: '%s'\n",
+			  gw_mode_curr_str, gw_mode_tmp_str);
+		break;
+	}
+
+	atomic_set(&gw_mode, gw_mode_tmp);
+	atomic_set(&gw_srv_class, gw_srv_class_tmp);
+	atomic_set(&gw_clnt_class, gw_clnt_class_tmp);
+
+	if (gw_clnt_class_tmp == 0)
+		gw_deselect();
+
+end:
+	kfree(gw_mode_string);
+	return count;
+}
diff --git a/batman-adv-kernelland/gateway_common.h b/batman-adv-kernelland/gateway_common.h
new file mode 100644
index 0000000..365cd00
--- /dev/null
+++ b/batman-adv-kernelland/gateway_common.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 B.A.T.M.A.N. contributors:
+ * Marek Lindner
+ * 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
+ *
+ */
+
+enum gw_modes {
+	GW_MODE_OFF,
+	GW_MODE_CLIENT,
+	GW_MODE_SERVER,
+};
+
+#define GW_MODE_OFF_NAME	"off"
+#define GW_MODE_CLIENT_NAME	"client"
+#define GW_MODE_SERVER_NAME	"server"
+
+extern atomic_t gw_mode;
+extern atomic_t gw_srv_class;
+
+void gw_srv_class_to_kbit(uint8_t gw_class, int *down, int *up);
+ssize_t gw_mode_set(const char __user *userbuffer, size_t count);
diff --git a/batman-adv-kernelland/main.c b/batman-adv-kernelland/main.c
index 1d80ea3..a64f070 100644
--- a/batman-adv-kernelland/main.c
+++ b/batman-adv-kernelland/main.c
@@ -28,6 +28,8 @@
 #include "device.h"
 #include "translation-table.h"
 #include "hard-interface.h"
+#include "gateway_common.h"
+#include "gateway_client.h"
 #include "types.h"
 #include "vis.h"
 #include "hash.h"
@@ -85,6 +87,9 @@ int init_module(void)
 	atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
 					 * for debugging now. */
 	atomic_set(&aggregation_enabled, 1);
+	atomic_set(&gw_mode, GW_MODE_OFF);
+	atomic_set(&gw_srv_class, 0);
+	atomic_set(&gw_clnt_class, 0);
 
 	/* the name should not be longer than 10 chars - see
 	 * http://lwn.net/Articles/23634/ */
@@ -191,6 +196,7 @@ void shutdown_module(void)
 
 	/* TODO: unregister BATMAN pack */
 
+	gw_node_list_free();
 	originator_free();
 
 	hna_local_free();
diff --git a/batman-adv-kernelland/originator.c b/batman-adv-kernelland/originator.c
index cff433e..a9ba24c 100644
--- a/batman-adv-kernelland/originator.c
+++ b/batman-adv-kernelland/originator.c
@@ -27,7 +27,7 @@
 #include "translation-table.h"
 #include "routing.h"
 #include "compat.h"
-
+#include "gateway_client.h"
 
 static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
 
@@ -241,6 +241,8 @@ void purge_orig(struct work_struct *work)
 	while (hash_iterate(orig_hash, &hashit)) {
 		orig_node = hashit.bucket->data;
 		if (purge_orig_node(orig_node)) {
+			if (orig_node->gw_flags)
+				gw_node_delete(orig_node);
 			hash_remove_bucket(orig_hash, &hashit);
 			free_orig_node(orig_node);
 		}
@@ -248,5 +250,7 @@ void purge_orig(struct work_struct *work)
 
 	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
+	gw_node_purge_deleted();
+	gw_election();
 	start_purge_timer();
 }
diff --git a/batman-adv-kernelland/packet.h b/batman-adv-kernelland/packet.h
index ad006ce..b543b03 100644
--- a/batman-adv-kernelland/packet.h
+++ b/batman-adv-kernelland/packet.h
@@ -28,7 +28,7 @@
 #define BAT_VIS       0x05
 
 /* this file is included by batctl which needs these defines */
-#define COMPAT_VERSION 8
+#define COMPAT_VERSION 9
 #define DIRECTLINK 0x40
 #define VIS_SERVER 0x20
 
@@ -53,6 +53,8 @@ struct batman_packet {
 	uint8_t  prev_sender[6];
 	uint8_t  ttl;
 	uint8_t  num_hna;
+	uint8_t  gw_flags;  /* flags related to gateway class */
+	uint8_t  align;
 } __attribute__((packed));
 
 #define BAT_PACKET_LEN sizeof(struct batman_packet)
diff --git a/batman-adv-kernelland/proc.c b/batman-adv-kernelland/proc.c
index 1bf493f..747ed5f 100644
--- a/batman-adv-kernelland/proc.c
+++ b/batman-adv-kernelland/proc.c
@@ -28,6 +28,8 @@
 #include "hash.h"
 #include "vis.h"
 #include "compat.h"
+#include "gateway_common.h"
+#include "gateway_client.h"
 
 static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
 static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file;
@@ -35,6 +37,7 @@ static struct proc_dir_entry *proc_transt_local_file;
 static struct proc_dir_entry *proc_transt_global_file;
 static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file;
 static struct proc_dir_entry *proc_aggr_file;
+static struct proc_dir_entry *proc_gw_mode_file, *proc_gw_srv_list_file;
 
 static int proc_interfaces_read(struct seq_file *seq, void *offset)
 {
@@ -462,6 +465,99 @@ static int proc_aggr_open(struct inode *inode, struct file *file)
 	return single_open(file, proc_aggr_read, NULL);
 }
 
+static int proc_gw_mode_read(struct seq_file *seq, void *offset)
+{
+	int down, up;
+	long gw_mode_curr = atomic_read(&gw_mode);
+	uint8_t gw_srv_class_curr = (uint8_t)atomic_read(&gw_srv_class);
+
+	gw_srv_class_to_kbit(gw_srv_class_curr, &down, &up);
+
+	seq_printf(seq, "[%c] %s\n",
+		   (gw_mode_curr == GW_MODE_OFF) ? 'x' : ' ',
+		   GW_MODE_OFF_NAME);
+
+	if (gw_mode_curr == GW_MODE_CLIENT)
+		seq_printf(seq, "[x] %s (gw_clnt_class: %i)\n",
+			   GW_MODE_CLIENT_NAME,
+			   atomic_read(&gw_clnt_class));
+	else
+		seq_printf(seq, "[ ] %s\n", GW_MODE_CLIENT_NAME);
+
+	if (gw_mode_curr == GW_MODE_SERVER)
+		seq_printf(seq,
+			   "[x] %s (gw_srv_class: %i -> propagating: %i%s/%i%s)\n",
+			   GW_MODE_SERVER_NAME,
+			   gw_srv_class_curr,
+			   (down > 2048 ? down / 1024 : down),
+			   (down > 2048 ? "MBit" : "KBit"),
+			   (up > 2048 ? up / 1024 : up),
+			   (up > 2048 ? "MBit" : "KBit"));
+	else
+		seq_printf(seq, "[ ] %s\n", GW_MODE_SERVER_NAME);
+
+	return 0;
+}
+
+static int proc_gw_mode_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_gw_mode_read, NULL);
+}
+
+static ssize_t proc_gw_mode_write(struct file *instance,
+				    const char __user *userbuffer,
+				    size_t count, loff_t *data)
+{
+	return gw_mode_set(userbuffer, count);
+}
+
+static int proc_gw_srv_list_read(struct seq_file *seq, void *offset)
+{
+	char *buff;
+	int buffsize = 4096;
+
+	buff = kmalloc(buffsize, GFP_KERNEL);
+	if (!buff)
+		return 0;
+
+	rcu_read_lock();
+	if (list_empty(&if_list)) {
+		rcu_read_unlock();
+		seq_printf(seq,
+			   "BATMAN disabled - please specify interfaces to enable it\n");
+		goto end;
+	}
+
+	if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
+		rcu_read_unlock();
+		seq_printf(seq,
+			   "BATMAN disabled - primary interface not active\n");
+		goto end;
+	}
+
+	seq_printf(seq,
+		   "      %-12s (%s/%i) %17s [%10s]: gw_srv_class ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n",
+		   "Gateway", "#", TQ_MAX_VALUE, "Nexthop",
+		   "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
+		   ((struct batman_if *)if_list.next)->dev,
+		   ((struct batman_if *)if_list.next)->addr_str);
+
+	rcu_read_unlock();
+
+	gw_client_fill_buffer_text(buff, buffsize);
+	seq_printf(seq, "%s", buff);
+
+end:
+	kfree(buff);
+	return 0;
+}
+
+static int proc_gw_srv_list_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_gw_srv_list_read, NULL);
+}
+
+
 /* satisfying different prototypes ... */
 static ssize_t proc_dummy_write(struct file *file, const char __user *buffer,
 				size_t count, loff_t *ppos)
@@ -469,6 +565,24 @@ static ssize_t proc_dummy_write(struct file *file, const char __user *buffer,
 	return count;
 }
 
+static const struct file_operations proc_gw_srv_list_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_gw_srv_list_open,
+	.read		= seq_read,
+	.write		= proc_dummy_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_gw_mode_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_gw_mode_open,
+	.read		= seq_read,
+	.write		= proc_gw_mode_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static const struct file_operations proc_aggr_fops = {
 	.owner		= THIS_MODULE,
 	.open		= proc_aggr_open,
@@ -567,6 +681,12 @@ void cleanup_procfs(void)
 	if (proc_aggr_file)
 		remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir);
 
+	if (proc_gw_mode_file)
+		remove_proc_entry(PROC_FILE_GW_MODE, proc_batman_dir);
+
+	if (proc_gw_srv_list_file)
+		remove_proc_entry(PROC_FILE_GW_SRV_LIST, proc_batman_dir);
+
 	if (proc_batman_dir)
 #ifdef __NET_NET_NAMESPACE_H
 		remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net);
@@ -671,5 +791,29 @@ int setup_procfs(void)
 		return -EFAULT;
 	}
 
+	proc_gw_mode_file = create_proc_entry(PROC_FILE_GW_MODE,
+					   S_IWUSR | S_IRUGO,
+					   proc_batman_dir);
+	if (proc_gw_mode_file) {
+		proc_gw_mode_file->proc_fops = &proc_gw_mode_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n",
+		       PROC_ROOT_DIR, PROC_FILE_GW_MODE);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_gw_srv_list_file = create_proc_entry(PROC_FILE_GW_SRV_LIST,
+					   S_IWUSR | S_IRUGO,
+					   proc_batman_dir);
+	if (proc_gw_srv_list_file) {
+		proc_gw_srv_list_file->proc_fops = &proc_gw_srv_list_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n",
+		       PROC_ROOT_DIR, PROC_FILE_GW_SRV_LIST);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
 	return 0;
 }
diff --git a/batman-adv-kernelland/proc.h b/batman-adv-kernelland/proc.h
index cd690e0..af38d40 100644
--- a/batman-adv-kernelland/proc.h
+++ b/batman-adv-kernelland/proc.h
@@ -34,6 +34,8 @@
 #define PROC_FILE_VIS_SRV "vis_server"
 #define PROC_FILE_VIS_DATA "vis_data"
 #define PROC_FILE_AGGR "aggregate_ogm"
+#define PROC_FILE_GW_MODE "gateway_mode"
+#define PROC_FILE_GW_SRV_LIST "gateway_srv_list"
 
 void cleanup_procfs(void);
 int setup_procfs(void);
diff --git a/batman-adv-kernelland/routing.c b/batman-adv-kernelland/routing.c
index 2eb932f..da6a779 100644
--- a/batman-adv-kernelland/routing.c
+++ b/batman-adv-kernelland/routing.c
@@ -33,6 +33,7 @@
 #include "vis.h"
 #include "aggregation.h"
 #include "compat.h"
+#include "gateway_client.h"
 
 DECLARE_WAIT_QUEUE_HEAD(thread_wait);
 
@@ -306,10 +307,20 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
 		goto update_hna;
 
 	update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len);
-	return;
+	goto update_gw;
 
 update_hna:
 	update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len);
+
+update_gw:
+	if (orig_node->gw_flags != batman_packet->gw_flags)
+		gw_node_update(orig_node, batman_packet->gw_flags);
+
+	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(&gw_clnt_class) > 2))
+		gw_check_election(orig_node);
 }
 
 static char count_real_packets(struct ethhdr *ethhdr,
diff --git a/batman-adv-kernelland/send.c b/batman-adv-kernelland/send.c
index edfdd5d..a40e8b8 100644
--- a/batman-adv-kernelland/send.c
+++ b/batman-adv-kernelland/send.c
@@ -28,6 +28,7 @@
 #include "types.h"
 #include "vis.h"
 #include "aggregation.h"
+#include "gateway_common.h"
 
 #include "compat.h"
 
@@ -279,6 +280,8 @@ void schedule_own_packet(struct batman_if *batman_if)
 	else
 		batman_packet->flags = 0;
 
+	batman_packet->gw_flags = (uint8_t)atomic_read(&gw_srv_class);
+
 	/* could be read by receive_bat_packet() */
 	atomic_inc(&batman_if->seqno);
 
diff --git a/batman-adv-kernelland/types.h b/batman-adv-kernelland/types.h
index dec1b54..495d94a 100644
--- a/batman-adv-kernelland/types.h
+++ b/batman-adv-kernelland/types.h
@@ -43,7 +43,6 @@ struct batman_if {
 	unsigned char *packet_buff;
 	int packet_len;
 	struct rcu_head rcu;
-
 };
 
 struct orig_node {               /* structure for orig_list maintaining nodes of mesh */
@@ -55,10 +54,10 @@ struct orig_node {               /* structure for orig_list maintaining nodes of
 	uint8_t tq_own;
 	int tq_asym_penalty;
 	unsigned long last_valid;        /* when last packet from this node was received */
-/*	uint8_t  gwflags;      * flags related to gateway functions: gateway class */
-	uint8_t  flags;    		/* for now only VIS_SERVER flag. */
+	uint8_t gw_flags;      /* flags related to gateway class */
+	uint8_t flags;    /* for now only VIS_SERVER flag. */
 	unsigned char *hna_buff;
-	int16_t  hna_buff_len;
+	int16_t hna_buff_len;
 	uint16_t last_real_seqno;   /* last and best known squence number */
 	uint8_t last_ttl;         /* ttl of last received packet */
 	TYPE_OF_WORD bcast_bits[NUM_WORDS];
@@ -66,6 +65,13 @@ struct orig_node {               /* structure for orig_list maintaining nodes of
 	struct list_head neigh_list;
 };
 
+struct gw_node {
+	struct list_head list;
+	struct orig_node *orig_node;
+	unsigned long deleted;
+	struct rcu_head rcu;
+};
+
 struct neigh_node {
 	struct list_head list;
 	uint8_t addr[ETH_ALEN];
-- 
1.6.5.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [B.A.T.M.A.N.] [PATCH 2/3] batctl: add support for gateway mode
  2010-01-04 15:46 ` [B.A.T.M.A.N.] [PATCH 1/3] batman-adv: adding gateway functionality Marek Lindner
@ 2010-01-04 15:46   ` Marek Lindner
  2010-01-04 15:46     ` [B.A.T.M.A.N.] [PATCH 3/3] batman-adv: send DHCP requests directly to the chosen gw Marek Lindner
  0 siblings, 1 reply; 17+ messages in thread
From: Marek Lindner @ 2010-01-04 15:46 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

---
 batctl/main.c       |   10 ++++++++++
 batctl/man/batctl.8 |    6 ++++++
 batctl/proc.c       |   16 ++++++++++++++++
 batctl/proc.h       |    8 ++++----
 4 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/batctl/main.c b/batctl/main.c
index 8be1d05..6e4493d 100644
--- a/batctl/main.c
+++ b/batctl/main.c
@@ -46,6 +46,8 @@ void print_usage(void) {
 	printf(" \tinterval|it   [orig_interval]   \tdisplay or modify the originator interval in ms\n");
 	printf(" \tloglevel|ll   [level]           \tdisplay or modify the log level\n");
 	printf(" \tlog|l                           \tread the log produced by the kernel module\n");
+	printf(" \tgw_mode|gw    [mode]            \tdisplay or modify the gateway mode\n");
+	printf(" \tgw_srv_list|gwl                 \tdisplay the gateway server list\n");
 	printf(" \ttranslocal|tl                   \tdisplay the local translation table\n");
 	printf(" \ttransglobal|tg                  \tdisplay the global translation table\n");
 	printf(" \tvis_server|vs [enable|disable]  \tdisplay or modify the status of the VIS server\n");
@@ -130,6 +132,14 @@ int main(int argc, char **argv)
 
 		ret = vis_data(argc - 1, argv + 1);
 
+	} else if ((strcmp(argv[1], "gw_mode") == 0) || (strcmp(argv[1], "gw") == 0)) {
+
+		ret = handle_proc_setting(argc - 1, argv + 1, PROC_GW_MODE, gw_mode_usage);
+
+	} else if ((strcmp(argv[1], "gw_srv_list") == 0) || (strcmp(argv[1], "gwl") == 0)) {
+
+		ret = handle_table(argc - 1, argv + 1, PROC_GW_SRV_LIST, gw_srv_list_usage);
+
 	} else if ((strcmp(argv[1], "aggregation") == 0) || (strcmp(argv[1], "ag") == 0)) {
 
 		ret = handle_proc_setting(argc - 1, argv + 1, PROC_AGGR, aggregation_usage);
diff --git a/batctl/man/batctl.8 b/batctl/man/batctl.8
index 304168c..61e7958 100644
--- a/batctl/man/batctl.8
+++ b/batctl/man/batctl.8
@@ -57,6 +57,12 @@ If no parameter is given the current log level settings are displayed otherwise
 .IP "\fBlog|l\fP	"
 Once started batctl will continuously read the log produced by the kernel module (the amount of log message can be influenced by modifying the log level). Whenever there are new log messages sent by the kernel batctl will display it. Use the "\-b" option to let batctl exit after the existing log buffer has been displayed. If "\-n" was given batctl will not replace the mac addresses with bat\-host names in the output.
 .br
+.IP "\fBgw_mode|gw	[off|client|server]\fP"
+If no parameter is given the current gateway mode is displayed otherwise the parameter is used to set the gateway mode.
+.br
+.IP "\fBgw_srv_list|gwl\fP"
+Once started batctl will refresh the displayed gateway server list every second. Use the "\-b" option to let batctl display the list only once (useful for scripts). If "\-n" was given batctl will not replace the mac addresses with bat\-host names in the output.
+.br
 .IP "\fBtranslocal|tl\fP"
 Once started batctl will refresh the displayed local translation table every second. Use the "\-b" option to let batctl display the table only once (useful for scripts). If "\-n" was given batctl will not replace the mac addresses with bat\-host names in the output.
 .br
diff --git a/batctl/proc.c b/batctl/proc.c
index d73a9fa..7ae19b4 100644
--- a/batctl/proc.c
+++ b/batctl/proc.c
@@ -95,6 +95,15 @@ void trans_global_usage(void)
 	printf(" \t -n don't replace mac addresses with bat-host names\n");
 }
 
+void gw_srv_list_usage(void)
+{
+	printf("Usage: batctl [options] gw_srv_list \n");
+	printf("options:\n");
+	printf(" \t -b batch mode - read the gateway server list once and quit\n");
+	printf(" \t -h print this help\n");
+	printf(" \t -n don't replace mac addresses with bat-host names\n");
+}
+
 void orig_interval_usage(void)
 {
 	printf("Usage: batctl [options] interval \n");
@@ -116,6 +125,13 @@ void aggregation_usage(void)
 	printf(" \t -h print this help\n");
 }
 
+void gw_mode_usage(void)
+{
+	printf("Usage: batctl [options] gw_mode [mode]\n");
+	printf("options:\n");
+	printf(" \t -h print this help\n");
+}
+
 int handle_table(int argc, char **argv, char *file_path, void table_usage(void))
 {
 	int optchar, read_opt = CLR_CONT_READ | USE_BAT_HOSTS;
diff --git a/batctl/proc.h b/batctl/proc.h
index ad00136..d867b78 100644
--- a/batctl/proc.h
+++ b/batctl/proc.h
@@ -19,19 +19,17 @@
  *
  */
 
-
-
 #define PROC_ROOT_PATH "/proc/net/batman-adv/"
 #define PROC_INTERFACES "interfaces"
 #define PROC_ORIGINATORS "originators"
 #define PROC_ORIG_INTERVAL "orig_interval"
-#define PROC_GATEWAYS "gateways"
 #define PROC_TRANSTABLE_LOCAL "transtable_local"
 #define PROC_TRANSTABLE_GLOBAL "transtable_global"
 #define PROC_VIS_SERVER "vis_server"
 #define PROC_VIS_DATA "vis_data"
 #define PROC_AGGR "aggregate_ogm"
-
+#define PROC_GW_MODE "gateway_mode"
+#define PROC_GW_SRV_LIST "gateway_srv_list"
 
 int interface(int argc, char **argv);
 
@@ -41,5 +39,7 @@ void trans_global_usage(void);
 void orig_interval_usage(void);
 void vis_server_usage(void);
 void aggregation_usage(void);
+void gw_mode_usage(void);
+void gw_srv_list_usage(void);
 int handle_table(int argc, char **argv, char *file_path, void table_usage(void));
 int handle_proc_setting(int argc, char **argv, char *file_path, void setting_usage(void));
-- 
1.6.5.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [B.A.T.M.A.N.] [PATCH 3/3] batman-adv: send DHCP requests directly to the chosen gw
  2010-01-04 15:46   ` [B.A.T.M.A.N.] [PATCH 2/3] batctl: add support for gateway mode Marek Lindner
@ 2010-01-04 15:46     ` Marek Lindner
  2010-01-05  6:43       ` Andrew Lunn
  0 siblings, 1 reply; 17+ messages in thread
From: Marek Lindner @ 2010-01-04 15:46 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

If the gateway client mode is active batman-adv will send the broadcasted
DHCP requests via unicast to the currently selected best gateway. Therefore
attached clients can profit from batman's knowledge about the network
topology.

Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
 batman-adv-kernelland/gateway_client.c |   45 ++++++++++++++++++++++++++++++++
 batman-adv-kernelland/gateway_client.h |    2 +
 batman-adv-kernelland/soft-interface.c |   17 ++++++++++--
 3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/batman-adv-kernelland/gateway_client.c b/batman-adv-kernelland/gateway_client.c
index 55789ad..434af2b 100644
--- a/batman-adv-kernelland/gateway_client.c
+++ b/batman-adv-kernelland/gateway_client.c
@@ -20,6 +20,8 @@
 #include "main.h"
 #include "gateway_client.h"
 #include "gateway_common.h"
+#include <linux/ip.h>
+#include <linux/udp.h>
 
 LIST_HEAD(gw_list);
 DEFINE_SPINLOCK(curr_gw_lock);
@@ -27,6 +29,20 @@ DEFINE_SPINLOCK(gw_list_lock);
 atomic_t gw_clnt_class;
 static struct gw_node *curr_gateway;
 
+void *gw_get_selected(void)
+{
+	struct gw_node *curr_gateway_tmp = NULL;
+
+	spin_lock(&curr_gw_lock);
+	curr_gateway_tmp = curr_gateway;
+	spin_unlock(&curr_gw_lock);
+
+	if (!curr_gateway_tmp)
+		return NULL;
+
+	return curr_gateway_tmp->orig_node;
+}
+
 void gw_deselect(void)
 {
 	spin_lock(&curr_gw_lock);
@@ -333,3 +349,32 @@ int gw_client_fill_buffer_text(unsigned char *buff, int buff_len)
 
 	return bytes_written;
 }
+
+bool gw_is_target(struct sk_buff *skb)
+{
+	struct ethhdr *ethhdr;
+	struct iphdr *iphdr;
+	struct udphdr *udphdr;
+
+	if (atomic_read(&gw_mode) != GW_MODE_CLIENT)
+		return false;
+
+	if (!curr_gateway)
+		return false;
+
+	ethhdr = (struct ethhdr *)skb->data;
+	if (ntohs(ethhdr->h_proto) != ETH_P_IP)
+		return false;
+
+	iphdr = (struct iphdr *)(skb->data + ETH_HLEN);
+
+	if (iphdr->protocol != IPPROTO_UDP)
+		return false;
+
+	udphdr = (struct udphdr *)(skb->data + ETH_HLEN + (iphdr->ihl * 4));
+
+	if (ntohs(udphdr->dest) != 67)
+		return false;
+
+	return true;
+}
diff --git a/batman-adv-kernelland/gateway_client.h b/batman-adv-kernelland/gateway_client.h
index 5eb1e4c..fc7a0df 100644
--- a/batman-adv-kernelland/gateway_client.h
+++ b/batman-adv-kernelland/gateway_client.h
@@ -21,9 +21,11 @@ extern atomic_t gw_clnt_class;
 
 void gw_deselect(void);
 void gw_election(void);
+void *gw_get_selected(void);
 void gw_check_election(struct orig_node *orig_node);
 void gw_node_update(struct orig_node *orig_node, uint8_t new_gwflags);
 void gw_node_delete(struct orig_node *orig_node);
 void gw_node_purge_deleted(void);
 void gw_node_list_free(void);
 int gw_client_fill_buffer_text(unsigned char *buff, int buff_len);
+bool gw_is_target(struct sk_buff *skb);
diff --git a/batman-adv-kernelland/soft-interface.c b/batman-adv-kernelland/soft-interface.c
index ee9aa39..80f7a23 100644
--- a/batman-adv-kernelland/soft-interface.c
+++ b/batman-adv-kernelland/soft-interface.c
@@ -26,6 +26,7 @@
 #include "translation-table.h"
 #include "types.h"
 #include "hash.h"
+#include "gateway_client.h"
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
 #include "compat.h"
@@ -181,6 +182,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
 	uint8_t dstaddr[6];
 	int data_len = skb->len;
 	unsigned long flags;
+	bool bcast_dst = false, do_bcast = true;
 
 	if (atomic_read(&module_state) != MODULE_ACTIVE)
 		goto dropped;
@@ -189,9 +191,14 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
 	/* TODO: check this for locks */
 	hna_local_add(ethhdr->h_source);
 
-	/* ethernet packet should be broadcasted */
-	if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) {
+	if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest))
+		bcast_dst = true;
+
+	if ((bcast_dst) && gw_is_target(skb))
+		do_bcast = false;
 
+	/* ethernet packet should be broadcasted */
+	if (bcast_dst && do_bcast) {
 		if (my_skb_push(skb, sizeof(struct bcast_packet)) < 0)
 			goto dropped;
 
@@ -219,8 +226,12 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
 	/* unicast packet */
 	} else {
 		spin_lock_irqsave(&orig_hash_lock, flags);
+
 		/* get routing information */
-		orig_node = ((struct orig_node *)hash_find(orig_hash,
+		if (bcast_dst)
+			orig_node = (struct orig_node *)gw_get_selected();
+		else
+			orig_node = ((struct orig_node *)hash_find(orig_hash,
 							   ethhdr->h_dest));
 
 		/* check for hna host */
-- 
1.6.5.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
  2010-01-04 15:44 [B.A.T.M.A.N.] batman-adv gateway support Marek Lindner
  2010-01-04 15:46 ` [B.A.T.M.A.N.] [PATCH 1/3] batman-adv: adding gateway functionality Marek Lindner
@ 2010-01-04 16:48 ` predrag balorda
  2010-01-04 16:55   ` Sven Eckelmann
  2010-01-04 20:23 ` Donald Gordon
  2010-01-05  6:31 ` Andrew Lunn
  3 siblings, 1 reply; 17+ messages in thread
From: predrag balorda @ 2010-01-04 16:48 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

hi,

why can I not unsubscribe from this list?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
  2010-01-04 16:48 ` [B.A.T.M.A.N.] batman-adv gateway support predrag balorda
@ 2010-01-04 16:55   ` Sven Eckelmann
       [not found]     ` <de7865071001040856u1b661bdcxb319ffe60b2b367b@mail.gmail.com>
  0 siblings, 1 reply; 17+ messages in thread
From: Sven Eckelmann @ 2010-01-04 16:55 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: predrag balorda

[-- Attachment #1: Type: Text/Plain, Size: 294 bytes --]

predrag balorda wrote:
> predrag balorda <predrag.balorda@gmail.com>

You can. Just go to https://lists.open-mesh.net/mm/listinfo/b.a.t.m.a.n, enter 
your mail and click "Unsubscribe or edit options" -> "unsubscribe" and then 
reply to the mail you have received.

Best regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
       [not found]     ` <de7865071001040856u1b661bdcxb319ffe60b2b367b@mail.gmail.com>
@ 2010-01-04 17:02       ` Sven Eckelmann
  0 siblings, 0 replies; 17+ messages in thread
From: Sven Eckelmann @ 2010-01-04 17:02 UTC (permalink / raw)
  To: predrag balorda; +Cc: b.a.t.m.a.n

[-- Attachment #1: Type: Text/Plain, Size: 214 bytes --]

predrag balorda wrote:
> I've done it 3 times in the last few days and nothing ever happened.
> Just as I wrote to the list a removal confirmation arrived.

Yes, I did it for you as explained.

Best regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
  2010-01-04 15:44 [B.A.T.M.A.N.] batman-adv gateway support Marek Lindner
  2010-01-04 15:46 ` [B.A.T.M.A.N.] [PATCH 1/3] batman-adv: adding gateway functionality Marek Lindner
  2010-01-04 16:48 ` [B.A.T.M.A.N.] batman-adv gateway support predrag balorda
@ 2010-01-04 20:23 ` Donald Gordon
  2010-01-04 20:58   ` Andrew Lunn
  2010-01-04 21:45   ` Linus Lüssing
  2010-01-05  6:31 ` Andrew Lunn
  3 siblings, 2 replies; 17+ messages in thread
From: Donald Gordon @ 2010-01-04 20:23 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

[-- Attachment #1: Type: text/plain, Size: 612 bytes --]

Hi

On Tue, Jan 5, 2010 at 4:44 AM, Marek Lindner <lindner_marek@yahoo.de>wrote:

>
> * The third patch checks whether locally received packets are DHCP queries
> and
> forwards them via uncicast to the best gateway instead of broadcasting
> them.
>
> Would it be possible to decide via a more general mechanism, maybe via a
BPF filter, which packets get sent to the gateway?  For instance, it would
be nice to be able to say that all ARP requests for *.*.*.1 also got sent to
the gateway direct :-)  This would also make adding IPv6 support trivial,
it'd just be another (or a more complex) BPF filter.

donald

[-- Attachment #2: Type: text/html, Size: 904 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
  2010-01-04 20:23 ` Donald Gordon
@ 2010-01-04 20:58   ` Andrew Lunn
  2010-01-04 21:20     ` Donald Gordon
  2010-01-04 21:45   ` Linus Lüssing
  1 sibling, 1 reply; 17+ messages in thread
From: Andrew Lunn @ 2010-01-04 20:58 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

> Would it be possible to decide via a more general mechanism, maybe via a
> BPF filter, which packets get sent to the gateway?  For instance, it would
> be nice to be able to say that all ARP requests for *.*.*.1 also got sent to
> the gateway direct :-)  This would also make adding IPv6 support trivial,
> it'd just be another (or a more complex) BPF filter.

BPF for outgoing packets? Different. I've only ever seen it used for
filtering incoming packets. ARP requests for *.*.*.1? I don't get
that. There should only be one host in the subnet which matches
*.*.*.1/24, so its going to reply anyway. What are you trying to
achieve here?

Also, how would you handle the gateway sending back an ICMP redirect
because it is the wrong gateway for a given destination, or not a
gateway at all? In the network i use most, *.*.*.5/24 happens to be
the gateway, not *.*.*.1. 

    Andrew

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
  2010-01-04 20:58   ` Andrew Lunn
@ 2010-01-04 21:20     ` Donald Gordon
  0 siblings, 0 replies; 17+ messages in thread
From: Donald Gordon @ 2010-01-04 21:20 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

[-- Attachment #1: Type: text/plain, Size: 1000 bytes --]

On Tue, Jan 5, 2010 at 9:58 AM, Andrew Lunn <andrew@lunn.ch> wrote:

>
> BPF for outgoing packets? Different. I've only ever seen it used for
> filtering incoming packets. ARP requests for *.*.*.1? I don't get
> that. There should only be one host in the subnet which matches
> *.*.*.1/24, so its going to reply anyway. What are you trying to
> achieve here?
>

BPF because it's already in the kernel and has a rule language.  Rules to
match "all DHCP packets, and IPv6 router solicitations" are easy to write,
and people who want to do something different/wierd don't need to rebuild
their kernels.

If it makes any more sense, substitute *.*.*.1 for "something matching the
IPs I use for gateways".  Aim: make it harder for people to configure their
PCs to respond to those ARPs and break the network.  Although for a mobile
node whose DHCP lease hasn't yet expired I can see that causing problems.
But if it's just a BPF filter then you can experiment with rules like these
fairly easily.

donald

[-- Attachment #2: Type: text/html, Size: 1356 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
  2010-01-04 20:23 ` Donald Gordon
  2010-01-04 20:58   ` Andrew Lunn
@ 2010-01-04 21:45   ` Linus Lüssing
  2010-01-04 22:27     ` Donald Gordon
  1 sibling, 1 reply; 17+ messages in thread
From: Linus Lüssing @ 2010-01-04 21:45 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

Hi,

despite the general, internal filtering rules it would be great to
be able to fetch the best gateway (the gateway with the best
BTM-TQ value) via /proc. So people would have the chance to use
the basic gatewaying feature with just a switch in batman-adv,
while people that want to do more complex filtering could fetch it
from /proc and use ebtables on top for example. Maybe even a
sorted list of all gateways in /proc would be nice to be able to
set up some more advanced (fall-back) scenarios with other
measuring methods/tools. And on the other hand we'd have the
possibility of batman-adv not interfering too much with the other
layers, instead tools explicitly designed for layer 2, 3, ...
have an interface to fetch the gateway information then which only
batman-adv knew before.
I think I've been talking about this partly with Marek a couple of
weeks ago before.

Cheers, Linus

On Tue, Jan 05, 2010 at 09:23:42AM +1300, Donald Gordon wrote:
> Hi
> 
> On Tue, Jan 5, 2010 at 4:44 AM, Marek Lindner <lindner_marek@yahoo.de>wrote:
> 
> >
> > * The third patch checks whether locally received packets are DHCP queries
> > and
> > forwards them via uncicast to the best gateway instead of broadcasting
> > them.
> >
> > Would it be possible to decide via a more general mechanism, maybe via a
> BPF filter, which packets get sent to the gateway?  For instance, it would
> be nice to be able to say that all ARP requests for *.*.*.1 also got sent to
> the gateway direct :-)  This would also make adding IPv6 support trivial,
> it'd just be another (or a more complex) BPF filter.
> 
> donald

> _______________________________________________
> B.A.T.M.A.N mailing list
> B.A.T.M.A.N@lists.open-mesh.net
> https://lists.open-mesh.net/mm/listinfo/b.a.t.m.a.n


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
  2010-01-04 21:45   ` Linus Lüssing
@ 2010-01-04 22:27     ` Donald Gordon
  0 siblings, 0 replies; 17+ messages in thread
From: Donald Gordon @ 2010-01-04 22:27 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

[-- Attachment #1: Type: text/plain, Size: 853 bytes --]

Hi

On Tue, Jan 5, 2010 at 10:45 AM, Linus Lüssing <linus.luessing@web.de>wrote:

> Maybe even a
> sorted list of all gateways in /proc would be nice to be able to
> set up some more advanced (fall-back) scenarios with other
> measuring methods/tools. And on the other hand we'd have the
> possibility of batman-adv not interfering too much with the other
> layers, instead tools explicitly designed for layer 2, 3, ...
> have an interface to fetch the gateway information then which only
> batman-adv knew before.


That would be even better than what I was suggesting.  It would, among other
things, make it easy (with the addition of some sort of directory in
userspace, or redefining the gateway flags) to find the closest node(s) with
some particular service.  I'm thinking of things like "all squids that are
nearby".

donald

[-- Attachment #2: Type: text/html, Size: 1146 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
  2010-01-04 15:44 [B.A.T.M.A.N.] batman-adv gateway support Marek Lindner
                   ` (2 preceding siblings ...)
  2010-01-04 20:23 ` Donald Gordon
@ 2010-01-05  6:31 ` Andrew Lunn
  2010-01-05  9:50   ` Marek Lindner
  3 siblings, 1 reply; 17+ messages in thread
From: Andrew Lunn @ 2010-01-05  6:31 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

> * The third patch checks whether locally received packets are DHCP
> queries and forwards them via uncicast to the best gateway instead
> of broadcasting them.

Can this be made a bit more robust? An easy DoS would be to offer to
be a gateway, but not run DHCP. All my near neighbours then fail to
get an IP address and i have quiet network with more bandwidth for
myself.

Could we inspect the DHCP packet a bit more deeply, look for DHCP
discovery packets, unicast 3 in 4 to the best gateway, broadcast 1 in
4 as a fallback.

  Andrew

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] [PATCH 3/3] batman-adv: send DHCP requests directly to the chosen gw
  2010-01-04 15:46     ` [B.A.T.M.A.N.] [PATCH 3/3] batman-adv: send DHCP requests directly to the chosen gw Marek Lindner
@ 2010-01-05  6:43       ` Andrew Lunn
  2010-01-05 10:00         ` Marek Lindner
  0 siblings, 1 reply; 17+ messages in thread
From: Andrew Lunn @ 2010-01-05  6:43 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking; +Cc: Marek Lindner

> +bool gw_is_target(struct sk_buff *skb)
> +{
> +	struct ethhdr *ethhdr;
> +	struct iphdr *iphdr;
> +	struct udphdr *udphdr;
> +
> +	if (atomic_read(&gw_mode) != GW_MODE_CLIENT)
> +		return false;
> +
> +	if (!curr_gateway)
> +		return false;
> +
> +	ethhdr = (struct ethhdr *)skb->data;
> +	if (ntohs(ethhdr->h_proto) != ETH_P_IP)
> +		return false;
> +
> +	iphdr = (struct iphdr *)(skb->data + ETH_HLEN);
> +
> +	if (iphdr->protocol != IPPROTO_UDP)
> +		return false;
> +
> +	udphdr = (struct udphdr *)(skb->data + ETH_HLEN + (iphdr->ihl * 4));
> +
> +	if (ntohs(udphdr->dest) != 67)
> +		return false;
> +
> +	return true;
> +}
> -	/* ethernet packet should be broadcasted */
> -	if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) {
> +	if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest))
> +		bcast_dst = true;
> +
> +	if ((bcast_dst) && gw_is_target(skb))
> +		do_bcast = false;

Say the DHCP server is running in client mode. It has also been
requested to broadcast its replies, not unicast the replies.

http://blogs.technet.com/teamdhcp/archive/2009/02/12/dhcp-broadcast-flag-handling-in-windows-7.aspx

If i'm reading this code correctly, it will end up sending the DHCP
reply messages by unicast to the best gateway, not the DHCP client?

      Andrew

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] batman-adv gateway support
  2010-01-05  6:31 ` Andrew Lunn
@ 2010-01-05  9:50   ` Marek Lindner
  0 siblings, 0 replies; 17+ messages in thread
From: Marek Lindner @ 2010-01-05  9:50 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Tuesday 05 January 2010 14:31:46 Andrew Lunn wrote:
> Can this be made a bit more robust? An easy DoS would be to offer to
> be a gateway, but not run DHCP. All my near neighbours then fail to
> get an IP address and i have quiet network with more bandwidth for
> myself.

Good point. Before I had another scheme in mind: DHCP requests are broadcasted 
but the batman-adv client would filter the responses preferring the selected 
gateway if its reply is available. Of course, that is more complex to 
implement.


> Could we inspect the DHCP packet a bit more deeply, look for DHCP
> discovery packets, unicast 3 in 4 to the best gateway, broadcast 1 in
> 4 as a fallback.

I'm not sure this approach is feasible. As soon as we broadcast a single 
packet we might end up with a badly chosen gateway.

The batman daemon is able to blacklist broken gateways and switches to another 
one. We may want to do the same.

Regards,
Marek

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] [PATCH 3/3] batman-adv: send DHCP requests directly to the chosen gw
  2010-01-05  6:43       ` Andrew Lunn
@ 2010-01-05 10:00         ` Marek Lindner
  2010-01-05 11:09           ` Andrew Lunn
  0 siblings, 1 reply; 17+ messages in thread
From: Marek Lindner @ 2010-01-05 10:00 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Tuesday 05 January 2010 14:43:49 you wrote:
> Say the DHCP server is running in client mode. It has also been
> requested to broadcast its replies, not unicast the replies.
> 
> http://blogs.technet.com/teamdhcp/archive/2009/02/12/dhcp-broadcast-flag-ha
> ndling-in-windows-7.aspx
> 
> If i'm reading this code correctly, it will end up sending the DHCP
> reply messages by unicast to the best gateway, not the DHCP client?

I don't really get your question.
The batman-adv gwclient will encapsulate the DHCP discover / request packets 
in ethernet unicast headers instead of broadcast headers to make sure only the 
best gateway receives these broadcasts.
The server's replies won't be affected at all.

Regards,
Marek

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [B.A.T.M.A.N.] [PATCH 3/3] batman-adv: send DHCP requests directly to the chosen gw
  2010-01-05 10:00         ` Marek Lindner
@ 2010-01-05 11:09           ` Andrew Lunn
  0 siblings, 0 replies; 17+ messages in thread
From: Andrew Lunn @ 2010-01-05 11:09 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

> On Tuesday 05 January 2010 14:43:49 you wrote:
> > Say the DHCP server is running in client mode. It has also been
> > requested to broadcast its replies, not unicast the replies.
> >
> > http://blogs.technet.com/teamdhcp/archive/2009/02/12/dhcp-broadcast-flag-ha
> > ndling-in-windows-7.aspx
> >
> > If i'm reading this code correctly, it will end up sending the DHCP
> > reply messages by unicast to the best gateway, not the DHCP client?
>
> I don't really get your question.
> The batman-adv gwclient will encapsulate the DHCP discover / request packets
> in ethernet unicast headers instead of broadcast headers to make sure only the
> best gateway receives these broadcasts.
> The server's replies won't be affected at all.

Ah, just read the RFC. I though the client was free to choose its
port, so it could choose port 67. If that was true, gw_is_target()
would return true for the reply and the reply would then be sent to
the gateway.

However, the RFC says the client must use port 68, so this can never
happen. So there is no problem here...

        Andrew

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2010-01-05 11:09 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-04 15:44 [B.A.T.M.A.N.] batman-adv gateway support Marek Lindner
2010-01-04 15:46 ` [B.A.T.M.A.N.] [PATCH 1/3] batman-adv: adding gateway functionality Marek Lindner
2010-01-04 15:46   ` [B.A.T.M.A.N.] [PATCH 2/3] batctl: add support for gateway mode Marek Lindner
2010-01-04 15:46     ` [B.A.T.M.A.N.] [PATCH 3/3] batman-adv: send DHCP requests directly to the chosen gw Marek Lindner
2010-01-05  6:43       ` Andrew Lunn
2010-01-05 10:00         ` Marek Lindner
2010-01-05 11:09           ` Andrew Lunn
2010-01-04 16:48 ` [B.A.T.M.A.N.] batman-adv gateway support predrag balorda
2010-01-04 16:55   ` Sven Eckelmann
     [not found]     ` <de7865071001040856u1b661bdcxb319ffe60b2b367b@mail.gmail.com>
2010-01-04 17:02       ` Sven Eckelmann
2010-01-04 20:23 ` Donald Gordon
2010-01-04 20:58   ` Andrew Lunn
2010-01-04 21:20     ` Donald Gordon
2010-01-04 21:45   ` Linus Lüssing
2010-01-04 22:27     ` Donald Gordon
2010-01-05  6:31 ` Andrew Lunn
2010-01-05  9:50   ` Marek Lindner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox