Included changes:
- avoid integer overflow in GW selection routine - prevent race condition by making capability bit changes atomic (use clear/set/test_bit) - fix synchronization issue in mcast tvlv handler - fix crash on double list removal of TT Request objects - fix leak by puring packets enqueued for sending upon iface removal - ensure network header pointer is set in skb -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJVzlUGAAoJEOb/4TMchkvfy9EQAJ0DBKdTqiuWwNQzZ9ghCeLi Njgwyq4WdvZXp8vIj9cq0AR1JsFvH9fGp4BlLE8pGsQyxURiWQmR/Jurvb0UGMhM SPVvl/b0nnCrRu937UcVEiq6wRrFwEr1fYfL45fY0c1eTkXSu/54iEURDvWlkpyX COB4cuydoPY6O2LGiPRsGlOGTYbQ/u89G1HyxFr9Ch2IVRMPVXB6zuI7puuEg2ee EwgI2IGO/GHHaScbXQpVy+bL6XL/OcQ4nCrYeaNpwbOKAOfGabNzfVncSCLRKMSW jZh5D3cG3AKGUPeooEtd8yGgNG3SSVNTXt7CL+WOM7/2EKvYeNdJFaQzbdZQEtT0 begOcUJ2K0yas/iExqYXtEPFCWXhjuzrb4u6wu5psGgu3zt1nltpCkplDEMcSEia C+dYE5r/JM2S1lsFclnjz+rBXu4ZfCUvV0q+50+lGiWPhfemM2M2XqJNcay0ioSm radSwMe549sh6r3ajwdxF5z66tU94PERMMxVxJ9Z3gmHUZ56phxEe6X0xBO91bhW aSCcFr6PQMxmfwanLj5Ydxm5MPHdDXF84YPMTFcGb4ya9ZWWURGNq7Sr85Ek7N6W 5DIA8F8/vsgaXYUn011aBu4q1mm5ZsTs9nR3MAxchAuuu3sTBOkd/BecS4T7CEOE IHnbxsJxXReJ/aCQFoks =ZEuN -----END PGP SIGNATURE----- Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge Antonio Quartulli says: ==================== Included changes: - avoid integer overflow in GW selection routine - prevent race condition by making capability bit changes atomic (use clear/set/test_bit) - fix synchronization issue in mcast tvlv handler - fix crash on double list removal of TT Request objects - fix leak by puring packets enqueued for sending upon iface removal - ensure network header pointer is set in skb ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
c1f066d4ee
|
@ -19,6 +19,7 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
@ -453,7 +454,7 @@ static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res,
|
|||
int j;
|
||||
|
||||
/* check if orig node candidate is running DAT */
|
||||
if (!(candidate->capabilities & BATADV_ORIG_CAPA_HAS_DAT))
|
||||
if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities))
|
||||
goto out;
|
||||
|
||||
/* Check if this node has already been selected... */
|
||||
|
@ -713,9 +714,9 @@ static void batadv_dat_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
|
|||
uint16_t tvlv_value_len)
|
||||
{
|
||||
if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND)
|
||||
orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_DAT;
|
||||
clear_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities);
|
||||
else
|
||||
orig->capabilities |= BATADV_ORIG_CAPA_HAS_DAT;
|
||||
set_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -153,15 +153,11 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
|
|||
struct batadv_neigh_node *router;
|
||||
struct batadv_neigh_ifinfo *router_ifinfo;
|
||||
struct batadv_gw_node *gw_node, *curr_gw = NULL;
|
||||
uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
|
||||
uint32_t gw_divisor;
|
||||
uint64_t max_gw_factor = 0, tmp_gw_factor = 0;
|
||||
uint8_t max_tq = 0;
|
||||
uint8_t tq_avg;
|
||||
struct batadv_orig_node *orig_node;
|
||||
|
||||
gw_divisor = BATADV_TQ_LOCAL_WINDOW_SIZE * BATADV_TQ_LOCAL_WINDOW_SIZE;
|
||||
gw_divisor *= 64;
|
||||
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) {
|
||||
if (gw_node->deleted)
|
||||
|
@ -187,7 +183,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
|
|||
tmp_gw_factor = tq_avg * tq_avg;
|
||||
tmp_gw_factor *= gw_node->bandwidth_down;
|
||||
tmp_gw_factor *= 100 * 100;
|
||||
tmp_gw_factor /= gw_divisor;
|
||||
tmp_gw_factor >>= 18;
|
||||
|
||||
if ((tmp_gw_factor > max_gw_factor) ||
|
||||
((tmp_gw_factor == max_gw_factor) &&
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
@ -588,19 +590,26 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||
*
|
||||
* If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,
|
||||
* orig, has toggled then this method updates counter and list accordingly.
|
||||
*
|
||||
* Caller needs to hold orig->mcast_handler_lock.
|
||||
*/
|
||||
static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
|
||||
struct batadv_orig_node *orig,
|
||||
uint8_t mcast_flags)
|
||||
{
|
||||
struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node;
|
||||
struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list;
|
||||
|
||||
/* switched from flag unset to set */
|
||||
if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
|
||||
!(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) {
|
||||
atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables);
|
||||
|
||||
spin_lock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
hlist_add_head_rcu(&orig->mcast_want_all_unsnoopables_node,
|
||||
&bat_priv->mcast.want_all_unsnoopables_list);
|
||||
/* flag checks above + mcast_handler_lock prevents this */
|
||||
WARN_ON(!hlist_unhashed(node));
|
||||
|
||||
hlist_add_head_rcu(node, head);
|
||||
spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
/* switched from flag set to unset */
|
||||
} else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) &&
|
||||
|
@ -608,7 +617,10 @@ static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
|
|||
atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables);
|
||||
|
||||
spin_lock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
hlist_del_rcu(&orig->mcast_want_all_unsnoopables_node);
|
||||
/* flag checks above + mcast_handler_lock prevents this */
|
||||
WARN_ON(hlist_unhashed(node));
|
||||
|
||||
hlist_del_init_rcu(node);
|
||||
spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
}
|
||||
}
|
||||
|
@ -621,19 +633,26 @@ static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
|
|||
*
|
||||
* If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has
|
||||
* toggled then this method updates counter and list accordingly.
|
||||
*
|
||||
* Caller needs to hold orig->mcast_handler_lock.
|
||||
*/
|
||||
static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
|
||||
struct batadv_orig_node *orig,
|
||||
uint8_t mcast_flags)
|
||||
{
|
||||
struct hlist_node *node = &orig->mcast_want_all_ipv4_node;
|
||||
struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list;
|
||||
|
||||
/* switched from flag unset to set */
|
||||
if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 &&
|
||||
!(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) {
|
||||
atomic_inc(&bat_priv->mcast.num_want_all_ipv4);
|
||||
|
||||
spin_lock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
hlist_add_head_rcu(&orig->mcast_want_all_ipv4_node,
|
||||
&bat_priv->mcast.want_all_ipv4_list);
|
||||
/* flag checks above + mcast_handler_lock prevents this */
|
||||
WARN_ON(!hlist_unhashed(node));
|
||||
|
||||
hlist_add_head_rcu(node, head);
|
||||
spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
/* switched from flag set to unset */
|
||||
} else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) &&
|
||||
|
@ -641,7 +660,10 @@ static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
|
|||
atomic_dec(&bat_priv->mcast.num_want_all_ipv4);
|
||||
|
||||
spin_lock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
hlist_del_rcu(&orig->mcast_want_all_ipv4_node);
|
||||
/* flag checks above + mcast_handler_lock prevents this */
|
||||
WARN_ON(hlist_unhashed(node));
|
||||
|
||||
hlist_del_init_rcu(node);
|
||||
spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
}
|
||||
}
|
||||
|
@ -654,19 +676,26 @@ static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
|
|||
*
|
||||
* If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has
|
||||
* toggled then this method updates counter and list accordingly.
|
||||
*
|
||||
* Caller needs to hold orig->mcast_handler_lock.
|
||||
*/
|
||||
static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
|
||||
struct batadv_orig_node *orig,
|
||||
uint8_t mcast_flags)
|
||||
{
|
||||
struct hlist_node *node = &orig->mcast_want_all_ipv6_node;
|
||||
struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list;
|
||||
|
||||
/* switched from flag unset to set */
|
||||
if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 &&
|
||||
!(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) {
|
||||
atomic_inc(&bat_priv->mcast.num_want_all_ipv6);
|
||||
|
||||
spin_lock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
hlist_add_head_rcu(&orig->mcast_want_all_ipv6_node,
|
||||
&bat_priv->mcast.want_all_ipv6_list);
|
||||
/* flag checks above + mcast_handler_lock prevents this */
|
||||
WARN_ON(!hlist_unhashed(node));
|
||||
|
||||
hlist_add_head_rcu(node, head);
|
||||
spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
/* switched from flag set to unset */
|
||||
} else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) &&
|
||||
|
@ -674,7 +703,10 @@ static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
|
|||
atomic_dec(&bat_priv->mcast.num_want_all_ipv6);
|
||||
|
||||
spin_lock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
hlist_del_rcu(&orig->mcast_want_all_ipv6_node);
|
||||
/* flag checks above + mcast_handler_lock prevents this */
|
||||
WARN_ON(hlist_unhashed(node));
|
||||
|
||||
hlist_del_init_rcu(node);
|
||||
spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
|
||||
}
|
||||
}
|
||||
|
@ -697,39 +729,42 @@ static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
|
|||
uint8_t mcast_flags = BATADV_NO_FLAGS;
|
||||
bool orig_initialized;
|
||||
|
||||
orig_initialized = orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST;
|
||||
if (orig_mcast_enabled && tvlv_value &&
|
||||
(tvlv_value_len >= sizeof(mcast_flags)))
|
||||
mcast_flags = *(uint8_t *)tvlv_value;
|
||||
|
||||
spin_lock_bh(&orig->mcast_handler_lock);
|
||||
orig_initialized = test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
|
||||
&orig->capa_initialized);
|
||||
|
||||
/* If mcast support is turned on decrease the disabled mcast node
|
||||
* counter only if we had increased it for this node before. If this
|
||||
* is a completely new orig_node no need to decrease the counter.
|
||||
*/
|
||||
if (orig_mcast_enabled &&
|
||||
!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST)) {
|
||||
!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
|
||||
if (orig_initialized)
|
||||
atomic_dec(&bat_priv->mcast.num_disabled);
|
||||
orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST;
|
||||
set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
|
||||
/* If mcast support is being switched off or if this is an initial
|
||||
* OGM without mcast support then increase the disabled mcast
|
||||
* node counter.
|
||||
*/
|
||||
} else if (!orig_mcast_enabled &&
|
||||
(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST ||
|
||||
(test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) ||
|
||||
!orig_initialized)) {
|
||||
atomic_inc(&bat_priv->mcast.num_disabled);
|
||||
orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST;
|
||||
clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
|
||||
}
|
||||
|
||||
orig->capa_initialized |= BATADV_ORIG_CAPA_HAS_MCAST;
|
||||
|
||||
if (orig_mcast_enabled && tvlv_value &&
|
||||
(tvlv_value_len >= sizeof(mcast_flags)))
|
||||
mcast_flags = *(uint8_t *)tvlv_value;
|
||||
set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);
|
||||
|
||||
batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags);
|
||||
batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags);
|
||||
batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);
|
||||
|
||||
orig->mcast_flags = mcast_flags;
|
||||
spin_unlock_bh(&orig->mcast_handler_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -763,11 +798,15 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
|
|||
{
|
||||
struct batadv_priv *bat_priv = orig->bat_priv;
|
||||
|
||||
if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) &&
|
||||
orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST)
|
||||
spin_lock_bh(&orig->mcast_handler_lock);
|
||||
|
||||
if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) &&
|
||||
test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized))
|
||||
atomic_dec(&bat_priv->mcast.num_disabled);
|
||||
|
||||
batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
|
||||
batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS);
|
||||
batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS);
|
||||
|
||||
spin_unlock_bh(&orig->mcast_handler_lock);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
@ -134,9 +135,9 @@ static void batadv_nc_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
|
|||
uint16_t tvlv_value_len)
|
||||
{
|
||||
if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND)
|
||||
orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_NC;
|
||||
clear_bit(BATADV_ORIG_CAPA_HAS_NC, &orig->capabilities);
|
||||
else
|
||||
orig->capabilities |= BATADV_ORIG_CAPA_HAS_NC;
|
||||
set_bit(BATADV_ORIG_CAPA_HAS_NC, &orig->capabilities);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -894,7 +895,7 @@ void batadv_nc_update_nc_node(struct batadv_priv *bat_priv,
|
|||
goto out;
|
||||
|
||||
/* check if orig node is network coding enabled */
|
||||
if (!(orig_node->capabilities & BATADV_ORIG_CAPA_HAS_NC))
|
||||
if (!test_bit(BATADV_ORIG_CAPA_HAS_NC, &orig_node->capabilities))
|
||||
goto out;
|
||||
|
||||
/* accept ogms from 'good' neighbors and single hop neighbors */
|
||||
|
|
|
@ -696,8 +696,13 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
|
|||
orig_node->last_seen = jiffies;
|
||||
reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
|
||||
orig_node->bcast_seqno_reset = reset_time;
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_MCAST
|
||||
orig_node->mcast_flags = BATADV_NO_FLAGS;
|
||||
INIT_HLIST_NODE(&orig_node->mcast_want_all_unsnoopables_node);
|
||||
INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv4_node);
|
||||
INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv6_node);
|
||||
spin_lock_init(&orig_node->mcast_handler_lock);
|
||||
#endif
|
||||
|
||||
/* create a vlan object for the "untagged" LAN */
|
||||
|
|
|
@ -616,7 +616,8 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
|
|||
* we delete only packets belonging to the given interface
|
||||
*/
|
||||
if ((hard_iface) &&
|
||||
(forw_packet->if_incoming != hard_iface))
|
||||
(forw_packet->if_incoming != hard_iface) &&
|
||||
(forw_packet->if_outgoing != hard_iface))
|
||||
continue;
|
||||
|
||||
spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
|
||||
|
|
|
@ -202,6 +202,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
|||
int gw_mode;
|
||||
enum batadv_forw_mode forw_mode;
|
||||
struct batadv_orig_node *mcast_single_orig = NULL;
|
||||
int network_offset = ETH_HLEN;
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
goto dropped;
|
||||
|
@ -214,14 +215,18 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
|||
case ETH_P_8021Q:
|
||||
vhdr = vlan_eth_hdr(skb);
|
||||
|
||||
if (vhdr->h_vlan_encapsulated_proto != ethertype)
|
||||
if (vhdr->h_vlan_encapsulated_proto != ethertype) {
|
||||
network_offset += VLAN_HLEN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* fall through */
|
||||
case ETH_P_BATMAN:
|
||||
goto dropped;
|
||||
}
|
||||
|
||||
skb_set_network_header(skb, network_offset);
|
||||
|
||||
if (batadv_bla_tx(bat_priv, skb, vid))
|
||||
goto dropped;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/compiler.h>
|
||||
|
@ -1879,7 +1880,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
|
|||
}
|
||||
spin_unlock_bh(list_lock);
|
||||
}
|
||||
orig_node->capa_initialized &= ~BATADV_ORIG_CAPA_HAS_TT;
|
||||
clear_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized);
|
||||
}
|
||||
|
||||
static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global,
|
||||
|
@ -2212,7 +2213,7 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
|
|||
spin_lock_bh(&bat_priv->tt.req_list_lock);
|
||||
|
||||
list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
|
||||
list_del(&node->list);
|
||||
list_del_init(&node->list);
|
||||
kfree(node);
|
||||
}
|
||||
|
||||
|
@ -2248,7 +2249,7 @@ static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
|
|||
list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
|
||||
if (batadv_has_timed_out(node->issued_at,
|
||||
BATADV_TT_REQUEST_TIMEOUT)) {
|
||||
list_del(&node->list);
|
||||
list_del_init(&node->list);
|
||||
kfree(node);
|
||||
}
|
||||
}
|
||||
|
@ -2530,7 +2531,8 @@ out:
|
|||
batadv_hardif_free_ref(primary_if);
|
||||
if (ret && tt_req_node) {
|
||||
spin_lock_bh(&bat_priv->tt.req_list_lock);
|
||||
list_del(&tt_req_node->list);
|
||||
/* list_del_init() verifies tt_req_node still is in the list */
|
||||
list_del_init(&tt_req_node->list);
|
||||
spin_unlock_bh(&bat_priv->tt.req_list_lock);
|
||||
kfree(tt_req_node);
|
||||
}
|
||||
|
@ -2838,7 +2840,7 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
|
|||
return;
|
||||
}
|
||||
}
|
||||
orig_node->capa_initialized |= BATADV_ORIG_CAPA_HAS_TT;
|
||||
set_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized);
|
||||
}
|
||||
|
||||
static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
|
||||
|
@ -2967,7 +2969,7 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
|
|||
list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
|
||||
if (!batadv_compare_eth(node->addr, resp_src))
|
||||
continue;
|
||||
list_del(&node->list);
|
||||
list_del_init(&node->list);
|
||||
kfree(node);
|
||||
}
|
||||
|
||||
|
@ -3340,7 +3342,8 @@ static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
|
|||
bool has_tt_init;
|
||||
|
||||
tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff;
|
||||
has_tt_init = orig_node->capa_initialized & BATADV_ORIG_CAPA_HAS_TT;
|
||||
has_tt_init = test_bit(BATADV_ORIG_CAPA_HAS_TT,
|
||||
&orig_node->capa_initialized);
|
||||
|
||||
/* orig table not initialised AND first diff is in the OGM OR the ttvn
|
||||
* increased by one -> we can apply the attached changes
|
||||
|
|
|
@ -221,6 +221,7 @@ struct batadv_orig_bat_iv {
|
|||
* @batadv_dat_addr_t: address of the orig node in the distributed hash
|
||||
* @last_seen: time when last packet from this node was received
|
||||
* @bcast_seqno_reset: time when the broadcast seqno window was reset
|
||||
* @mcast_handler_lock: synchronizes mcast-capability and -flag changes
|
||||
* @mcast_flags: multicast flags announced by the orig node
|
||||
* @mcast_want_all_unsnoop_node: a list node for the
|
||||
* mcast.want_all_unsnoopables list
|
||||
|
@ -268,13 +269,15 @@ struct batadv_orig_node {
|
|||
unsigned long last_seen;
|
||||
unsigned long bcast_seqno_reset;
|
||||
#ifdef CONFIG_BATMAN_ADV_MCAST
|
||||
/* synchronizes mcast tvlv specific orig changes */
|
||||
spinlock_t mcast_handler_lock;
|
||||
uint8_t mcast_flags;
|
||||
struct hlist_node mcast_want_all_unsnoopables_node;
|
||||
struct hlist_node mcast_want_all_ipv4_node;
|
||||
struct hlist_node mcast_want_all_ipv6_node;
|
||||
#endif
|
||||
uint8_t capabilities;
|
||||
uint8_t capa_initialized;
|
||||
unsigned long capabilities;
|
||||
unsigned long capa_initialized;
|
||||
atomic_t last_ttvn;
|
||||
unsigned char *tt_buff;
|
||||
int16_t tt_buff_len;
|
||||
|
@ -313,10 +316,10 @@ struct batadv_orig_node {
|
|||
* (= orig node announces a tvlv of type BATADV_TVLV_MCAST)
|
||||
*/
|
||||
enum batadv_orig_capabilities {
|
||||
BATADV_ORIG_CAPA_HAS_DAT = BIT(0),
|
||||
BATADV_ORIG_CAPA_HAS_NC = BIT(1),
|
||||
BATADV_ORIG_CAPA_HAS_TT = BIT(2),
|
||||
BATADV_ORIG_CAPA_HAS_MCAST = BIT(3),
|
||||
BATADV_ORIG_CAPA_HAS_DAT,
|
||||
BATADV_ORIG_CAPA_HAS_NC,
|
||||
BATADV_ORIG_CAPA_HAS_TT,
|
||||
BATADV_ORIG_CAPA_HAS_MCAST,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче