Included changes:

- use per_cpu_add when possible
 - prevent the TT component to add multicast address as "mesh clients"
 - some debug output improvements
 - proper lockdeps class initializations
 - new style fixes (space before/after brackets)
 - other minor fixes and refactoring
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.19 (GNU/Linux)
 
 iQIcBAABAgAGBQJQ8y1GAAoJEADl0hg6qKeOgegQAKq0TMD2XVDpFthqwszcEZ7o
 1zunQ/UGp1+8ZZ+GiJ3B8VxbFpq4MYybC/J2eow7WmlDPMGmRCS5dTsYn1tkYiwY
 MgBGhzuoDLcSpKZsJTrfzu8l6CkgdRHf3hLVON/UNu5SDueEXxPO7cRCrOtfNR/g
 auFxNIfCderWaBiRmSQ2BZdAhSwdsh0igqg87YVETuXJrFBG4yLTAEerxOU2m+eC
 v2YrNI+tRIlCoE8N8o3cJwkpCml+teFElA0Z7KxswHzmTIipkALd/LWBaU/GDKWS
 Pto5n9bH2oIS4VywxH3OB5Gd8NNnEPlxUblupZljlcHLJiVD06qFYCQx0/iVon5j
 Dbcfc9P9RSL4pp1zrOR6VvtOmrrtn06HXVdIT0Fse9ZjgaHX0WzdMV2ZM830xmdq
 AslxOcZsuQMXmiPr8pwmHvIwSfVnWPmQpkXyP8NCYIqM6NYzznAuLdnbT6bix1wC
 sPPtNEip2HW0d524qWiyVDrSuJ44tndk6t6Ycjw0uv/KnGX4XWUi4XaR6/qVOCES
 EmGVt+cQhqPTl+qzXsyfGoyE5cieU0BfTyvQ//5JS/At9H4VGNGsBvJx3T2HD0+0
 fkP3uu9EvChZWDKGQbJE3FMeBG8v+xtQIIS81UCRrryIpkCY4Txl264wdvDcjbup
 DzS6fJgDo2WnRNs8JPT8
 =G3Vh
 -----END PGP SIGNATURE-----

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

Included changes:
- use per_cpu_add when possible
- prevent the TT component to add multicast address as "mesh clients"
- some debug output improvements
- proper lockdeps class initializations
- new style fixes (space before/after brackets)
- other minor fixes and refactoring

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2013-01-13 20:36:56 -05:00
commit a4412a681a
13 changed files with 88 additions and 70 deletions

View File

