Re: [B.A.T.M.A.N.] BATMAN routing
by Sven Eckelmann
On Monday 07 March 2011 22:00:25 hlabishi kobo wrote:
> Linus suggested to me that i should print the window and see how it
> looks, I did that and it returns this ef0fffffe, ffbffff, f70fffff,
> eb1b53c0, eb3950b8, eb1749c0. I am not sure if this are hexadecimal
> number or what.
I would think that you wrote the part which prints out this values. This means
that you know which parameters you gave printk and that you should know the
conversation specifiers and length modifiers that you used in the format
string.
But I would guess without having any of these information that you used %x to
print these values. Whatever you used as argument - 32 bit (size of single
int) of it were printed in unsigned in hexidecimal notation. Maybe you should
think about using %lx to print unsigned long ints in hexidecimal notation in
case you really used %x.
Which brings me to another question: Why to I see 6 numbers in your post and
why has the first one 9 nibbles?
As said before (and also recommended by Linus): try to write a small c program
which uses these values, print the single bits, try to write some test
algorithm using these decoded bits and play a little bit around with other
test inputs before trying random things inside the kernel.
> Again this is the results of printing seq_bits, so far
> i have not been able to print real_bits as this cannot even make a
> network ping. Could you enlighten me in this case.
I cannot understand how pings and printks are related...
May I ask how these things are related to your work/studies? It is ok to play
around a little bit as small side project/hobby without having the time and
knowledge to understand what you are really doing. That is usually a good way
to find new interesting topics and maybe to learn something (or blow up a
building...). But I would highly recommend to switch the topic in case this is
part of your thesis or work.
It is not meant as harsh criticism of what you try to do, but it seems that
right now you aren't able to efficiently work with it and to gain enough
knowledge by yourself to be able to understand simple parts the thing you are
working with.
Best regards,
Sven
11 years, 9 months
[B.A.T.M.A.N.] [PATCH 1/2] batctl: Remove obsolete creation of source packages
by Sven Eckelmann
The creation of source packages is now either done by the release team
using special scripts or through gitweb. It is not needed to provide the
source target inside the Makefile and may not work in the future anyway.
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
---
Makefile | 19 -------------------
1 files changed, 0 insertions(+), 19 deletions(-)
diff --git a/Makefile b/Makefile
index a992e89..b5b4e2b 100644
--- a/Makefile
+++ b/Makefile
@@ -69,11 +69,8 @@ REVISION= $(shell if [ -d .svn ]; then \
REVISION_VERSION =\"\ $(REVISION)\"
-BAT_VERSION = $(shell grep "^\#define SOURCE_VERSION " $(SOURCE_VERSION_HEADER) | sed -e '1p' -n | awk -F '"' '{print $$2}' | awk '{print $$1}')
-FILE_NAME = $(PACKAGE_NAME)_$(BAT_VERSION)-rv$(REVISION)_$@
NUM_CPUS = $(shell nproc 2> /dev/null || echo 1)
-
all:
$(MAKE) -j $(NUM_CPUS) $(BINARY_NAME)
@@ -84,25 +81,9 @@ $(BINARY_NAME): $(SRC_O) $(SRC_H) Makefile
$(Q_CC)$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -MD -c $< -o $@
-include $(SRC_C:.c=.d)
-sources:
- mkdir -p $(FILE_NAME)
-
- for i in $$( find . | grep $(SRC_FILES) | grep -v "\.svn" ); do [ -d $$i ] && mkdir -p $(FILE_NAME)/$$i ; [ -f $$i ] && cp -Lvp $$i $(FILE_NAME)/$$i ;done
-
- wget -O changelog.html http://www.open-mesh.net/log/$(LOG_BRANCH)/
- html2text -o changelog.txt -nobs -ascii changelog.html
- awk '/View revision/,/10\/01\/06 20:23:03/' changelog.txt > $(FILE_NAME)/CHANGELOG
-
- for i in $$( find man | grep -v "\.svn" ); do [ -f $$i ] && groff -man -Thtml $$i > $(FILE_NAME)/$$i.html ;done
-
- tar czvf $(FILE_NAME).tgz $(FILE_NAME)
-
clean:
rm -f $(BINARY_NAME) *.o *.d
-clean-long:
- rm -rf $(PACKAGE_NAME)_*
-
install:
mkdir -p $(SBINDIR)
install -m 0755 $(BINARY_NAME) $(SBINDIR)
--
1.7.4.1
11 years, 10 months
[B.A.T.M.A.N.] [PATCH] [batman-adv] Set the txqueuelen to zero when creating soft interface.
by Andrew Lunn
>From e03cb760a296b55138dd6507b5e676c22cecf37e Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew(a)lunn.ch>
Date: Mon, 21 Mar 2011 21:31:44 +0100
Subject: [PATCH] [batman-adv] Set the txqueuelen to zero when creating soft interface.
Like other virtual interfaces, e.g. br0, we don't need a transmit
queue. Packets should only be queued on real interfaces which are
underneath. In practice this patch makes little difference since the
virtual interfaces can accept packets as fast as they come, but the
patch will avoid bufferbloat questions to the mailling lists in the
future.
Signed-off-by: Andrew Lunn <andrew(a)lunn.ch>
Tested-by: Linus Luesing <linus.luessing(a)web.de>
---
soft-interface.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/soft-interface.c b/soft-interface.c
index 9ed2614..7230e33 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -524,6 +524,7 @@ static void interface_setup(struct net_device *dev)
dev->hard_start_xmit = interface_tx;
#endif
dev->destructor = free_netdev;
+ dev->tx_queue_len = 0;
/**
* can't call min_mtu, because the needed variables
--
1.7.4.1
11 years, 10 months
[B.A.T.M.A.N.] [PATCH] batman-adv: protect softif_neigh by rcu
by Simon Wunderlich
Add get/set wrapper functions for softif_neigh and
use rcu functions to manipulate the pointers.
Signed-off-by: Simon Wunderlich <siwu(a)hrz.tu-chemnitz.de>
---
soft-interface.c | 112 ++++++++++++++++++++++++++++++++++++++++++------------
types.h | 2 +-
2 files changed, 88 insertions(+), 26 deletions(-)
diff --git a/batman-adv/soft-interface.c b/batman-adv/soft-interface.c
index 9ed2614..624d922 100644
--- a/batman-adv/soft-interface.c
+++ b/batman-adv/soft-interface.c
@@ -90,11 +90,47 @@ static void softif_neigh_free_ref(struct softif_neigh *softif_neigh)
call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu);
}
+static struct softif_neigh *bat_priv_get_softif_neigh(struct bat_priv *bat_priv)
+{
+ struct softif_neigh *neigh;
+
+ rcu_read_lock();
+ neigh = rcu_dereference(bat_priv->softif_neigh);
+
+ if (neigh && !atomic_inc_not_zero(&neigh->refcount))
+ neigh = NULL;
+
+ rcu_read_unlock();
+ return neigh;
+}
+
+static void bat_priv_set_softif_neigh(struct bat_priv *bat_priv,
+ struct softif_neigh *new_neigh)
+{
+ struct softif_neigh *old_neigh;
+
+ rcu_read_lock();
+ old_neigh = rcu_dereference(bat_priv->softif_neigh);
+
+ /* increase softif neigh */
+ if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount))
+ new_neigh = NULL;
+
+ rcu_assign_pointer(bat_priv->softif_neigh, new_neigh);
+
+ if (old_neigh)
+ softif_neigh_free_ref(old_neigh);
+
+ rcu_read_unlock();
+}
+
void softif_neigh_purge(struct bat_priv *bat_priv)
{
- struct softif_neigh *softif_neigh, *softif_neigh_tmp;
+ struct softif_neigh *softif_neigh, *curr_softif_neigh;
struct hlist_node *node, *node_tmp;
+ curr_softif_neigh = bat_priv_get_softif_neigh(bat_priv);
+
spin_lock_bh(&bat_priv->softif_neigh_lock);
hlist_for_each_entry_safe(softif_neigh, node, node_tmp,
@@ -107,20 +143,25 @@ void softif_neigh_purge(struct bat_priv *bat_priv)
hlist_del_rcu(&softif_neigh->list);
- if (bat_priv->softif_neigh == softif_neigh) {
+ if (curr_softif_neigh == softif_neigh) {
bat_dbg(DBG_ROUTES, bat_priv,
"Current mesh exit point '%pM' vanished "
"(vid: %d).\n",
softif_neigh->addr, softif_neigh->vid);
- softif_neigh_tmp = bat_priv->softif_neigh;
- bat_priv->softif_neigh = NULL;
- softif_neigh_free_ref(softif_neigh_tmp);
+ bat_priv_set_softif_neigh(bat_priv, NULL);
+ if (curr_softif_neigh) {
+ /* for the local variable */
+ softif_neigh_free_ref(curr_softif_neigh);
+ curr_softif_neigh = NULL;
+ }
}
softif_neigh_free_ref(softif_neigh);
}
spin_unlock_bh(&bat_priv->softif_neigh_lock);
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
}
static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv,
@@ -171,6 +212,7 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct softif_neigh *softif_neigh;
struct hlist_node *node;
+ struct softif_neigh *curr_softif_neigh;
if (!bat_priv->primary_if) {
return seq_printf(seq, "BATMAN mesh %s disabled - "
@@ -180,14 +222,17 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
+ curr_softif_neigh = bat_priv_get_softif_neigh(bat_priv);
rcu_read_lock();
hlist_for_each_entry_rcu(softif_neigh, node,
&bat_priv->softif_neigh_list, list)
seq_printf(seq, "%s %pM (vid: %d)\n",
- bat_priv->softif_neigh == softif_neigh
+ curr_softif_neigh == softif_neigh
? "=>" : " ", softif_neigh->addr,
softif_neigh->vid);
rcu_read_unlock();
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
return 0;
}
@@ -198,7 +243,8 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
struct bat_priv *bat_priv = netdev_priv(dev);
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct batman_packet *batman_packet;
- struct softif_neigh *softif_neigh, *softif_neigh_tmp;
+ struct softif_neigh *softif_neigh;
+ struct softif_neigh *curr_softif_neigh = NULL;
if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
batman_packet = (struct batman_packet *)
@@ -223,7 +269,8 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
if (!softif_neigh)
goto err;
- if (bat_priv->softif_neigh == softif_neigh)
+ curr_softif_neigh = bat_priv_get_softif_neigh(bat_priv);
+ if (curr_softif_neigh == softif_neigh)
goto out;
/* we got a neighbor but its mac is 'bigger' than ours */
@@ -232,38 +279,45 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
goto out;
/* switch to new 'smallest neighbor' */
- if ((bat_priv->softif_neigh) &&
- (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr,
+ if ((curr_softif_neigh) &&
+ (memcmp(softif_neigh->addr, curr_softif_neigh->addr,
ETH_ALEN) < 0)) {
bat_dbg(DBG_ROUTES, bat_priv,
"Changing mesh exit point from %pM (vid: %d) "
"to %pM (vid: %d).\n",
- bat_priv->softif_neigh->addr,
- bat_priv->softif_neigh->vid,
+ curr_softif_neigh->addr,
+ curr_softif_neigh->vid,
softif_neigh->addr, softif_neigh->vid);
- softif_neigh_tmp = bat_priv->softif_neigh;
- bat_priv->softif_neigh = softif_neigh;
- softif_neigh_free_ref(softif_neigh_tmp);
- /* we need to hold the additional reference */
- goto err;
+
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
+ bat_priv_set_softif_neigh(bat_priv, softif_neigh);
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
+
+ goto out;
}
/* close own batX device and use softif_neigh as exit node */
- if ((!bat_priv->softif_neigh) &&
+ if ((!curr_softif_neigh) &&
(memcmp(softif_neigh->addr,
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) {
bat_dbg(DBG_ROUTES, bat_priv,
"Setting mesh exit point to %pM (vid: %d).\n",
softif_neigh->addr, softif_neigh->vid);
- bat_priv->softif_neigh = softif_neigh;
- /* we need to hold the additional reference */
- goto err;
+
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
+ bat_priv_set_softif_neigh(bat_priv, softif_neigh);
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
+
+ goto out;
}
out:
softif_neigh_free_ref(softif_neigh);
err:
kfree_skb(skb);
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
+
return;
}
@@ -321,6 +375,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
struct bat_priv *bat_priv = netdev_priv(soft_iface);
struct bcast_packet *bcast_packet;
struct vlan_ethhdr *vhdr;
+ struct softif_neigh *curr_softif_neigh = NULL;
int data_len = skb->len, ret;
short vid = -1;
bool do_bcast = false;
@@ -348,7 +403,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
* if we have a another chosen mesh exit node in range
* it will transport the packets to the mesh
*/
- if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid))
+ curr_softif_neigh = bat_priv_get_softif_neigh(bat_priv);
+ if ((curr_softif_neigh) && (curr_softif_neigh->vid == vid))
goto dropped;
/* TODO: check this for locks */
@@ -410,6 +466,8 @@ dropped:
dropped_freed:
bat_priv->stats.tx_dropped++;
end:
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
return NETDEV_TX_OK;
}
@@ -421,6 +479,7 @@ void interface_rx(struct net_device *soft_iface,
struct unicast_packet *unicast_packet;
struct ethhdr *ethhdr;
struct vlan_ethhdr *vhdr;
+ struct softif_neigh *curr_softif_neigh = NULL;
short vid = -1;
int ret;
@@ -450,7 +509,8 @@ void interface_rx(struct net_device *soft_iface,
* if we have a another chosen mesh exit node in range
* it will transport the packets to the non-mesh network
*/
- if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) {
+ curr_softif_neigh = bat_priv_get_softif_neigh(bat_priv);
+ if (curr_softif_neigh && (curr_softif_neigh->vid == vid)) {
skb_push(skb, hdr_size);
unicast_packet = (struct unicast_packet *)skb->data;
@@ -461,7 +521,7 @@ void interface_rx(struct net_device *soft_iface,
skb_reset_mac_header(skb);
memcpy(unicast_packet->dest,
- bat_priv->softif_neigh->addr, ETH_ALEN);
+ curr_softif_neigh->addr, ETH_ALEN);
ret = route_unicast_packet(skb, recv_if);
if (ret == NET_RX_DROP)
goto dropped;
@@ -486,11 +546,13 @@ void interface_rx(struct net_device *soft_iface,
soft_iface->last_rx = jiffies;
netif_rx(skb);
- return;
+ goto out;
dropped:
kfree_skb(skb);
out:
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
return;
}
diff --git a/batman-adv/types.h b/batman-adv/types.h
index 091476d..75123b1 100644
--- a/batman-adv/types.h
+++ b/batman-adv/types.h
@@ -147,7 +147,7 @@ struct bat_priv {
atomic_t batman_queue_left;
char num_ifaces;
struct hlist_head softif_neigh_list;
- struct softif_neigh *softif_neigh;
+ struct softif_neigh __rcu *softif_neigh;
struct debug_log *debug_log;
struct hard_iface *primary_if;
struct kobject *mesh_obj;
--
1.7.2.3
11 years, 10 months
[B.A.T.M.A.N.] [PATCH] batman-adv: concentrate all curr_gw related rcu operations in select/deselect functions
by Marek Lindner
Signed-off-by: Marek Lindner <lindner_marek(a)yahoo.de>
---
batman-adv/gateway_client.c | 166 +++++++++++++++++++++++++------------------
batman-adv/gateway_client.h | 2 +-
batman-adv/unicast.c | 2 +-
3 files changed, 98 insertions(+), 72 deletions(-)
diff --git a/batman-adv/gateway_client.c b/batman-adv/gateway_client.c
index 42a8a7b..5a0427a 100644
--- a/batman-adv/gateway_client.c
+++ b/batman-adv/gateway_client.c
@@ -43,39 +43,46 @@ static void gw_node_free_ref(struct gw_node *gw_node)
call_rcu(&gw_node->rcu, gw_node_free_rcu);
}
-struct orig_node *gw_get_selected(struct bat_priv *bat_priv)
+static struct gw_node *gw_get_selected_gw_node(struct bat_priv *bat_priv)
{
- struct gw_node *curr_gateway_tmp;
- struct orig_node *orig_node = NULL;
+ struct gw_node *gw_node;
rcu_read_lock();
- curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw);
- if (!curr_gateway_tmp)
- goto out;
-
- orig_node = curr_gateway_tmp->orig_node;
- if (!orig_node)
+ gw_node = rcu_dereference(bat_priv->curr_gw);
+ if (!gw_node)
goto out;
- if (!atomic_inc_not_zero(&orig_node->refcount))
- orig_node = NULL;
+ if (!atomic_inc_not_zero(&gw_node->refcount))
+ gw_node = NULL;
out:
rcu_read_unlock();
- return orig_node;
+ return gw_node;
}
-void gw_deselect(struct bat_priv *bat_priv)
+struct orig_node *gw_get_selected_orig(struct bat_priv *bat_priv)
{
struct gw_node *gw_node;
+ struct orig_node *orig_node = NULL;
- spin_lock_bh(&bat_priv->gw_list_lock);
- gw_node = rcu_dereference(bat_priv->curr_gw);
- rcu_assign_pointer(bat_priv->curr_gw, NULL);
- spin_unlock_bh(&bat_priv->gw_list_lock);
+ gw_node = gw_get_selected_gw_node(bat_priv);
+ if (!gw_node)
+ goto out;
+ rcu_read_lock();
+ orig_node = gw_node->orig_node;
+ if (!orig_node)
+ goto unlock;
+
+ if (!atomic_inc_not_zero(&orig_node->refcount))
+ orig_node = NULL;
+
+unlock:
+ rcu_read_unlock();
+out:
if (gw_node)
gw_node_free_ref(gw_node);
+ return orig_node;
}
static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
@@ -85,8 +92,11 @@ static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
new_gw_node = NULL;
- spin_lock_bh(&bat_priv->gw_list_lock);
+ rcu_read_lock();
curr_gw_node = rcu_dereference(bat_priv->curr_gw);
+ rcu_read_unlock();
+
+ spin_lock_bh(&bat_priv->gw_list_lock);
rcu_assign_pointer(bat_priv->curr_gw, new_gw_node);
spin_unlock_bh(&bat_priv->gw_list_lock);
@@ -94,10 +104,15 @@ static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
gw_node_free_ref(curr_gw_node);
}
+void gw_deselect(struct bat_priv *bat_priv)
+{
+ gw_select(bat_priv, NULL);
+}
+
void gw_election(struct bat_priv *bat_priv)
{
struct hlist_node *node;
- struct gw_node *gw_node, *curr_gw, *curr_gw_tmp = NULL;
+ struct gw_node *gw_node, *curr_gw = NULL, *curr_gw_tmp = NULL;
struct neigh_node *router;
uint8_t max_tq = 0;
uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
@@ -112,25 +127,17 @@ void gw_election(struct bat_priv *bat_priv)
if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT)
return;
- rcu_read_lock();
- curr_gw = rcu_dereference(bat_priv->curr_gw);
- if (curr_gw) {
- rcu_read_unlock();
- return;
- }
+ curr_gw = gw_get_selected_gw_node(bat_priv);
+ if (!curr_gw)
+ goto out;
+ rcu_read_lock();
if (hlist_empty(&bat_priv->gw_list)) {
-
- if (curr_gw) {
- rcu_read_unlock();
- bat_dbg(DBG_BATMAN, bat_priv,
- "Removing selected gateway - "
- "no gateway in range\n");
- gw_deselect(bat_priv);
- } else
- rcu_read_unlock();
-
- return;
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Removing selected gateway - "
+ "no gateway in range\n");
+ gw_deselect(bat_priv);
+ goto unlock;
}
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
@@ -182,7 +189,7 @@ void gw_election(struct bat_priv *bat_priv)
if (curr_gw != curr_gw_tmp) {
router = orig_node_get_router(curr_gw_tmp->orig_node);
if (!router)
- goto out;
+ goto unlock;
if ((curr_gw) && (!curr_gw_tmp))
bat_dbg(DBG_BATMAN, bat_priv,
@@ -207,8 +214,11 @@ void gw_election(struct bat_priv *bat_priv)
gw_select(bat_priv, curr_gw_tmp);
}
-out:
+unlock:
rcu_read_unlock();
+out:
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
}
void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
@@ -217,7 +227,7 @@ void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
struct neigh_node *router_gw = NULL, *router_orig = NULL;
uint8_t gw_tq_avg, orig_tq_avg;
- curr_gw_orig = gw_get_selected(bat_priv);
+ curr_gw_orig = gw_get_selected_orig(bat_priv);
if (!curr_gw_orig)
goto deselect;
@@ -299,7 +309,11 @@ void gw_node_update(struct bat_priv *bat_priv,
struct orig_node *orig_node, uint8_t new_gwflags)
{
struct hlist_node *node;
- struct gw_node *gw_node;
+ struct gw_node *gw_node, *curr_gw;
+
+ curr_gw = gw_get_selected_gw_node(bat_priv);
+ if (!curr_gw)
+ goto out;
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
@@ -320,22 +334,25 @@ void gw_node_update(struct bat_priv *bat_priv,
"Gateway %pM removed from gateway list\n",
orig_node->orig);
- if (gw_node == rcu_dereference(bat_priv->curr_gw)) {
- rcu_read_unlock();
- gw_deselect(bat_priv);
- return;
- }
+ if (gw_node == curr_gw)
+ goto deselect;
}
- rcu_read_unlock();
- return;
+ goto out;
}
- rcu_read_unlock();
if (new_gwflags == 0)
- return;
+ goto out;
gw_node_add(bat_priv, orig_node, new_gwflags);
+ goto out;
+
+deselect:
+ gw_deselect(bat_priv);
+out:
+ rcu_read_unlock();
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
}
void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
@@ -345,9 +362,12 @@ void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
void gw_node_purge(struct bat_priv *bat_priv)
{
- struct gw_node *gw_node;
+ struct gw_node *gw_node, *curr_gw;
struct hlist_node *node, *node_tmp;
unsigned long timeout = 2 * PURGE_TIMEOUT * HZ;
+ char do_deselect = 0;
+
+ curr_gw = gw_get_selected_gw_node(bat_priv);
spin_lock_bh(&bat_priv->gw_list_lock);
@@ -358,15 +378,21 @@ void gw_node_purge(struct bat_priv *bat_priv)
atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)
continue;
- if (rcu_dereference(bat_priv->curr_gw) == gw_node)
- gw_deselect(bat_priv);
+ if (curr_gw == gw_node)
+ do_deselect = 1;
hlist_del_rcu(&gw_node->list);
gw_node_free_ref(gw_node);
}
-
spin_unlock_bh(&bat_priv->gw_list_lock);
+
+ /* gw_deselect() needs to acquire the gw_list_lock */
+ if (do_deselect)
+ gw_deselect(bat_priv);
+
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
}
/**
@@ -385,22 +411,22 @@ static int _write_buffer_text(struct bat_priv *bat_priv,
if (!router)
goto out;
- rcu_read_lock();
- curr_gw = rcu_dereference(bat_priv->curr_gw);
+ curr_gw = gw_get_selected_gw_node(bat_priv);
ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n",
- (curr_gw == gw_node ? "=>" : " "),
- gw_node->orig_node->orig,
- router->tq_avg, router->addr,
- router->if_incoming->net_dev->name,
- gw_node->orig_node->gw_flags,
- (down > 2048 ? down / 1024 : down),
- (down > 2048 ? "MBit" : "KBit"),
- (up > 2048 ? up / 1024 : up),
- (up > 2048 ? "MBit" : "KBit"));
+ (curr_gw == gw_node ? "=>" : " "),
+ gw_node->orig_node->orig,
+ router->tq_avg, router->addr,
+ router->if_incoming->net_dev->name,
+ gw_node->orig_node->gw_flags,
+ (down > 2048 ? down / 1024 : down),
+ (down > 2048 ? "MBit" : "KBit"),
+ (up > 2048 ? up / 1024 : up),
+ (up > 2048 ? "MBit" : "KBit"));
- rcu_read_unlock();
neigh_node_free_ref(router);
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
out:
return ret;
}
@@ -459,6 +485,7 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
struct iphdr *iphdr;
struct ipv6hdr *ipv6hdr;
struct udphdr *udphdr;
+ struct gw_node *curr_gw;
unsigned int header_len = 0;
if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
@@ -523,12 +550,11 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
return -1;
- rcu_read_lock();
- if (!rcu_dereference(bat_priv->curr_gw)) {
- rcu_read_unlock();
+ curr_gw = gw_get_selected_gw_node(bat_priv);
+ if (!curr_gw)
return 0;
- }
- rcu_read_unlock();
+ if (curr_gw)
+ gw_node_free_ref(curr_gw);
return 1;
}
diff --git a/batman-adv/gateway_client.h b/batman-adv/gateway_client.h
index 97c31d1..1ce8c60 100644
--- a/batman-adv/gateway_client.h
+++ b/batman-adv/gateway_client.h
@@ -24,7 +24,7 @@
void gw_deselect(struct bat_priv *bat_priv);
void gw_election(struct bat_priv *bat_priv);
-struct orig_node *gw_get_selected(struct bat_priv *bat_priv);
+struct orig_node *gw_get_selected_orig(struct bat_priv *bat_priv);
void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node);
void gw_node_update(struct bat_priv *bat_priv,
struct orig_node *orig_node, uint8_t new_gwflags);
diff --git a/batman-adv/unicast.c b/batman-adv/unicast.c
index 19f84bd..d46acc8 100644
--- a/batman-adv/unicast.c
+++ b/batman-adv/unicast.c
@@ -289,7 +289,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
/* get routing information */
if (is_multicast_ether_addr(ethhdr->h_dest)) {
- orig_node = (struct orig_node *)gw_get_selected(bat_priv);
+ orig_node = (struct orig_node *)gw_get_selected_orig(bat_priv);
if (orig_node)
goto find_router;
}
--
1.7.2.3
11 years, 10 months
[B.A.T.M.A.N.] Modification of BATMAN IV's route selection algorithm
by Matthew Britton
Hi,
We have just completed a brief research project looking at the performance
of BATMAN IV in a MANET with directional antennas. We've augmenting BATMAN's
route selection algorithm with a simple hysteresis mechanism called
"Batrytis" to reduce route-flapping in some circumstances. Please find
attached an initial technical report describing our work. You are welcome to
publish this on your site if you wish, and any feedback would also be
welcome. We have as yet not published this work, although it may be modified
into a conference paper later in the year. We probably will not have time to
extend this work although there are clearly many issues that could be
explored further.
Best regards,
Matt
Dr. Matthew Britton
Senior Analyst
Teletraffic Research Centre
Office 5.18, Level 5, Innova21 Building, North Terrace, Adelaide
Mobile: +61 (0) 404 384 221
Landline: +61 (8) 8313 0565
E-mail: matthew.britton(a)adelaide.edu.au
11 years, 10 months
Re: [B.A.T.M.A.N.] UDP multicast
by Simon Wunderlich
Hello Olivier,
yes, batman advanced (note, not the layer 3 BATMAN) supports multicast. It
behaves like a (rather lossy) Ethernet interface and transports multicast
traffic just like broadcast. For broadcast, we use a "classic flooding"
approach, which means that every message is rebroadcasted by every node
once when heard first. This "works" also for UDP multicast traffic,
but is not designed for high bandwidth multicast/broadcast data.
Linus and me are working on an optimization for multicast which is currently
in an experimental stage, which may also be better suited for your application.
However, I don't know whether LCM works on lossy networks and which bandwidth
requirements it has. Also note that the optimization is not "deployment ready"
yet. ;)
A few pointers to get started:
Quick Start Guide: http://www.open-mesh.org/wiki/batman-adv/Quick-start-guide
First Announcement of Multicast Optimization (Specification attached):
https://lists.open-mesh.org/pipermail/b.a.t.m.a.n/2010-December/003858.html
best regards,
Simon
On Thu, Mar 24, 2011 at 07:42:21PM +0000, Toupet, Olivier wrote:
> Hello,
>
> I am considering using the Lightweight Communications and Marshalling (LCM) library recently developed at MIT: http://code.google.com/p/lcm/ . However, that library relies on UDP multicast and I need it to work for mesh networks. I have only used simple UDP in the past with B.A.T.M.A.N. and I was wondering if my applications would still work with B.A.T.M.A.N. if I went with UDP multicast. Doing a little bit of research on the web seems to indicate that the UDP packets would be treated like broadcast packets and would then be flooded in the network, which doesn't seem efficient bandwidth-wise. Is that really the case? Would B.A.T.M.A.N. work with LCM (i.e. UDP multicast)? Is there documentation that explains how to set up B.A.T.M.A.N. for UDP multicast?
>
> Thanks in advance for your reply.
>
> Best regards,
>
> Olivier
11 years, 10 months
[B.A.T.M.A.N.] B.A.T.M.A.N. @Google Summer of Code 2011
by Linus Lüssing
*** Google Summer of Code 2011 ***
Since last Monday the student application period for the Google
Summer of Code 2011 has opened. A chance for any student to get
their hands dirty on their favorite OpenSource project and getting
its development process and code base to know better during these
2 months - while getting payed for it! And guess what? This year,
you can play with Batman - ehh, B.A.T.M.A.N. Anyways, they both
want to save the world of course ;).
As the application of OpenMesh as a mentoring organization was
sadly rejected last year, we decided and agreed on applying via
Freifunk this year, which serves as an umbrella organization for
various projects dealing with wireless mesh networks.
If you are interested in mesh networking and B.A.T.M.A.N. and if
you also love OpenSource software and would like to become a more
firm part of it, then get in touch with us via mailinglist and/or
IRC. So far the following ideas have been collected which you may
apply for:
http://wiki.freifunk.net/Ideas#B.A.T.M.A.N.
But feel free to tell us your own suggestions and ideas, too.
***** ****
*** Student application deadline is the 8th of April!! ***
**** *****
- GSoC timeline:
http://www.google-melange.com/document/show/gsoc_program/google/gsoc2011/...
- Student Check List:
http://wiki.freifunk.net/Student_Check_List
- Freifunk GSoC Page:
http://www.google-melange.com/gsoc/org/show/google/gsoc2011/freifunk
Happy routing,
The B.A.T.M.A.N. team
11 years, 10 months
Re: [B.A.T.M.A.N.] TTL yes, TTL no
by Antonio Quartulli
On Sat, Mar 26, 2011 at 06:45:48PM +0100, Andrew Lunn wrote:
> > I think it is wrong: TQ is not decremented by hop_penalty each time, but it is
> > multiplied by (TQ_MAX-hop_penalty/TQ_MAX), then the number of hops is
> > bigger than what you said. With hop_penalty = 10 we can probably reach
> > ~135 hops (raw calculus 255*(TQ_MAX-hop_penalty/TQ_MAX)^135) =~ 0)
>
> I agree with the principle. However, you need to take rounding into
> effect. The kernel does integer arithmetic and TQ is always an integer
> value. I also got it wrong in my last post. I used the wrong round
> function when calculating the values. Using rounddown() i get:
>
[cut]
>
> After 73 hops, TQ will be zero.
You are right, my raw calculus was too raw :p
>
> > Looking at the calculus above, I'm proposing to use TTL = ~135
>
> TTL of 73 would be more accurate i think.
Yes.
>
> Which leads me to a new question. At WBM we talked about moving the
> HNAs out of the OGMs. If we had a really big mesh, with more than 73
> hops from side to side, do we get into a situation where we have HNAs
> from more than 73 hops away, but no idea how to route to them since
> OGMs got dropped when TQ reached 0?
>
Mh..The HNA request is triggered by the TTVN carried into the OGM. Then a node
far more than 73 hops should never ask for HNAs it cannot reach..
Moreover, a route toward a client is never allocated if we don't have
its orig_node in our DB.
Bye
--
Antonio Quartulli
..each of us alone is worth nothing..
Ernesto "Che" Guevara
11 years, 10 months
Re: [B.A.T.M.A.N.] TTL yes, TTL no
by Antonio Quartulli
Hello,
On sab, mar 26, 2011 at 04:31:42 +0100, Marek Lindner wrote:
>
> Hi,
>
> > In these days I was wondering whether the TTL field in the OGM packet is
> > really useful or not...Due to hop_penalty an OGM will be discarded as
> > soon as the TQ will reach 0 (which is a sort of TTL mechanism itself).
> > At this point why is the TTL field needed?
>
> uhm.., you probably are right. As long as there is a hop penalty it also
> functions as a TTL. Keep in mind that it is possible to set the hop penalty to
> zero. With the current default hop penalty of 10 the maximum number of hops is
> limited to 25.
I think it is wrong: TQ is not decremented by hop_penalty each time, but it is
multiplied by (TQ_MAX-hop_penalty/TQ_MAX), then the number of hops is
bigger than what you said. With hop_penalty = 10 we can probably reach
~135 hops (raw calculus 255*(TQ_MAX-hop_penalty/TQ_MAX)^135) =~ 0)
>
>
> > Someone could probably say that a node far at least TTL hops will never
> > be reached by a unicast packet, then it is meaningless to let it know
> > about me. But then it could be possible to recalibrate the TTL such that
> > it has to be equal to the maximum length in number of hops of the longest
> > path the OGM can traverse.
>
> Not quite sure what you are proposing. A TTL of TQ_MAX / hop penalty ?
>
Looking at the calculus above, I'm proposing to use TTL = ~135
Bye!
--
Antonio Quartulli
..each of us alone is worth nothing..
Ernesto "Che" Guevara
11 years, 10 months