Commit 627d2cc0 authored by David S. Miller's avatar David S. Miller

Merge tag 'batman-adv-fix-for-davem' of git://git.open-mesh.org/linux-merge

Included changes:
- ensure bonding is used (if enabled) for packets coming in the soft
  interface
- fix race condition to avoid orig_nodes to be deleted right after
  being added
- avoid false positive lockdep splats by assigning lockclass to
  the proper hashtable lock objects
- avoid miscounting of multicast 'disabled' nodes in the network
- fix memory leak in the Global Translation Table in case of
  originator interval change
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 07ff890d 9d31b3ce
...@@ -685,11 +685,13 @@ static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, ...@@ -685,11 +685,13 @@ static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
if (orig_initialized) if (orig_initialized)
atomic_dec(&bat_priv->mcast.num_disabled); atomic_dec(&bat_priv->mcast.num_disabled);
orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST; orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST;
/* If mcast support is being switched off increase the disabled /* If mcast support is being switched off or if this is an initial
* mcast node counter. * OGM without mcast support then increase the disabled mcast
* node counter.
*/ */
} else if (!orig_mcast_enabled && } else if (!orig_mcast_enabled &&
orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) { (orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST ||
!orig_initialized)) {
atomic_inc(&bat_priv->mcast.num_disabled); atomic_inc(&bat_priv->mcast.num_disabled);
orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST; orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST;
} }
...@@ -738,7 +740,8 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig) ...@@ -738,7 +740,8 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
{ {
struct batadv_priv *bat_priv = orig->bat_priv; struct batadv_priv *bat_priv = orig->bat_priv;
if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST)) if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) &&
orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST)
atomic_dec(&bat_priv->mcast.num_disabled); atomic_dec(&bat_priv->mcast.num_disabled);
batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS); batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
......
...@@ -133,7 +133,7 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv) ...@@ -133,7 +133,7 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv)
if (!bat_priv->nc.decoding_hash) if (!bat_priv->nc.decoding_hash)
goto err; goto err;
batadv_hash_set_lock_class(bat_priv->nc.coding_hash, batadv_hash_set_lock_class(bat_priv->nc.decoding_hash,
&batadv_nc_decoding_hash_lock_class_key); &batadv_nc_decoding_hash_lock_class_key);
INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker); INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker);
......
...@@ -570,9 +570,6 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu) ...@@ -570,9 +570,6 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
batadv_frag_purge_orig(orig_node, NULL); batadv_frag_purge_orig(orig_node, NULL);
batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1,
"originator timed out");
if (orig_node->bat_priv->bat_algo_ops->bat_orig_free) if (orig_node->bat_priv->bat_algo_ops->bat_orig_free)
orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node); orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node);
...@@ -678,6 +675,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, ...@@ -678,6 +675,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
atomic_set(&orig_node->last_ttvn, 0); atomic_set(&orig_node->last_ttvn, 0);
orig_node->tt_buff = NULL; orig_node->tt_buff = NULL;
orig_node->tt_buff_len = 0; orig_node->tt_buff_len = 0;
orig_node->last_seen = jiffies;
reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
orig_node->bcast_seqno_reset = reset_time; orig_node->bcast_seqno_reset = reset_time;
#ifdef CONFIG_BATMAN_ADV_MCAST #ifdef CONFIG_BATMAN_ADV_MCAST
...@@ -977,6 +975,9 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv) ...@@ -977,6 +975,9 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
if (batadv_purge_orig_node(bat_priv, orig_node)) { if (batadv_purge_orig_node(bat_priv, orig_node)) {
batadv_gw_node_delete(bat_priv, orig_node); batadv_gw_node_delete(bat_priv, orig_node);
hlist_del_rcu(&orig_node->hash_entry); hlist_del_rcu(&orig_node->hash_entry);
batadv_tt_global_del_orig(orig_node->bat_priv,
orig_node, -1,
"originator timed out");
batadv_orig_node_free_ref(orig_node); batadv_orig_node_free_ref(orig_node);
continue; continue;
} }
......
...@@ -443,11 +443,13 @@ batadv_find_router(struct batadv_priv *bat_priv, ...@@ -443,11 +443,13 @@ batadv_find_router(struct batadv_priv *bat_priv,
router = batadv_orig_router_get(orig_node, recv_if); router = batadv_orig_router_get(orig_node, recv_if);
if (!router)
return router;
/* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop) /* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop)
* and if activated. * and if activated.
*/ */
if (recv_if == BATADV_IF_DEFAULT || !atomic_read(&bat_priv->bonding) || if (!(recv_if == BATADV_IF_DEFAULT && atomic_read(&bat_priv->bonding)))
!router)
return router; return router;
/* bonding: loop through the list of possible routers found /* bonding: loop through the list of possible routers found
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment