Re: [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Write lockdep xmit class in late initialization phase

2012-08-30 Thread Antonio Quartulli
On Mon, Aug 27, 2012 at 10:53:50AM +0200, Sven Eckelmann wrote:
 e27bb6fa916451e9eaced16e7c21d5b71a3b7f30 (batman-adv: Set special lockdep
 classes to avoid lockdep warning) introduced a lockdep class for the tx 
 queue,
 but did not set it in the correct initialization phase. The batman-adv 
 specific
 lock class could be replaced by a later netdevice registration phase.
 
 Reported-by: Antonio Quartulli or...@autistici.org
 Signed-off-by: Sven Eckelmann s...@narfation.org

Tested-by: Antonio Quartulli or...@autistici.org


This solves the problem reported in bug #162! Thank you Sven!

 ---
  soft-interface.c |   35 ---
  1 file changed, 24 insertions(+), 11 deletions(-)
 
 diff --git a/soft-interface.c b/soft-interface.c
 index a584f62..72d8767 100644
 --- a/soft-interface.c
 +++ b/soft-interface.c
 @@ -352,16 +352,6 @@ out:
   return;
  }
  
 -static const struct net_device_ops batadv_netdev_ops = {
 - .ndo_open = batadv_interface_open,
 - .ndo_stop = batadv_interface_release,
 - .ndo_get_stats = batadv_interface_stats,
 - .ndo_set_mac_address = batadv_interface_set_mac_addr,
 - .ndo_change_mtu = batadv_interface_change_mtu,
 - .ndo_start_xmit = batadv_interface_tx,
 - .ndo_validate_addr = eth_validate_addr
 -};
 -
  /* batman-adv network devices have devices nesting below it and are a special
   * super class of normal network devices; split their locks off into a
   * separate class since they always nest.
 @@ -382,6 +372,30 @@ static void batadv_set_lockdep_class(struct net_device 
 *dev)
   netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL);
  }
  
 +/**
 + * batadv_softif_init - Late stage initialization of soft interface
 + * @dev: registered network device to modify
 + *
 + * Returns error code on failures
 + */
 +static int batadv_softif_init(struct net_device *dev)
 +{
 + batadv_set_lockdep_class(dev);
 +
 + return 0;
 +}
 +
 +static const struct net_device_ops batadv_netdev_ops = {
 + .ndo_init = batadv_softif_init,
 + .ndo_open = batadv_interface_open,
 + .ndo_stop = batadv_interface_release,
 + .ndo_get_stats = batadv_interface_stats,
 + .ndo_set_mac_address = batadv_interface_set_mac_addr,
 + .ndo_change_mtu = batadv_interface_change_mtu,
 + .ndo_start_xmit = batadv_interface_tx,
 + .ndo_validate_addr = eth_validate_addr
 +};
 +
  static void batadv_interface_setup(struct net_device *dev)
  {
   struct batadv_priv *priv = netdev_priv(dev);
 @@ -391,7 +405,6 @@ static void batadv_interface_setup(struct net_device *dev)
   dev-netdev_ops = batadv_netdev_ops;
   dev-destructor = free_netdev;
   dev-tx_queue_len = 0;
 - batadv_set_lockdep_class(dev);
  
   /* can't call min_mtu, because the needed variables
* have not been initialized yet
 -- 
 1.7.10.4

-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto Che Guevara


pgpWksbYKX20w.pgp
Description: PGP signature


[B.A.T.M.A.N.] [PATCH] batman-adv: roaming re-routing mechanism redesign

2012-08-30 Thread Antonio Quartulli
The roaming re-routing procedure has been slightly revised in order to get rid
of the tt_poss_change variable that was not clearly representing the node/client
states. Now the code directly relies on the TT_CLIENT_ROAM flag that can be
set on the involved local/global clients.

This improvement also allow clients to roam multiple times in the same
originator-interval, because nodes now let packets go to the node that was
originally serving the roamed client which will then reroute the data to the
correct destination at any point in time.

Signed-off-by: Antonio Quartulli or...@autistici.org
---

- This patch is based on top of:
  batman-adv: substitute tt_poss_change with a per-tt_entry flag

 translation-table.c | 216 
 1 file changed, 152 insertions(+), 64 deletions(-)

diff --git a/translation-table.c b/translation-table.c
index 21830f5..e5afcee 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -238,90 +238,138 @@ static int batadv_tt_local_init(struct batadv_priv 
*bat_priv)
return 0;
 }
 
+static void
+batadv_tt_global_del_struct(struct batadv_priv *bat_priv,
+   struct batadv_tt_global_entry *tt_global_entry,
+   const char *message)
+{
+   batadv_dbg(BATADV_DBG_TT, bat_priv,
+  Deleting global tt entry %pM: %s\n,
+  tt_global_entry-common.addr, message);
+
+   batadv_hash_remove(bat_priv-tt.global_hash, batadv_compare_tt,
+  batadv_choose_orig, tt_global_entry-common.addr);
+   batadv_tt_global_entry_free_ref(tt_global_entry);
+
+}
+
 void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 int ifindex)
 {
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
-   struct batadv_tt_local_entry *tt_local_entry = NULL;
-   struct batadv_tt_global_entry *tt_global_entry = NULL;
+   struct batadv_tt_local_entry *tt_local = NULL;
+   struct batadv_tt_global_entry *tt_global = NULL;
struct hlist_head *head;
struct hlist_node *node;
struct batadv_tt_orig_list_entry *orig_entry;
int hash_added;
+   bool back_roam = false;
 
-   tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
+   tt_local = batadv_tt_local_hash_find(bat_priv, addr);
+   /* look for the global entry so that we can eventually operate on it */
+   tt_global = batadv_tt_global_hash_find(bat_priv, addr);
 
-   if (tt_local_entry) {
-   tt_local_entry-last_seen = jiffies;
-   /* possibly unset the BATADV_TT_CLIENT_PENDING flag */
-   tt_local_entry-common.flags = ~BATADV_TT_CLIENT_PENDING;
-   goto out;
+
+   if (tt_local) {
+   tt_local-last_seen = jiffies;
+   if (tt_local-common.flags  BATADV_TT_CLIENT_PENDING) {
+   /* if this client is marked as pending it means that it
+* was purged out before.
+*/
+   batadv_dbg(BATADV_DBG_TT, bat_priv,
+  Readding pending client %pM\n, addr);
+   tt_local-common.flags = ~BATADV_TT_CLIENT_PENDING;
+   goto add_event;
+   }
+   /* if the entry is marked as NEW, it means that the node is not
+* the original owner of this client (in this orig-interval),
+* therefore it does need to  eventually send a roaming
+* advertisement
+*/
+   /*if (tt_local-common.flags  BATADV_TT_CLIENT_NEW)
+   goto out;*/
+
+   if (tt_local-common.flags  BATADV_TT_CLIENT_ROAM) {
+   batadv_dbg(BATADV_DBG_TT, bat_priv,
+  Roaming client %pM came back to its 
original location\n,
+  addr);
+   tt_local-common.flags = ~BATADV_TT_CLIENT_ROAM;
+   back_roam = true;
+   goto check_roaming;
+   }
+   goto check_roaming;
}
 
-   tt_local_entry = kmalloc(sizeof(*tt_local_entry), GFP_ATOMIC);
-   if (!tt_local_entry)
+   tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
+   if (!tt_local)
goto out;
 
batadv_dbg(BATADV_DBG_TT, bat_priv,
   Creating new local tt entry: %pM (ttvn: %d)\n, addr,
   (uint8_t)atomic_read(bat_priv-tt.vn));
 
-   memcpy(tt_local_entry-common.addr, addr, ETH_ALEN);
-   tt_local_entry-common.flags = BATADV_NO_FLAGS;
+   memcpy(tt_local-common.addr, addr, ETH_ALEN);
+   tt_local-common.flags = BATADV_NO_FLAGS;
if (batadv_is_wifi_iface(ifindex))
-   tt_local_entry-common.flags |= BATADV_TT_CLIENT_WIFI;
-   atomic_set(tt_local_entry-common.refcount, 2);
-  

[B.A.T.M.A.N.] [PATCH] batman-adv: don't rely on positions in struct for hashing

2012-08-30 Thread Simon Wunderlich
The hash functions in the bridge loop avoidance code expects the
VLAN vid to be right after the mac address, but this is not guaranteed.

Fix this by explicitly hashing over the right fields of the struct.

Reported-by: Marek Lindner lindner_ma...@yahoo.de
Signed-off-by: Simon Wunderlich s...@hrz.tu-chemnitz.de
---
 bridge_loop_avoidance.c |   32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index 0921509..7e62c79 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -37,18 +37,26 @@ static void batadv_bla_periodic_work(struct work_struct 
*work);
 static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
 struct batadv_backbone_gw *backbone_gw);
 
+static inline void hash_bytes(uint32_t *hash, void *data, uint32_t size)
+{
+   const unsigned char *key = data;
+   int i;
+
+   for (i = 0; i  size; i++) {
+   *hash += key[i];
+   *hash += (*hash  10);
+   *hash ^= (*hash  6);
+   }
+}
+
 /* return the index of the claim */
 static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
 {
-   const unsigned char *key = data;
+   struct batadv_claim *claim = (struct batadv_claim *)data;
uint32_t hash = 0;
-   size_t i;
 
-   for (i = 0; i  ETH_ALEN + sizeof(short); i++) {
-   hash += key[i];
-   hash += (hash  10);
-   hash ^= (hash  6);
-   }
+   hash_bytes(hash, claim-addr, sizeof(claim-addr));
+   hash_bytes(hash, claim-vid, sizeof(claim-vid));
 
hash += (hash  3);
hash ^= (hash  11);
@@ -61,15 +69,11 @@ static inline uint32_t batadv_choose_claim(const void 
*data, uint32_t size)
 static inline uint32_t batadv_choose_backbone_gw(const void *data,
 uint32_t size)
 {
-   const unsigned char *key = data;
+   struct batadv_claim *claim = (struct batadv_claim *)data;
uint32_t hash = 0;
-   size_t i;
 
-   for (i = 0; i  ETH_ALEN + sizeof(short); i++) {
-   hash += key[i];
-   hash += (hash  10);
-   hash ^= (hash  6);
-   }
+   hash_bytes(hash, claim-addr, sizeof(claim-addr));
+   hash_bytes(hash, claim-vid, sizeof(claim-vid));
 
hash += (hash  3);
hash ^= (hash  11);
-- 
1.7.10



Re: [B.A.T.M.A.N.] [PATCH] batman-adv: don't rely on positions in struct for hashing

2012-08-30 Thread Antonio Quartulli
On Thu, Aug 30, 2012 at 06:22:27PM +0200, Simon Wunderlich wrote:
 The hash functions in the bridge loop avoidance code expects the
 VLAN vid to be right after the mac address, but this is not guaranteed.
 
 Fix this by explicitly hashing over the right fields of the struct.
 

What about creating a new structure like

struct {
uint8_t mac[ETH_ALEN];
short vid;
}

to be used as first field in the batadv_claim object? Then you can easily hash
the first 10 bytes in one shot.
This would also help to avoid code duplication in the future (TT will support
VLAN tagging sooner or later and will need the same trick).

Cheers,


-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto Che Guevara


pgpVVAyWMBYrC.pgp
Description: PGP signature


Re: [B.A.T.M.A.N.] [PATCH] batman-adv: don't rely on positions in struct for hashing

2012-08-30 Thread Antonio Quartulli
On Thu, Aug 30, 2012 at 06:33:52PM +0200, Antonio Quartulli wrote:
 On Thu, Aug 30, 2012 at 06:22:27PM +0200, Simon Wunderlich wrote:
  The hash functions in the bridge loop avoidance code expects the
  VLAN vid to be right after the mac address, but this is not guaranteed.
  
  Fix this by explicitly hashing over the right fields of the struct.
  
 
 What about creating a new structure like
 
 struct {
   uint8_t mac[ETH_ALEN];
   short vid;
 }
 
 to be used as first field in the batadv_claim object? Then you can easily hash
 the first 10 bytes in one shot.
 This would also help to avoid code duplication in the future (TT will support
 VLAN tagging sooner or later and will need the same trick).

Sorry,
but my proposal is wrong. In the new structure we could still have some padding
between the two fields (and we can't know), therefore we cannot hash 10bytes in
one shot as I said.

Drop my idea :)

Cheers,




-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto Che Guevara


pgpDFiydbUYcG.pgp
Description: PGP signature