@ -183,7 +183,6 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
/* adjust all flags and log packets */ /* adjust all flags and log packets */
while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
batadv_ogm_packet->tt_num_changes)) { batadv_ogm_packet->tt_num_changes)) {
/* we might have aggregated direct link packets with an /* we might have aggregated direct link packets with an
* ordinary base packet * ordinary base packet
*/ */
@ -261,7 +260,6 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
*/ */
if ((directlink && (batadv_ogm_packet->header.ttl == 1)) || if ((directlink && (batadv_ogm_packet->header.ttl == 1)) ||
(forw_packet->own && (forw_packet->if_incoming != primary_if))) { (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
/* FIXME: what about aggregated packets ? */ /* FIXME: what about aggregated packets ? */
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"%s packet (originator %pM, seqno %u, TTL %d) on interface %s [%pM]\n", "%s packet (originator %pM, seqno %u, TTL %d) on interface %s [%pM]\n",
@ -325,7 +323,6 @@ batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
if (time_before(send_time, forw_packet->send_time) && if (time_before(send_time, forw_packet->send_time) &&
time_after_eq(aggregation_end_time, forw_packet->send_time) && time_after_eq(aggregation_end_time, forw_packet->send_time) &&
(aggregated_bytes <= BATADV_MAX_AGGREGATION_BYTES)) { (aggregated_bytes <= BATADV_MAX_AGGREGATION_BYTES)) {
/* check aggregation compatibility /* check aggregation compatibility
* -> direct link packets are broadcasted on * -> direct link packets are broadcasted on
* their interface only * their interface only
@ -815,7 +812,6 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(tmp_neigh_node, node, hlist_for_each_entry_rcu(tmp_neigh_node, node,
&orig_neigh_node->neigh_list, list) { &orig_neigh_node->neigh_list, list) {
if (!batadv_compare_eth(tmp_neigh_node->addr, if (!batadv_compare_eth(tmp_neigh_node->addr,
orig_neigh_node->orig)) orig_neigh_node->orig))
continue; continue;
@ -949,7 +945,6 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(tmp_neigh_node, node, hlist_for_each_entry_rcu(tmp_neigh_node, node,
&orig_node->neigh_list, list) { &orig_node->neigh_list, list) {
is_duplicate |= batadv_test_bit(tmp_neigh_node->real_bits, is_duplicate |= batadv_test_bit(tmp_neigh_node->real_bits,
orig_node->last_real_seqno, orig_node->last_real_seqno,
seqno); seqno);
@ -1033,7 +1028,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
is_single_hop_neigh = true; is_single_hop_neigh = true;
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n", "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %#.4x, changes %u, tq %d, TTL %d, V %d, IDF %d)\n",
ethhdr->h_source, if_incoming->net_dev->name, ethhdr->h_source, if_incoming->net_dev->name,
if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig, if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig,
batadv_ogm_packet->prev_sender, batadv_ogm_packet->prev_sender,
@ -1223,7 +1218,6 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
/* is single hop (direct) neighbor */ /* is single hop (direct) neighbor */
if (is_single_hop_neigh) { if (is_single_hop_neigh) {
/* mark direct link on incoming interface */ /* mark direct link on incoming interface */
batadv_iv_ogm_forward(orig_node, ethhdr, batadv_ogm_packet, batadv_iv_ogm_forward(orig_node, ethhdr, batadv_ogm_packet,
is_single_hop_neigh, is_single_hop_neigh,

View File

@ -57,7 +57,7 @@ static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
static inline uint32_t batadv_choose_backbone_gw(const void *data, static inline uint32_t batadv_choose_backbone_gw(const void *data,
uint32_t size) uint32_t size)
{ {
struct batadv_claim *claim = (struct batadv_claim *)data; const struct batadv_claim *claim = (struct batadv_claim *)data;
uint32_t hash = 0; uint32_t hash = 0;
hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr)); hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
@ -235,7 +235,6 @@ batadv_bla_del_backbone_claims(struct batadv_backbone_gw *backbone_gw)
spin_lock_bh(list_lock); spin_lock_bh(list_lock);
hlist_for_each_entry_safe(claim, node, node_tmp, hlist_for_each_entry_safe(claim, node, node_tmp,
head, hash_entry) { head, hash_entry) {
if (claim->backbone_gw != backbone_gw) if (claim->backbone_gw != backbone_gw)
continue; continue;
@ -338,7 +337,6 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
"bla_send_claim(): REQUEST of %pM to %pMon vid %d\n", "bla_send_claim(): REQUEST of %pM to %pMon vid %d\n",
ethhdr->h_source, ethhdr->h_dest, vid); ethhdr->h_source, ethhdr->h_dest, vid);
break; break;
} }
if (vid != -1) if (vid != -1)
@ -539,7 +537,6 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid, batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
BATADV_CLAIM_TYPE_ANNOUNCE); BATADV_CLAIM_TYPE_ANNOUNCE);
} }
/** /**
@ -598,7 +595,6 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
batadv_backbone_gw_free_ref(claim->backbone_gw); batadv_backbone_gw_free_ref(claim->backbone_gw);
} }
/* set (new) backbone gw */ /* set (new) backbone gw */
atomic_inc(&backbone_gw->refcount); atomic_inc(&backbone_gw->refcount);
@ -661,12 +657,12 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv,
crc = ntohs(*((__be16 *)(&an_addr[4]))); crc = ntohs(*((__be16 *)(&an_addr[4])));
batadv_dbg(BATADV_DBG_BLA, bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv,
"handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %04x\n", "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n",
vid, backbone_gw->orig, crc); vid, backbone_gw->orig, crc);
if (backbone_gw->crc != crc) { if (backbone_gw->crc != crc) {
batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv, batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
"handle_announce(): CRC FAILED for %pM/%d (my = %04x, sent = %04x)\n", "handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n",
backbone_gw->orig, backbone_gw->vid, backbone_gw->orig, backbone_gw->vid,
backbone_gw->crc, crc); backbone_gw->crc, crc);
@ -835,7 +831,7 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv,
/* if our mesh friends mac is bigger, use it for ourselves. */ /* if our mesh friends mac is bigger, use it for ourselves. */
if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) { if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) {
batadv_dbg(BATADV_DBG_BLA, bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv,
"taking other backbones claim group: %04x\n", "taking other backbones claim group: %#.4x\n",
ntohs(bla_dst->group)); ntohs(bla_dst->group));
bla_dst_own->group = bla_dst->group; bla_dst_own->group = bla_dst->group;
} }
@ -1626,10 +1622,10 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
primary_addr = primary_if->net_dev->dev_addr; primary_addr = primary_if->net_dev->dev_addr;
seq_printf(seq, seq_printf(seq,
"Claims announced for the mesh %s (orig %pM, group id %04x)\n", "Claims announced for the mesh %s (orig %pM, group id %#.4x)\n",
net_dev->name, primary_addr, net_dev->name, primary_addr,
ntohs(bat_priv->bla.claim_dest.group)); ntohs(bat_priv->bla.claim_dest.group));
seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n", seq_printf(seq, " %-17s %-5s %-17s [o] (%-6s)\n",
"Client", "VID", "Originator", "CRC"); "Client", "VID", "Originator", "CRC");
for (i = 0; i < hash->size; i++) { for (i = 0; i < hash->size; i++) {
head = &hash->table[i]; head = &hash->table[i];
@ -1638,7 +1634,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
hlist_for_each_entry_rcu(claim, node, head, hash_entry) { hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
is_own = batadv_compare_eth(claim->backbone_gw->orig, is_own = batadv_compare_eth(claim->backbone_gw->orig,
primary_addr); primary_addr);
seq_printf(seq, " * %pM on % 5d by %pM [%c] (%04x)\n", seq_printf(seq, " * %pM on % 5d by %pM [%c] (%#.4x)\n",
claim->addr, claim->vid, claim->addr, claim->vid,
claim->backbone_gw->orig, claim->backbone_gw->orig,
(is_own ? 'x' : ' '), (is_own ? 'x' : ' '),
@ -1672,10 +1668,10 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
primary_addr = primary_if->net_dev->dev_addr; primary_addr = primary_if->net_dev->dev_addr;
seq_printf(seq, seq_printf(seq,
"Backbones announced for the mesh %s (orig %pM, group id %04x)\n", "Backbones announced for the mesh %s (orig %pM, group id %#.4x)\n",
net_dev->name, primary_addr, net_dev->name, primary_addr,
ntohs(bat_priv->bla.claim_dest.group)); ntohs(bat_priv->bla.claim_dest.group));
seq_printf(seq, " %-17s %-5s %-9s (%-4s)\n", seq_printf(seq, " %-17s %-5s %-9s (%-6s)\n",
"Originator", "VID", "last seen", "CRC"); "Originator", "VID", "last seen", "CRC");
for (i = 0; i < hash->size; i++) { for (i = 0; i < hash->size; i++) {
head = &hash->table[i]; head = &hash->table[i];
@ -1693,7 +1689,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
continue; continue;
seq_printf(seq, seq_printf(seq,
" * %pM on % 5d % 4i.%03is (%04x)\n", " * %pM on % 5d % 4i.%03is (%#.4x)\n",
backbone_gw->orig, backbone_gw->vid, backbone_gw->orig, backbone_gw->vid,
secs, msecs, backbone_gw->crc); secs, msecs, backbone_gw->crc);
} }

View File

@ -164,7 +164,6 @@ static ssize_t batadv_log_read(struct file *file, char __user *buf,
buf++; buf++;
i++; i++;
} }
spin_unlock_bh(&debug_log->lock); spin_unlock_bh(&debug_log->lock);
@ -230,7 +229,6 @@ static void batadv_debug_log_cleanup(struct batadv_priv *bat_priv)
#else /* CONFIG_BATMAN_ADV_DEBUG */ #else /* CONFIG_BATMAN_ADV_DEBUG */
static int batadv_debug_log_setup(struct batadv_priv *bat_priv) static int batadv_debug_log_setup(struct batadv_priv *bat_priv)
{ {
bat_priv->debug_log = NULL;
return 0; return 0;
} }
@ -397,10 +395,8 @@ err:
void batadv_debugfs_destroy(void) void batadv_debugfs_destroy(void)
{ {
if (batadv_debugfs) { debugfs_remove_recursive(batadv_debugfs);
debugfs_remove_recursive(batadv_debugfs); batadv_debugfs = NULL;
batadv_debugfs = NULL;
}
} }
int batadv_debugfs_add_meshif(struct net_device *dev) int batadv_debugfs_add_meshif(struct net_device *dev)

View File

@ -89,7 +89,7 @@ static inline void batadv_hash_delete(struct batadv_hashtable *hash,
* *
* Returns the new hash value. * Returns the new hash value.
*/ */
static inline uint32_t batadv_hash_bytes(uint32_t hash, void *data, static inline uint32_t batadv_hash_bytes(uint32_t hash, const void *data,
uint32_t size) uint32_t size)
{ {
const unsigned char *key = data; const unsigned char *key = data;

View File

@ -41,7 +41,7 @@
* -> TODO: check influence on BATADV_TQ_LOCAL_WINDOW_SIZE * -> TODO: check influence on BATADV_TQ_LOCAL_WINDOW_SIZE
*/ */
#define BATADV_PURGE_TIMEOUT 200000 /* 200 seconds */ #define BATADV_PURGE_TIMEOUT 200000 /* 200 seconds */
#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */ #define BATADV_TT_LOCAL_TIMEOUT 600000 /* in milliseconds */
#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */ #define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */
#define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */ #define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */
#define BATADV_DAT_ENTRY_TIMEOUT (5*60000) /* 5 mins in milliseconds */ #define BATADV_DAT_ENTRY_TIMEOUT (5*60000) /* 5 mins in milliseconds */
@ -276,9 +276,7 @@ static inline bool batadv_has_timed_out(unsigned long timestamp,
static inline void batadv_add_counter(struct batadv_priv *bat_priv, size_t idx, static inline void batadv_add_counter(struct batadv_priv *bat_priv, size_t idx,
size_t count) size_t count)
{ {
int cpu = get_cpu(); this_cpu_add(bat_priv->bat_counters[idx], count);
per_cpu_ptr(bat_priv->bat_counters, cpu)[idx] += count;
put_cpu();
} }
#define batadv_inc_counter(b, i) batadv_add_counter(b, i, 1) #define batadv_inc_counter(b, i) batadv_add_counter(b, i, 1)

View File

@ -29,6 +29,9 @@
#include "soft-interface.h" #include "soft-interface.h"
#include "bridge_loop_avoidance.h" #include "bridge_loop_avoidance.h"
/* hash class keys */
static struct lock_class_key batadv_orig_hash_lock_class_key;
static void batadv_purge_orig(struct work_struct *work); static void batadv_purge_orig(struct work_struct *work);
static void batadv_start_purge_timer(struct batadv_priv *bat_priv) static void batadv_start_purge_timer(struct batadv_priv *bat_priv)
@ -57,6 +60,9 @@ int batadv_originator_init(struct batadv_priv *bat_priv)
if (!bat_priv->orig_hash) if (!bat_priv->orig_hash)
goto err; goto err;
batadv_hash_set_lock_class(bat_priv->orig_hash,
&batadv_orig_hash_lock_class_key);
batadv_start_purge_timer(bat_priv); batadv_start_purge_timer(bat_priv);
return 0; return 0;
@ -178,7 +184,6 @@ void batadv_originator_free(struct batadv_priv *bat_priv)
spin_lock_bh(list_lock); spin_lock_bh(list_lock);
hlist_for_each_entry_safe(orig_node, node, node_tmp, hlist_for_each_entry_safe(orig_node, node, node_tmp,
head, hash_entry) { head, hash_entry) {
hlist_del_rcu(node); hlist_del_rcu(node);
batadv_orig_node_free_ref(orig_node); batadv_orig_node_free_ref(orig_node);
} }
@ -285,7 +290,6 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
/* for all neighbors towards this originator ... */ /* for all neighbors towards this originator ... */
hlist_for_each_entry_safe(neigh_node, node, node_tmp, hlist_for_each_entry_safe(neigh_node, node, node_tmp,
&orig_node->neigh_list, list) { &orig_node->neigh_list, list) {
last_seen = neigh_node->last_seen; last_seen = neigh_node->last_seen;
if_incoming = neigh_node->if_incoming; if_incoming = neigh_node->if_incoming;
@ -293,7 +297,6 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
(if_incoming->if_status == BATADV_IF_INACTIVE) || (if_incoming->if_status == BATADV_IF_INACTIVE) ||
(if_incoming->if_status == BATADV_IF_NOT_IN_USE) || (if_incoming->if_status == BATADV_IF_NOT_IN_USE) ||
(if_incoming->if_status == BATADV_IF_TO_BE_REMOVED)) { (if_incoming->if_status == BATADV_IF_TO_BE_REMOVED)) {
if ((if_incoming->if_status == BATADV_IF_INACTIVE) || if ((if_incoming->if_status == BATADV_IF_INACTIVE) ||
(if_incoming->if_status == BATADV_IF_NOT_IN_USE) || (if_incoming->if_status == BATADV_IF_NOT_IN_USE) ||
(if_incoming->if_status == BATADV_IF_TO_BE_REMOVED)) (if_incoming->if_status == BATADV_IF_TO_BE_REMOVED))

View File

@ -80,7 +80,6 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
/* route added */ /* route added */
} else if ((!curr_router) && (neigh_node)) { } else if ((!curr_router) && (neigh_node)) {
batadv_dbg(BATADV_DBG_ROUTES, bat_priv, batadv_dbg(BATADV_DBG_ROUTES, bat_priv,
"Adding route towards: %pM (via %pM)\n", "Adding route towards: %pM (via %pM)\n",
orig_node->orig, neigh_node->addr); orig_node->orig, neigh_node->addr);
@ -172,7 +171,6 @@ void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node,
*/ */
hlist_for_each_entry_rcu(tmp_neigh_node, node, hlist_for_each_entry_rcu(tmp_neigh_node, node,
&orig_node->neigh_list, list) { &orig_node->neigh_list, list) {
if (tmp_neigh_node == neigh_node) if (tmp_neigh_node == neigh_node)
continue; continue;
@ -836,7 +834,6 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
if (unicast_packet->header.packet_type == BATADV_UNICAST_FRAG && if (unicast_packet->header.packet_type == BATADV_UNICAST_FRAG &&
batadv_frag_can_reassemble(skb, batadv_frag_can_reassemble(skb,
neigh_node->if_incoming->net_dev->mtu)) { neigh_node->if_incoming->net_dev->mtu)) {
ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb); ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
if (ret == NET_RX_DROP) if (ret == NET_RX_DROP)
@ -1103,7 +1100,6 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
/* packet for me */ /* packet for me */
if (batadv_is_my_mac(unicast_packet->dest)) { if (batadv_is_my_mac(unicast_packet->dest)) {
ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb); ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
if (ret == NET_RX_DROP) if (ret == NET_RX_DROP)

View File

@ -330,7 +330,6 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
spin_lock_bh(&bat_priv->forw_bcast_list_lock); spin_lock_bh(&bat_priv->forw_bcast_list_lock);
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
&bat_priv->forw_bcast_list, list) { &bat_priv->forw_bcast_list, list) {
/* if purge_outstanding_packets() was called with an argument /* if purge_outstanding_packets() was called with an argument
* we delete only packets belonging to the given interface * we delete only packets belonging to the given interface
*/ */
@ -357,7 +356,6 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
spin_lock_bh(&bat_priv->forw_bat_list_lock); spin_lock_bh(&bat_priv->forw_bat_list_lock);
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
&bat_priv->forw_bat_list, list) { &bat_priv->forw_bat_list, list) {
/* if purge_outstanding_packets() was called with an argument /* if purge_outstanding_packets() was called with an argument
* we delete only packets belonging to the given interface * we delete only packets belonging to the given interface
*/ */

View File

@ -180,7 +180,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
goto dropped; goto dropped;
/* Register the client MAC in the transtable */ /* Register the client MAC in the transtable */
batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); if (!is_multicast_ether_addr(ethhdr->h_source))
batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
/* don't accept stp packets. STP does not help in meshes. /* don't accept stp packets. STP does not help in meshes.
* better use the bridge loop avoidance ... * better use the bridge loop avoidance ...
@ -479,7 +480,9 @@ struct net_device *batadv_softif_create(const char *name)
atomic_set(&bat_priv->aggregated_ogms, 1); atomic_set(&bat_priv->aggregated_ogms, 1);
atomic_set(&bat_priv->bonding, 0); atomic_set(&bat_priv->bonding, 0);
#ifdef CONFIG_BATMAN_ADV_BLA
atomic_set(&bat_priv->bridge_loop_avoidance, 0); atomic_set(&bat_priv->bridge_loop_avoidance, 0);
#endif
#ifdef CONFIG_BATMAN_ADV_DAT #ifdef CONFIG_BATMAN_ADV_DAT
atomic_set(&bat_priv->distributed_arp_table, 1); atomic_set(&bat_priv->distributed_arp_table, 1);
#endif #endif
@ -490,7 +493,9 @@ struct net_device *batadv_softif_create(const char *name)
atomic_set(&bat_priv->gw_bandwidth, 41); atomic_set(&bat_priv->gw_bandwidth, 41);
atomic_set(&bat_priv->orig_interval, 1000); atomic_set(&bat_priv->orig_interval, 1000);
atomic_set(&bat_priv->hop_penalty, 30); atomic_set(&bat_priv->hop_penalty, 30);
#ifdef CONFIG_BATMAN_ADV_DEBUG
atomic_set(&bat_priv->log_level, 0); atomic_set(&bat_priv->log_level, 0);
#endif
atomic_set(&bat_priv->fragmentation, 1); atomic_set(&bat_priv->fragmentation, 1);
atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);

View File

@ -29,6 +29,10 @@
#include <linux/crc16.h> #include <linux/crc16.h>
/* hash class keys */
static struct lock_class_key batadv_tt_local_hash_lock_class_key;
static struct lock_class_key batadv_tt_global_hash_lock_class_key;
static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
struct batadv_orig_node *orig_node); struct batadv_orig_node *orig_node);
static void batadv_tt_purge(struct work_struct *work); static void batadv_tt_purge(struct work_struct *work);
@ -112,7 +116,6 @@ batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data)
struct batadv_tt_global_entry, struct batadv_tt_global_entry,
common); common);
return tt_global_entry; return tt_global_entry;
} }
static void static void
@ -235,6 +238,9 @@ static int batadv_tt_local_init(struct batadv_priv *bat_priv)
if (!bat_priv->tt.local_hash) if (!bat_priv->tt.local_hash)
return -ENOMEM; return -ENOMEM;
batadv_hash_set_lock_class(bat_priv->tt.local_hash,
&batadv_tt_local_hash_lock_class_key);
return 0; return 0;
} }
@ -249,7 +255,6 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv,
batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt, batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
batadv_choose_orig, tt_global->common.addr); batadv_choose_orig, tt_global->common.addr);
batadv_tt_global_entry_free_ref(tt_global); batadv_tt_global_entry_free_ref(tt_global);
} }
void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
@ -305,7 +310,11 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
(uint8_t)atomic_read(&bat_priv->tt.vn)); (uint8_t)atomic_read(&bat_priv->tt.vn));
memcpy(tt_local->common.addr, addr, ETH_ALEN); memcpy(tt_local->common.addr, addr, ETH_ALEN);
tt_local->common.flags = BATADV_NO_FLAGS; /* The local entry has to be marked as NEW to avoid to send it in
* a full table response going out before the next ttvn increment
* (consistency check)
*/
tt_local->common.flags = BATADV_TT_CLIENT_NEW;
if (batadv_is_wifi_iface(ifindex)) if (batadv_is_wifi_iface(ifindex))
tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
atomic_set(&tt_local->common.refcount, 2); atomic_set(&tt_local->common.refcount, 2);
@ -316,12 +325,6 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
if (batadv_compare_eth(addr, soft_iface->dev_addr)) if (batadv_compare_eth(addr, soft_iface->dev_addr))
tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE; tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
/* The local entry has to be marked as NEW to avoid to send it in
* a full table response going out before the next ttvn increment
* (consistency check)
*/
tt_local->common.flags |= BATADV_TT_CLIENT_NEW;
hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt, hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
batadv_choose_orig, &tt_local->common, batadv_choose_orig, &tt_local->common,
&tt_local->common.hash_entry); &tt_local->common.hash_entry);
@ -472,18 +475,27 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
struct batadv_priv *bat_priv = netdev_priv(net_dev); struct batadv_priv *bat_priv = netdev_priv(net_dev);
struct batadv_hashtable *hash = bat_priv->tt.local_hash; struct batadv_hashtable *hash = bat_priv->tt.local_hash;
struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_common_entry *tt_common_entry;
struct batadv_tt_local_entry *tt_local;
struct batadv_hard_iface *primary_if; struct batadv_hard_iface *primary_if;
struct hlist_node *node; struct hlist_node *node;
struct hlist_head *head; struct hlist_head *head;
uint32_t i; uint32_t i;
int last_seen_secs;
int last_seen_msecs;
unsigned long last_seen_jiffies;
bool no_purge;
uint16_t np_flag = BATADV_TT_CLIENT_NOPURGE;
primary_if = batadv_seq_print_text_primary_if_get(seq); primary_if = batadv_seq_print_text_primary_if_get(seq);
if (!primary_if) if (!primary_if)
goto out; goto out;
seq_printf(seq, seq_printf(seq,
"Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", "Locally retrieved addresses (from %s) announced via TT (TTVN: %u CRC: %#.4x):\n",
net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn)); net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn),
bat_priv->tt.local_crc);
seq_printf(seq, " %-13s %-7s %-10s\n", "Client", "Flags",
"Last seen");
for (i = 0; i < hash->size; i++) { for (i = 0; i < hash->size; i++) {
head = &hash->table[i]; head = &hash->table[i];
@ -491,18 +503,29 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(tt_common_entry, node, hlist_for_each_entry_rcu(tt_common_entry, node,
head, hash_entry) { head, hash_entry) {
seq_printf(seq, " * %pM [%c%c%c%c%c]\n", tt_local = container_of(tt_common_entry,
struct batadv_tt_local_entry,
common);
last_seen_jiffies = jiffies - tt_local->last_seen;
last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
last_seen_secs = last_seen_msecs / 1000;
last_seen_msecs = last_seen_msecs % 1000;
no_purge = tt_common_entry->flags & np_flag;
seq_printf(seq, " * %pM [%c%c%c%c%c] %3u.%03u\n",
tt_common_entry->addr, tt_common_entry->addr,
(tt_common_entry->flags & (tt_common_entry->flags &
BATADV_TT_CLIENT_ROAM ? 'R' : '.'), BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
(tt_common_entry->flags & no_purge ? 'P' : '.',
BATADV_TT_CLIENT_NOPURGE ? 'P' : '.'),
(tt_common_entry->flags & (tt_common_entry->flags &
BATADV_TT_CLIENT_NEW ? 'N' : '.'), BATADV_TT_CLIENT_NEW ? 'N' : '.'),
(tt_common_entry->flags & (tt_common_entry->flags &
BATADV_TT_CLIENT_PENDING ? 'X' : '.'), BATADV_TT_CLIENT_PENDING ? 'X' : '.'),
(tt_common_entry->flags & (tt_common_entry->flags &
BATADV_TT_CLIENT_WIFI ? 'W' : '.')); BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
no_purge ? last_seen_secs : 0,
no_purge ? last_seen_msecs : 0);
} }
rcu_read_unlock(); rcu_read_unlock();
} }
@ -627,7 +650,6 @@ static void batadv_tt_local_purge(struct batadv_priv *bat_priv)
batadv_tt_local_purge_list(bat_priv, head); batadv_tt_local_purge_list(bat_priv, head);
spin_unlock_bh(list_lock); spin_unlock_bh(list_lock);
} }
} }
static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
@ -676,6 +698,9 @@ static int batadv_tt_global_init(struct batadv_priv *bat_priv)
if (!bat_priv->tt.global_hash) if (!bat_priv->tt.global_hash)
return -ENOMEM; return -ENOMEM;
batadv_hash_set_lock_class(bat_priv->tt.global_hash,
&batadv_tt_global_hash_lock_class_key);
return 0; return 0;
} }
@ -967,10 +992,11 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
best_entry = batadv_transtable_best_orig(tt_global_entry); best_entry = batadv_transtable_best_orig(tt_global_entry);
if (best_entry) { if (best_entry) {
last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn); last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
seq_printf(seq, " %c %pM (%3u) via %pM (%3u) [%c%c%c]\n", seq_printf(seq,
" %c %pM (%3u) via %pM (%3u) (%#.4x) [%c%c%c]\n",
'*', tt_global_entry->common.addr, '*', tt_global_entry->common.addr,
best_entry->ttvn, best_entry->orig_node->orig, best_entry->ttvn, best_entry->orig_node->orig,
last_ttvn, last_ttvn, best_entry->orig_node->tt_crc,
(flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
(flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'), (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
(flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.')); (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
@ -1012,8 +1038,9 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, seq_printf(seq,
"Globally announced TT entries received via the mesh %s\n", "Globally announced TT entries received via the mesh %s\n",
net_dev->name); net_dev->name);
seq_printf(seq, " %-13s %s %-15s %s %s\n", seq_printf(seq, " %-13s %s %-15s %s (%-6s) %s\n",
"Client", "(TTVN)", "Originator", "(Curr TTVN)", "Flags"); "Client", "(TTVN)", "Originator", "(Curr TTVN)", "CRC",
"Flags");
for (i = 0; i < hash->size; i++) { for (i = 0; i < hash->size; i++) {
head = &hash->table[i]; head = &hash->table[i];
@ -1049,7 +1076,6 @@ batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
batadv_tt_orig_list_entry_free_ref(orig_entry); batadv_tt_orig_list_entry_free_ref(orig_entry);
} }
spin_unlock_bh(&tt_global_entry->list_lock); spin_unlock_bh(&tt_global_entry->list_lock);
} }
static void static void
@ -1825,7 +1851,6 @@ out:
if (!ret) if (!ret)
kfree_skb(skb); kfree_skb(skb);
return ret; return ret;
} }
static bool static bool
@ -2352,7 +2377,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
} }
spin_unlock_bh(list_lock); spin_unlock_bh(list_lock);
} }
} }
static int batadv_tt_commit_changes(struct batadv_priv *bat_priv, static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
@ -2496,7 +2520,7 @@ void batadv_tt_update_orig(struct batadv_priv *bat_priv,
orig_node->tt_crc != tt_crc) { orig_node->tt_crc != tt_crc) {
request_table: request_table:
batadv_dbg(BATADV_DBG_TT, bat_priv, batadv_dbg(BATADV_DBG_TT, bat_priv,
"TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %u last_crc: %u num_changes: %u)\n", "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %#.4x last_crc: %#.4x num_changes: %u)\n",
orig_node->orig, ttvn, orig_ttvn, tt_crc, orig_node->orig, ttvn, orig_ttvn, tt_crc,
orig_node->tt_crc, tt_num_changes); orig_node->tt_crc, tt_num_changes);
batadv_send_tt_request(bat_priv, orig_node, ttvn, batadv_send_tt_request(bat_priv, orig_node, ttvn,
@ -2549,7 +2573,6 @@ bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
batadv_tt_local_entry_free_ref(tt_local_entry); batadv_tt_local_entry_free_ref(tt_local_entry);
out: out:
return ret; return ret;
} }
bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,

View File

@ -119,7 +119,6 @@ struct batadv_orig_node {
spinlock_t ogm_cnt_lock; spinlock_t ogm_cnt_lock;
/* bcast_seqno_lock protects bcast_bits, last_bcast_seqno */ /* bcast_seqno_lock protects bcast_bits, last_bcast_seqno */
spinlock_t bcast_seqno_lock; spinlock_t bcast_seqno_lock;
spinlock_t tt_list_lock; /* protects tt_list */
atomic_t bond_candidates; atomic_t bond_candidates;
struct list_head bond_list; struct list_head bond_list;
}; };
@ -273,7 +272,9 @@ struct batadv_priv {
atomic_t bonding; /* boolean */ atomic_t bonding; /* boolean */
atomic_t fragmentation; /* boolean */ atomic_t fragmentation; /* boolean */
atomic_t ap_isolation; /* boolean */ atomic_t ap_isolation; /* boolean */
#ifdef CONFIG_BATMAN_ADV_BLA
atomic_t bridge_loop_avoidance; /* boolean */ atomic_t bridge_loop_avoidance; /* boolean */
#endif
#ifdef CONFIG_BATMAN_ADV_DAT #ifdef CONFIG_BATMAN_ADV_DAT
atomic_t distributed_arp_table; /* boolean */ atomic_t distributed_arp_table; /* boolean */
#endif #endif
@ -283,12 +284,16 @@ struct batadv_priv {
atomic_t gw_bandwidth; /* gw bandwidth */ atomic_t gw_bandwidth; /* gw bandwidth */
atomic_t orig_interval; /* uint */ atomic_t orig_interval; /* uint */
atomic_t hop_penalty; /* uint */ atomic_t hop_penalty; /* uint */
#ifdef CONFIG_BATMAN_ADV_DEBUG
atomic_t log_level; /* uint */ atomic_t log_level; /* uint */
#endif
atomic_t bcast_seqno; atomic_t bcast_seqno;
atomic_t bcast_queue_left; atomic_t bcast_queue_left;
atomic_t batman_queue_left; atomic_t batman_queue_left;
char num_ifaces; char num_ifaces;
#ifdef CONFIG_BATMAN_ADV_DEBUG
struct batadv_debug_log *debug_log; struct batadv_debug_log *debug_log;
#endif
struct kobject *mesh_obj; struct kobject *mesh_obj;
struct dentry *debug_dir; struct dentry *debug_dir;
struct hlist_head forw_bat_list; struct hlist_head forw_bat_list;

View File

@ -133,7 +133,6 @@ batadv_frag_search_packet(struct list_head *head,
is_head = !!(up->flags & BATADV_UNI_FRAG_HEAD); is_head = !!(up->flags & BATADV_UNI_FRAG_HEAD);
list_for_each_entry(tfp, head, list) { list_for_each_entry(tfp, head, list) {
if (!tfp->skb) if (!tfp->skb)
continue; continue;
@ -162,7 +161,6 @@ void batadv_frag_list_free(struct list_head *head)
struct batadv_frag_packet_list_entry *pf, *tmp_pf; struct batadv_frag_packet_list_entry *pf, *tmp_pf;
if (!list_empty(head)) { if (!list_empty(head)) {
list_for_each_entry_safe(pf, tmp_pf, head, list) { list_for_each_entry_safe(pf, tmp_pf, head, list) {
kfree_skb(pf->skb); kfree_skb(pf->skb);
list_del(&pf->list); list_del(&pf->list);

View File

@ -28,6 +28,9 @@
#define BATADV_MAX_VIS_PACKET_SIZE 1000 #define BATADV_MAX_VIS_PACKET_SIZE 1000
/* hash class keys */
static struct lock_class_key batadv_vis_hash_lock_class_key;
static void batadv_start_vis_timer(struct batadv_priv *bat_priv); static void batadv_start_vis_timer(struct batadv_priv *bat_priv);
/* free the info */ /* free the info */
@ -852,6 +855,9 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
goto err; goto err;
} }
batadv_hash_set_lock_class(bat_priv->vis.hash,
&batadv_vis_hash_lock_class_key);
bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC); bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
if (!bat_priv->vis.my_info) if (!bat_priv->vis.my_info)
goto err; goto err;