Hello David,
this is our set of changes intended for net-next/linux-3.7. It is mostly composed by style fixes and cleanups. Other than that you have a patch introducing a new table in debugfs (backbone gateways table for the Bridge Loop Avoidance) and a new mechanism for the TranslationTable component. The latter allows mesh nodes to immediately detect new clients joining the network, without waiting for any periodic advertisement.
Thank you, Antonio
The following changes since commit 0fa7fa98dbcc2789409ed24e885485e645803d7f:
packet: Protect packet sk list with mutex (v2) (2012-08-22 22:58:27 -0700)
are available in the git repository at:
git://git.open-mesh.org/linux-merge.git tags/batman-adv-for-davem
for you to fetch changes up to fa4f0afcf40361bf67ed3abd520a5fbe12d11166:
batman-adv: Start new development cycle (2012-08-23 14:20:23 +0200)
---------------------------------------------------------------- Included changes: - a set of codestyle rearrangements/fixes - new feature to early detect new joining (mesh-unaware) clients - a minor fix for the gw-feature - substitution of shift operations with the BIT() macro - reorganization of the main batman-adv structure (struct batadv_priv) - some more (very) minor cleanups and fixes
---------------------------------------------------------------- Antonio Quartulli (5): batman-adv: move function arguments on one line batman-adv: add reference counting for type batadv_tt_orig_list_entry batman-adv: fix typos in comments batman-adv: detect not yet announced clients batman-adv: change interface_rx to get orig node
Jonathan Corbet (1): batman-adv: remove a misleading comment
Marek Lindner (1): batman-adv: convert remaining packet counters to per_cpu_ptr() infrastructure
Martin Hundebøll (2): batman-adv: Move batadv_check_unicast_packet() batman-adv: Drop tt queries with foreign dest
Simon Wunderlich (4): batman-adv: Add the backbone gateway list to debugfs batman-adv: correct comments in bridge loop avoidance batman-adv: rename bridge loop avoidance claim types batman-adv: check batadv_orig_hash_add_if() return code
Sven Eckelmann (5): batman-adv: Split batadv_priv in sub-structures for features batman-adv: Use BIT(x) macro to calculate bit positions batman-adv: Don't break statements after assignment operator batman-adv: Reduce accumulated length of simple statements batman-adv: Start new development cycle
Documentation/networking/batman-adv.txt | 7 +- net/batman-adv/bat_iv_ogm.c | 96 ++++--- net/batman-adv/bridge_loop_avoidance.c | 214 ++++++++++------ net/batman-adv/bridge_loop_avoidance.h | 11 +- net/batman-adv/debugfs.c | 12 + net/batman-adv/gateway_client.c | 53 ++-- net/batman-adv/hard-interface.c | 13 +- net/batman-adv/main.c | 27 +- net/batman-adv/main.h | 29 +-- net/batman-adv/packet.h | 35 +-- net/batman-adv/routing.c | 85 +++---- net/batman-adv/send.c | 8 +- net/batman-adv/soft-interface.c | 79 +++--- net/batman-adv/soft-interface.h | 5 +- net/batman-adv/translation-table.c | 416 +++++++++++++++++++------------ net/batman-adv/translation-table.h | 4 +- net/batman-adv/types.h | 120 +++++---- net/batman-adv/unicast.c | 16 +- net/batman-adv/vis.c | 144 +++++------ net/batman-adv/vis.h | 2 +- 20 files changed, 818 insertions(+), 558 deletions(-)
Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/bridge_loop_avoidance.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index 563cfbf..3f0dfa2 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h @@ -41,8 +41,7 @@ void batadv_bla_free(struct batadv_priv *bat_priv); #else /* ifdef CONFIG_BATMAN_ADV_BLA */
static inline int batadv_bla_rx(struct batadv_priv *bat_priv, - struct sk_buff *skb, short vid, - bool is_bcast) + struct sk_buff *skb, short vid, bool is_bcast) { return 0; }
From: Simon Wunderlich simon.wunderlich@s2003.tu-chemnitz.de
This is especially useful if there are no claims yet, but we still want to know which gateways are using bridge loop avoidance in the network.
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Antonio Quartulli ordex@autistici.org --- Documentation/networking/batman-adv.txt | 7 ++-- net/batman-adv/bridge_loop_avoidance.c | 65 +++++++++++++++++++++++++++++++ net/batman-adv/bridge_loop_avoidance.h | 8 ++++ net/batman-adv/debugfs.c | 12 ++++++ 4 files changed, 89 insertions(+), 3 deletions(-)
diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt index 8f3ae4a..a173d2a 100644 --- a/Documentation/networking/batman-adv.txt +++ b/Documentation/networking/batman-adv.txt @@ -75,9 +75,10 @@ folder:
There is a special folder for debugging information:
-# ls /sys/kernel/debug/batman_adv/bat0/ -# bla_claim_table log socket transtable_local -# gateways originators transtable_global vis_data +# ls /sys/kernel/debug/batman_adv/bat0/ +# bla_backbone_table log transtable_global +# bla_claim_table originators transtable_local +# gateways socket vis_data
Some of the files contain all sort of status information regard- ing the mesh network. For example, you can view the table of diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 6705d35..7e60466 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1616,3 +1616,68 @@ out: batadv_hardif_free_ref(primary_if); return ret; } + +int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) +{ + struct net_device *net_dev = (struct net_device *)seq->private; + struct batadv_priv *bat_priv = netdev_priv(net_dev); + struct batadv_hashtable *hash = bat_priv->backbone_hash; + struct batadv_backbone_gw *backbone_gw; + struct batadv_hard_iface *primary_if; + struct hlist_node *node; + struct hlist_head *head; + int secs, msecs; + uint32_t i; + bool is_own; + int ret = 0; + uint8_t *primary_addr; + + primary_if = batadv_primary_if_get_selected(bat_priv); + if (!primary_if) { + ret = seq_printf(seq, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + goto out; + } + + if (primary_if->if_status != BATADV_IF_ACTIVE) { + ret = seq_printf(seq, + "BATMAN mesh %s disabled - primary interface not active\n", + net_dev->name); + goto out; + } + + primary_addr = primary_if->net_dev->dev_addr; + seq_printf(seq, + "Backbones announced for the mesh %s (orig %pM, group id %04x)\n", + net_dev->name, primary_addr, + ntohs(bat_priv->claim_dest.group)); + seq_printf(seq, " %-17s %-5s %-9s (%-4s)\n", + "Originator", "VID", "last seen", "CRC"); + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + rcu_read_lock(); + hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { + msecs = jiffies_to_msecs(jiffies - + backbone_gw->lasttime); + secs = msecs / 1000; + msecs = msecs % 1000; + + is_own = batadv_compare_eth(backbone_gw->orig, + primary_addr); + if (is_own) + continue; + + seq_printf(seq, + " * %pM on % 5d % 4i.%03is (%04x)\n", + backbone_gw->orig, backbone_gw->vid, + secs, msecs, backbone_gw->crc); + } + rcu_read_unlock(); + } +out: + if (primary_if) + batadv_hardif_free_ref(primary_if); + return ret; +} diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index 3f0dfa2..789cb73 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h @@ -27,6 +27,8 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid); int batadv_bla_is_backbone_gw(struct sk_buff *skb, struct batadv_orig_node *orig_node, int hdr_size); int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); +int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, + void *offset); int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig); int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, struct batadv_bcast_packet *bcast_packet, @@ -65,6 +67,12 @@ static inline int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, return 0; }
+static inline int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, + void *offset) +{ + return 0; +} + static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig) { diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c index 34fbb16..391d4fb 100644 --- a/net/batman-adv/debugfs.c +++ b/net/batman-adv/debugfs.c @@ -267,6 +267,15 @@ static int batadv_bla_claim_table_open(struct inode *inode, struct file *file) return single_open(file, batadv_bla_claim_table_seq_print_text, net_dev); } + +static int batadv_bla_backbone_table_open(struct inode *inode, + struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, batadv_bla_backbone_table_seq_print_text, + net_dev); +} + #endif
static int batadv_transtable_local_open(struct inode *inode, struct file *file) @@ -305,6 +314,8 @@ static BATADV_DEBUGINFO(transtable_global, S_IRUGO, batadv_transtable_global_open); #ifdef CONFIG_BATMAN_ADV_BLA static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open); +static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO, + batadv_bla_backbone_table_open); #endif static BATADV_DEBUGINFO(transtable_local, S_IRUGO, batadv_transtable_local_open); @@ -316,6 +327,7 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { &batadv_debuginfo_transtable_global, #ifdef CONFIG_BATMAN_ADV_BLA &batadv_debuginfo_bla_claim_table, + &batadv_debuginfo_bla_backbone_table, #endif &batadv_debuginfo_transtable_local, &batadv_debuginfo_vis_data,
From: Simon Wunderlich simon.wunderlich@s2003.tu-chemnitz.de
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/bridge_loop_avoidance.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 7e60466..5f1ad80 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -281,7 +281,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, NULL, /* Ethernet SRC/HW SRC: originator mac */ primary_if->net_dev->dev_addr, - /* HW DST: FF:43:05:XX:00:00 + /* HW DST: FF:43:05:XX:YY:YY * with XX = claim type * and YY:YY = group id */ @@ -323,7 +323,8 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, break; case BATADV_CLAIM_TYPE_REQUEST: /* request frame - * set HW SRC to the special mac containg the crc + * set HW SRC and header destination to the receiving backbone + * gws mac */ memcpy(hw_src, mac, ETH_ALEN); memcpy(ethhdr->h_dest, mac, ETH_ALEN);
From: Simon Wunderlich simon.wunderlich@s2003.tu-chemnitz.de
for consistency reasons within the code and with the documentation, we should always call it "claim" and "unclaim".
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/bridge_loop_avoidance.c | 18 +++++++++--------- net/batman-adv/packet.h | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 5f1ad80..84dd841 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -295,7 +295,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
/* now we pretend that the client would have sent this ... */ switch (claimtype) { - case BATADV_CLAIM_TYPE_ADD: + case BATADV_CLAIM_TYPE_CLAIM: /* normal claim frame * set Ethernet SRC to the clients mac */ @@ -303,7 +303,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid); break; - case BATADV_CLAIM_TYPE_DEL: + case BATADV_CLAIM_TYPE_UNCLAIM: /* unclaim frame * set HW SRC to the clients mac */ @@ -468,7 +468,7 @@ static void batadv_bla_answer_request(struct batadv_priv *bat_priv, continue;
batadv_bla_send_claim(bat_priv, claim->addr, claim->vid, - BATADV_CLAIM_TYPE_ADD); + BATADV_CLAIM_TYPE_CLAIM); } rcu_read_unlock(); } @@ -703,7 +703,7 @@ static int batadv_handle_unclaim(struct batadv_priv *bat_priv, if (primary_if && batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) batadv_bla_send_claim(bat_priv, claim_addr, vid, - BATADV_CLAIM_TYPE_DEL); + BATADV_CLAIM_TYPE_UNCLAIM);
backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid);
@@ -739,7 +739,7 @@ static int batadv_handle_claim(struct batadv_priv *bat_priv, batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) batadv_bla_send_claim(bat_priv, claim_addr, vid, - BATADV_CLAIM_TYPE_ADD); + BATADV_CLAIM_TYPE_CLAIM);
/* TODO: we could call something like tt_local_del() here. */
@@ -784,12 +784,12 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv, * otherwise assume it is in the hw_src */ switch (bla_dst->type) { - case BATADV_CLAIM_TYPE_ADD: + case BATADV_CLAIM_TYPE_CLAIM: backbone_addr = hw_src; break; case BATADV_CLAIM_TYPE_REQUEST: case BATADV_CLAIM_TYPE_ANNOUNCE: - case BATADV_CLAIM_TYPE_DEL: + case BATADV_CLAIM_TYPE_UNCLAIM: backbone_addr = ethhdr->h_source; break; default: @@ -905,12 +905,12 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
/* check for the different types of claim frames ... */ switch (bla_dst->type) { - case BATADV_CLAIM_TYPE_ADD: + case BATADV_CLAIM_TYPE_CLAIM: if (batadv_handle_claim(bat_priv, primary_if, hw_src, ethhdr->h_source, vid)) return 1; break; - case BATADV_CLAIM_TYPE_DEL: + case BATADV_CLAIM_TYPE_UNCLAIM: if (batadv_handle_unclaim(bat_priv, primary_if, ethhdr->h_source, hw_src, vid)) return 1; diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 8d3e55a..65d66e4 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -92,8 +92,8 @@ enum batadv_tt_client_flags {
/* claim frame types for the bridge loop avoidance */ enum batadv_bla_claimframe { - BATADV_CLAIM_TYPE_ADD = 0x00, - BATADV_CLAIM_TYPE_DEL = 0x01, + BATADV_CLAIM_TYPE_CLAIM = 0x00, + BATADV_CLAIM_TYPE_UNCLAIM = 0x01, BATADV_CLAIM_TYPE_ANNOUNCE = 0x02, BATADV_CLAIM_TYPE_REQUEST = 0x03, };
From: Marek Lindner lindner_marek@yahoo.de
Signed-off-by: Marek Lindner lindner_marek@yahoo.de Acked-by: Martin Hundebøll martin@hundeboll.net Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/bridge_loop_avoidance.c | 5 ++-- net/batman-adv/soft-interface.c | 51 +++++++++++++++++++++----------- net/batman-adv/types.h | 5 ++++ 3 files changed, 42 insertions(+), 19 deletions(-)
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 84dd841..c9732ac 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -340,8 +340,9 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
skb_reset_mac_header(skb); skb->protocol = eth_type_trans(skb, soft_iface); - bat_priv->stats.rx_packets++; - bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; + batadv_inc_counter(bat_priv, BATADV_CNT_RX); + batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, + skb->len + ETH_HLEN); soft_iface->last_rx = jiffies;
netif_rx(skb); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 109ea2a..2b3842b 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -93,7 +93,14 @@ static int batadv_interface_release(struct net_device *dev) static struct net_device_stats *batadv_interface_stats(struct net_device *dev) { struct batadv_priv *bat_priv = netdev_priv(dev); - return &bat_priv->stats; + struct net_device_stats *stats = &bat_priv->stats; + + stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX); + stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES); + stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED); + stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX); + stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES); + return stats; }
static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) @@ -246,14 +253,14 @@ static int batadv_interface_tx(struct sk_buff *skb, goto dropped_freed; }
- bat_priv->stats.tx_packets++; - bat_priv->stats.tx_bytes += data_len; + batadv_inc_counter(bat_priv, BATADV_CNT_TX); + batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len); goto end;
dropped: kfree_skb(skb); dropped_freed: - bat_priv->stats.tx_dropped++; + batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED); end: if (primary_if) batadv_hardif_free_ref(primary_if); @@ -308,8 +315,9 @@ void batadv_interface_rx(struct net_device *soft_iface,
/* skb->ip_summed = CHECKSUM_UNNECESSARY; */
- bat_priv->stats.rx_packets++; - bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; + batadv_inc_counter(bat_priv, BATADV_CNT_RX); + batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, + skb->len + ETH_HLEN);
soft_iface->last_rx = jiffies;
@@ -379,15 +387,22 @@ struct net_device *batadv_softif_create(const char *name) if (!soft_iface) goto out;
+ bat_priv = netdev_priv(soft_iface); + + /* batadv_interface_stats() needs to be available as soon as + * register_netdevice() has been called + */ + bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); + if (!bat_priv->bat_counters) + goto free_soft_iface; + ret = register_netdevice(soft_iface); if (ret < 0) { pr_err("Unable to register the batman interface '%s': %i\n", name, ret); - goto free_soft_iface; + goto free_bat_counters; }
- bat_priv = netdev_priv(soft_iface); - atomic_set(&bat_priv->aggregated_ogms, 1); atomic_set(&bat_priv->bonding, 0); atomic_set(&bat_priv->bridge_loop_avoidance, 0); @@ -417,17 +432,13 @@ struct net_device *batadv_softif_create(const char *name) bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0;
- bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); - if (!bat_priv->bat_counters) - goto unreg_soft_iface; - ret = batadv_algo_select(bat_priv, batadv_routing_algo); if (ret < 0) - goto free_bat_counters; + goto unreg_soft_iface;
ret = batadv_sysfs_add_meshif(soft_iface); if (ret < 0) - goto free_bat_counters; + goto unreg_soft_iface;
ret = batadv_debugfs_add_meshif(soft_iface); if (ret < 0) @@ -443,12 +454,13 @@ unreg_debugfs: batadv_debugfs_del_meshif(soft_iface); unreg_sysfs: batadv_sysfs_del_meshif(soft_iface); -free_bat_counters: - free_percpu(bat_priv->bat_counters); unreg_soft_iface: + free_percpu(bat_priv->bat_counters); unregister_netdevice(soft_iface); return NULL;
+free_bat_counters: + free_percpu(bat_priv->bat_counters); free_soft_iface: free_netdev(soft_iface); out: @@ -518,6 +530,11 @@ static u32 batadv_get_link(struct net_device *dev) static const struct { const char name[ETH_GSTRING_LEN]; } batadv_counters_strings[] = { + { "tx" }, + { "tx_bytes" }, + { "tx_dropped" }, + { "rx" }, + { "rx_bytes" }, { "forward" }, { "forward_bytes" }, { "mgmt_tx" }, diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 12635fd..7812b6e 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -145,6 +145,11 @@ struct batadv_bcast_duplist_entry { #endif
enum batadv_counters { + BATADV_CNT_TX, + BATADV_CNT_TX_BYTES, + BATADV_CNT_TX_DROPPED, + BATADV_CNT_RX, + BATADV_CNT_RX_BYTES, BATADV_CNT_FORWARD, BATADV_CNT_FORWARD_BYTES, BATADV_CNT_MGMT_TX,
From: Jonathan Corbet corbet@lwn.net
As much as I'm happy to see LWN links sprinkled through the kernel by the dozen, this one in particular reflects a very old state of reality; the associated comment is now incorrect. So just delete it.
Signed-off-by: Jonathan Corbet corbet@lwn.net Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/main.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 13c88b2..2a1f243 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -58,9 +58,6 @@ static int __init batadv_init(void)
batadv_iv_init();
- /* the name should not be longer than 10 chars - see - * http://lwn.net/Articles/23634/ - */ batadv_event_workqueue = create_singlethread_workqueue("bat_events");
if (!batadv_event_workqueue)
The batadv_tt_orig_list_entry structure didn't have any refcounting mechanism so far. This patch introduces it and makes the structure being usable in much more complex context.
Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/translation-table.c | 77 +++++++++++++++++++++++++----------- net/batman-adv/types.h | 1 + 2 files changed, 54 insertions(+), 24 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 99dd8f7..eb8490e 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -152,6 +152,8 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu) static void batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) { + if (!atomic_dec_and_test(&orig_entry->refcount)) + return; /* to avoid race conditions, immediately decrease the tt counter */ atomic_dec(&orig_entry->orig_node->tt_size); call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); @@ -625,50 +627,82 @@ static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv) spin_unlock_bh(&bat_priv->tt_changes_list_lock); }
+/* retrieves the orig_tt_list_entry belonging to orig_node from the + * batadv_tt_global_entry list + * + * returns it with an increased refcounter, NULL if not found + */ +static struct batadv_tt_orig_list_entry * +batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry, + const struct batadv_orig_node *orig_node) +{ + struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL; + const struct hlist_head *head; + struct hlist_node *node; + + rcu_read_lock(); + head = &entry->orig_list; + hlist_for_each_entry_rcu(tmp_orig_entry, node, head, list) { + if (tmp_orig_entry->orig_node != orig_node) + continue; + if (!atomic_inc_not_zero(&tmp_orig_entry->refcount)) + continue; + + orig_entry = tmp_orig_entry; + break; + } + rcu_read_unlock(); + + return orig_entry; +} + /* find out if an orig_node is already in the list of a tt_global_entry. - * returns 1 if found, 0 otherwise + * returns true if found, false otherwise */ static bool batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, const struct batadv_orig_node *orig_node) { - struct batadv_tt_orig_list_entry *tmp_orig_entry; - const struct hlist_head *head; - struct hlist_node *node; + struct batadv_tt_orig_list_entry *orig_entry; bool found = false;
- rcu_read_lock(); - head = &entry->orig_list; - hlist_for_each_entry_rcu(tmp_orig_entry, node, head, list) { - if (tmp_orig_entry->orig_node == orig_node) { - found = true; - break; - } + orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node); + if (orig_entry) { + found = true; + batadv_tt_orig_list_entry_free_ref(orig_entry); } - rcu_read_unlock(); + return found; }
static void -batadv_tt_global_add_orig_entry(struct batadv_tt_global_entry *tt_global_entry, +batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, struct batadv_orig_node *orig_node, int ttvn) { struct batadv_tt_orig_list_entry *orig_entry;
+ orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node); + if (orig_entry) + goto out; + orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC); if (!orig_entry) - return; + goto out;
INIT_HLIST_NODE(&orig_entry->list); atomic_inc(&orig_node->refcount); atomic_inc(&orig_node->tt_size); orig_entry->orig_node = orig_node; orig_entry->ttvn = ttvn; + atomic_set(&orig_entry->refcount, 2);
- spin_lock_bh(&tt_global_entry->list_lock); + spin_lock_bh(&tt_global->list_lock); hlist_add_head_rcu(&orig_entry->list, - &tt_global_entry->orig_list); - spin_unlock_bh(&tt_global_entry->list_lock); + &tt_global->orig_list); + spin_unlock_bh(&tt_global->list_lock); +out: + if (orig_entry) + batadv_tt_orig_list_entry_free_ref(orig_entry); }
/* caller must hold orig_node refcount */ @@ -709,9 +743,6 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, batadv_tt_global_entry_free_ref(tt_global_entry); goto out_remove; } - - batadv_tt_global_add_orig_entry(tt_global_entry, orig_node, - ttvn); } else { /* there is already a global entry, use this one. */
@@ -728,11 +759,9 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, tt_global_entry->roam_at = 0; }
- if (!batadv_tt_global_entry_has_orig(tt_global_entry, - orig_node)) - batadv_tt_global_add_orig_entry(tt_global_entry, - orig_node, ttvn); } + /* add the new orig_entry (if needed) */ + batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
batadv_dbg(BATADV_DBG_TT, bat_priv, "Creating new global tt entry: %pM (via %pM)\n", diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 7812b6e..664ef81 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -282,6 +282,7 @@ struct batadv_tt_global_entry { struct batadv_tt_orig_list_entry { struct batadv_orig_node *orig_node; uint8_t ttvn; + atomic_t refcount; struct rcu_head rcu; struct hlist_node list; };
the word millisecond is misspelled in several comments. This patch fixes it.
Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/main.h | 8 ++++---- net/batman-adv/vis.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 5d8fa07..4dfeae5 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -41,13 +41,13 @@ * -> TODO: check influence on BATADV_TQ_LOCAL_WINDOW_SIZE */ #define BATADV_PURGE_TIMEOUT 200000 /* 200 seconds */ -#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in miliseconds */ -#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in miliseconds */ +#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */ +#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */ /* sliding packet range of received originator messages in sequence numbers * (should be a multiple of our word size) */ #define BATADV_TQ_LOCAL_WINDOW_SIZE 64 -/* miliseconds we have to keep pending tt_req */ +/* milliseconds we have to keep pending tt_req */ #define BATADV_TT_REQUEST_TIMEOUT 3000
#define BATADV_TQ_GLOBAL_WINDOW_SIZE 5 @@ -59,7 +59,7 @@ #define BATADV_TT_OGM_APPEND_MAX 3
/* Time in which a client can roam at most ROAMING_MAX_COUNT times in - * miliseconds + * milliseconds */ #define BATADV_ROAMING_MAX_TIME 20000 #define BATADV_ROAMING_MAX_COUNT 5 diff --git a/net/batman-adv/vis.h b/net/batman-adv/vis.h index 84e716e..873282f 100644 --- a/net/batman-adv/vis.h +++ b/net/batman-adv/vis.h @@ -20,7 +20,7 @@ #ifndef _NET_BATMAN_ADV_VIS_H_ #define _NET_BATMAN_ADV_VIS_H_
-/* timeout of vis packets in miliseconds */ +/* timeout of vis packets in milliseconds */ #define BATADV_VIS_TIMEOUT 200000
int batadv_vis_seq_print_text(struct seq_file *seq, void *offset);
From: Simon Wunderlich simon.wunderlich@s2003.tu-chemnitz.de
If this call fails, some of the orig_nodes spaces may have been resized for the increased number of interface, and some may not. If we would just continue with the larger number of interfaces, this would lead to access to not allocated memory later.
We better check the return code, and don't add the interface if no memory is available. OTOH, keeping some of the orig_nodes with too much memory allocated should hurt no one (except for a few too many bytes allocated).
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/hard-interface.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 282bf6e..2c5a247 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -313,7 +313,13 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, hard_iface->if_num = bat_priv->num_ifaces; bat_priv->num_ifaces++; hard_iface->if_status = BATADV_IF_INACTIVE; - batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); + ret = batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); + if (ret < 0) { + bat_priv->bat_algo_ops->bat_iface_disable(hard_iface); + bat_priv->num_ifaces--; + hard_iface->if_status = BATADV_IF_NOT_IN_USE; + goto err_dev; + }
hard_iface->batman_adv_ptype.type = ethertype; hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv;
From: Sven Eckelmann sven@narfation.org
The structure batadv_priv grows everytime a new feature is introduced. It gets hard to find the parts of the struct that belongs to a specific feature. This becomes even harder by the fact that not every feature uses a prefix in the member name.
The variables for bridge loop avoidence, gateway handling, translation table and visualization server are moved into separate structs that are included in the bat_priv main struct.
Signed-off-by: Sven Eckelmann sven@narfation.org Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/bat_iv_ogm.c | 4 +- net/batman-adv/bridge_loop_avoidance.c | 115 +++++++++--------- net/batman-adv/gateway_client.c | 32 ++--- net/batman-adv/hard-interface.c | 5 +- net/batman-adv/main.c | 24 ++-- net/batman-adv/routing.c | 6 +- net/batman-adv/soft-interface.c | 17 +-- net/batman-adv/translation-table.c | 208 ++++++++++++++++---------------- net/batman-adv/types.h | 113 ++++++++++------- net/batman-adv/vis.c | 130 ++++++++++---------- 10 files changed, 343 insertions(+), 311 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index e877af8..eb507c9 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -603,8 +603,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) htonl((uint32_t)atomic_read(&hard_iface->seqno)); atomic_inc(&hard_iface->seqno);
- batadv_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn); - batadv_ogm_packet->tt_crc = htons(bat_priv->tt_crc); + batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn); + batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc); if (tt_num_changes >= 0) batadv_ogm_packet->tt_num_changes = tt_num_changes;
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index c9732ac..ad18017 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -133,7 +133,7 @@ static void batadv_claim_free_ref(struct batadv_claim *claim) static struct batadv_claim *batadv_claim_hash_find(struct batadv_priv *bat_priv, struct batadv_claim *data) { - struct batadv_hashtable *hash = bat_priv->claim_hash; + struct batadv_hashtable *hash = bat_priv->bla.claim_hash; struct hlist_head *head; struct hlist_node *node; struct batadv_claim *claim; @@ -174,7 +174,7 @@ static struct batadv_backbone_gw * batadv_backbone_hash_find(struct batadv_priv *bat_priv, uint8_t *addr, short vid) { - struct batadv_hashtable *hash = bat_priv->backbone_hash; + struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; struct hlist_head *head; struct hlist_node *node; struct batadv_backbone_gw search_entry, *backbone_gw; @@ -218,7 +218,7 @@ batadv_bla_del_backbone_claims(struct batadv_backbone_gw *backbone_gw) int i; spinlock_t *list_lock; /* protects write access to the hash lists */
- hash = backbone_gw->bat_priv->claim_hash; + hash = backbone_gw->bat_priv->bla.claim_hash; if (!hash) return;
@@ -265,7 +265,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, if (!primary_if) return;
- memcpy(&local_claim_dest, &bat_priv->claim_dest, + memcpy(&local_claim_dest, &bat_priv->bla.claim_dest, sizeof(local_claim_dest)); local_claim_dest.type = claimtype;
@@ -391,7 +391,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig, /* one for the hash, one for returning */ atomic_set(&entry->refcount, 2);
- hash_added = batadv_hash_add(bat_priv->backbone_hash, + hash_added = batadv_hash_add(bat_priv->bla.backbone_hash, batadv_compare_backbone_gw, batadv_choose_backbone_gw, entry, &entry->hash_entry); @@ -458,7 +458,7 @@ static void batadv_bla_answer_request(struct batadv_priv *bat_priv, if (!backbone_gw) return;
- hash = bat_priv->claim_hash; + hash = bat_priv->bla.claim_hash; for (i = 0; i < hash->size; i++) { head = &hash->table[i];
@@ -499,7 +499,7 @@ static void batadv_bla_send_request(struct batadv_backbone_gw *backbone_gw)
/* no local broadcasts should be sent or received, for now. */ if (!atomic_read(&backbone_gw->request_sent)) { - atomic_inc(&backbone_gw->bat_priv->bla_num_requests); + atomic_inc(&backbone_gw->bat_priv->bla.num_requests); atomic_set(&backbone_gw->request_sent, 1); } } @@ -559,7 +559,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n", mac, vid); - hash_added = batadv_hash_add(bat_priv->claim_hash, + hash_added = batadv_hash_add(bat_priv->bla.claim_hash, batadv_compare_claim, batadv_choose_claim, claim, &claim->hash_entry); @@ -612,7 +612,7 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n", mac, vid);
- batadv_hash_remove(bat_priv->claim_hash, batadv_compare_claim, + batadv_hash_remove(bat_priv->bla.claim_hash, batadv_compare_claim, batadv_choose_claim, claim); batadv_claim_free_ref(claim); /* reference from the hash is gone */
@@ -659,7 +659,7 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, * we can allow traffic again. */ if (atomic_read(&backbone_gw->request_sent)) { - atomic_dec(&backbone_gw->bat_priv->bla_num_requests); + atomic_dec(&backbone_gw->bat_priv->bla.num_requests); atomic_set(&backbone_gw->request_sent, 0); } } @@ -774,7 +774,7 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv, struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
bla_dst = (struct batadv_bla_claim_dst *)hw_dst; - bla_dst_own = &bat_priv->claim_dest; + bla_dst_own = &bat_priv->bla.claim_dest;
/* check if it is a claim packet in general */ if (memcmp(bla_dst->magic, bla_dst_own->magic, @@ -947,7 +947,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now) spinlock_t *list_lock; /* protects write access to the hash lists */ int i;
- hash = bat_priv->backbone_hash; + hash = bat_priv->bla.backbone_hash; if (!hash) return;
@@ -971,7 +971,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now) purge_now: /* don't wait for the pending request anymore */ if (atomic_read(&backbone_gw->request_sent)) - atomic_dec(&bat_priv->bla_num_requests); + atomic_dec(&bat_priv->bla.num_requests);
batadv_bla_del_backbone_claims(backbone_gw);
@@ -1001,7 +1001,7 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv, struct batadv_hashtable *hash; int i;
- hash = bat_priv->claim_hash; + hash = bat_priv->bla.claim_hash; if (!hash) return;
@@ -1048,11 +1048,12 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, struct hlist_node *node; struct hlist_head *head; struct batadv_hashtable *hash; + __be16 group; int i;
/* reset bridge loop avoidance group id */ - bat_priv->claim_dest.group = - htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); + group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); + bat_priv->bla.claim_dest.group = group;
if (!oldif) { batadv_bla_purge_claims(bat_priv, NULL, 1); @@ -1060,7 +1061,7 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, return; }
- hash = bat_priv->backbone_hash; + hash = bat_priv->bla.backbone_hash; if (!hash) return;
@@ -1090,8 +1091,8 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, /* (re)start the timer */ static void batadv_bla_start_timer(struct batadv_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->bla_work, batadv_bla_periodic_work); - queue_delayed_work(batadv_event_workqueue, &bat_priv->bla_work, + INIT_DELAYED_WORK(&bat_priv->bla.work, batadv_bla_periodic_work); + queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work, msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH)); }
@@ -1104,6 +1105,7 @@ static void batadv_bla_periodic_work(struct work_struct *work) struct delayed_work *delayed_work = container_of(work, struct delayed_work, work); struct batadv_priv *bat_priv; + struct batadv_priv_bla *priv_bla; struct hlist_node *node; struct hlist_head *head; struct batadv_backbone_gw *backbone_gw; @@ -1111,7 +1113,8 @@ static void batadv_bla_periodic_work(struct work_struct *work) struct batadv_hard_iface *primary_if; int i;
- bat_priv = container_of(delayed_work, struct batadv_priv, bla_work); + priv_bla = container_of(delayed_work, struct batadv_priv_bla, work); + bat_priv = container_of(priv_bla, struct batadv_priv, bla); primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -1122,7 +1125,7 @@ static void batadv_bla_periodic_work(struct work_struct *work) if (!atomic_read(&bat_priv->bridge_loop_avoidance)) goto out;
- hash = bat_priv->backbone_hash; + hash = bat_priv->bla.backbone_hash; if (!hash) goto out;
@@ -1162,40 +1165,41 @@ int batadv_bla_init(struct batadv_priv *bat_priv) int i; uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00}; struct batadv_hard_iface *primary_if; + uint16_t crc; + unsigned long entrytime;
batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n");
/* setting claim destination address */ - memcpy(&bat_priv->claim_dest.magic, claim_dest, 3); - bat_priv->claim_dest.type = 0; + memcpy(&bat_priv->bla.claim_dest.magic, claim_dest, 3); + bat_priv->bla.claim_dest.type = 0; primary_if = batadv_primary_if_get_selected(bat_priv); if (primary_if) { - bat_priv->claim_dest.group = - htons(crc16(0, primary_if->net_dev->dev_addr, - ETH_ALEN)); + crc = crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN); + bat_priv->bla.claim_dest.group = htons(crc); batadv_hardif_free_ref(primary_if); } else { - bat_priv->claim_dest.group = 0; /* will be set later */ + bat_priv->bla.claim_dest.group = 0; /* will be set later */ }
/* initialize the duplicate list */ + entrytime = jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT); for (i = 0; i < BATADV_DUPLIST_SIZE; i++) - bat_priv->bcast_duplist[i].entrytime = - jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT); - bat_priv->bcast_duplist_curr = 0; + bat_priv->bla.bcast_duplist[i].entrytime = entrytime; + bat_priv->bla.bcast_duplist_curr = 0;
- if (bat_priv->claim_hash) + if (bat_priv->bla.claim_hash) return 0;
- bat_priv->claim_hash = batadv_hash_new(128); - bat_priv->backbone_hash = batadv_hash_new(32); + bat_priv->bla.claim_hash = batadv_hash_new(128); + bat_priv->bla.backbone_hash = batadv_hash_new(32);
- if (!bat_priv->claim_hash || !bat_priv->backbone_hash) + if (!bat_priv->bla.claim_hash || !bat_priv->bla.backbone_hash) return -ENOMEM;
- batadv_hash_set_lock_class(bat_priv->claim_hash, + batadv_hash_set_lock_class(bat_priv->bla.claim_hash, &batadv_claim_hash_lock_class_key); - batadv_hash_set_lock_class(bat_priv->backbone_hash, + batadv_hash_set_lock_class(bat_priv->bla.backbone_hash, &batadv_backbone_hash_lock_class_key);
batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hashes initialized\n"); @@ -1236,8 +1240,9 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, crc = crc16(0, content, length);
for (i = 0; i < BATADV_DUPLIST_SIZE; i++) { - curr = (bat_priv->bcast_duplist_curr + i) % BATADV_DUPLIST_SIZE; - entry = &bat_priv->bcast_duplist[curr]; + curr = (bat_priv->bla.bcast_duplist_curr + i); + curr %= BATADV_DUPLIST_SIZE; + entry = &bat_priv->bla.bcast_duplist[curr];
/* we can stop searching if the entry is too old ; * later entries will be even older @@ -1258,13 +1263,13 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, return 1; } /* not found, add a new entry (overwrite the oldest entry) */ - curr = (bat_priv->bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); + curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); curr %= BATADV_DUPLIST_SIZE; - entry = &bat_priv->bcast_duplist[curr]; + entry = &bat_priv->bla.bcast_duplist[curr]; entry->crc = crc; entry->entrytime = jiffies; memcpy(entry->orig, bcast_packet->orig, ETH_ALEN); - bat_priv->bcast_duplist_curr = curr; + bat_priv->bla.bcast_duplist_curr = curr;
/* allow it, its the first occurence. */ return 0; @@ -1281,7 +1286,7 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, */ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig) { - struct batadv_hashtable *hash = bat_priv->backbone_hash; + struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; struct hlist_head *head; struct hlist_node *node; struct batadv_backbone_gw *backbone_gw; @@ -1361,18 +1366,18 @@ void batadv_bla_free(struct batadv_priv *bat_priv) { struct batadv_hard_iface *primary_if;
- cancel_delayed_work_sync(&bat_priv->bla_work); + cancel_delayed_work_sync(&bat_priv->bla.work); primary_if = batadv_primary_if_get_selected(bat_priv);
- if (bat_priv->claim_hash) { + if (bat_priv->bla.claim_hash) { batadv_bla_purge_claims(bat_priv, primary_if, 1); - batadv_hash_destroy(bat_priv->claim_hash); - bat_priv->claim_hash = NULL; + batadv_hash_destroy(bat_priv->bla.claim_hash); + bat_priv->bla.claim_hash = NULL; } - if (bat_priv->backbone_hash) { + if (bat_priv->bla.backbone_hash) { batadv_bla_purge_backbone_gw(bat_priv, 1); - batadv_hash_destroy(bat_priv->backbone_hash); - bat_priv->backbone_hash = NULL; + batadv_hash_destroy(bat_priv->bla.backbone_hash); + bat_priv->bla.backbone_hash = NULL; } if (primary_if) batadv_hardif_free_ref(primary_if); @@ -1411,7 +1416,7 @@ int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid, goto allow;
- if (unlikely(atomic_read(&bat_priv->bla_num_requests))) + if (unlikely(atomic_read(&bat_priv->bla.num_requests))) /* don't allow broadcasts while requests are in flight */ if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) goto handled; @@ -1510,7 +1515,7 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid)
ethhdr = (struct ethhdr *)skb_mac_header(skb);
- if (unlikely(atomic_read(&bat_priv->bla_num_requests))) + if (unlikely(atomic_read(&bat_priv->bla.num_requests))) /* don't allow broadcasts while requests are in flight */ if (is_multicast_ether_addr(ethhdr->h_dest)) goto handled; @@ -1566,7 +1571,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->claim_hash; + struct batadv_hashtable *hash = bat_priv->bla.claim_hash; struct batadv_claim *claim; struct batadv_hard_iface *primary_if; struct hlist_node *node; @@ -1595,7 +1600,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) seq_printf(seq, "Claims announced for the mesh %s (orig %pM, group id %04x)\n", net_dev->name, primary_addr, - ntohs(bat_priv->claim_dest.group)); + ntohs(bat_priv->bla.claim_dest.group)); seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n", "Client", "VID", "Originator", "CRC"); for (i = 0; i < hash->size; i++) { @@ -1623,7 +1628,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->backbone_hash; + struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; struct batadv_backbone_gw *backbone_gw; struct batadv_hard_iface *primary_if; struct hlist_node *node; @@ -1653,7 +1658,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) seq_printf(seq, "Backbones announced for the mesh %s (orig %pM, group id %04x)\n", net_dev->name, primary_addr, - ntohs(bat_priv->claim_dest.group)); + ntohs(bat_priv->bla.claim_dest.group)); seq_printf(seq, " %-17s %-5s %-9s (%-4s)\n", "Originator", "VID", "last seen", "CRC"); for (i = 0; i < hash->size; i++) { diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index fc866f2..eef7cc7 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -48,7 +48,7 @@ batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv) struct batadv_gw_node *gw_node;
rcu_read_lock(); - gw_node = rcu_dereference(bat_priv->curr_gw); + gw_node = rcu_dereference(bat_priv->gw.curr_gw); if (!gw_node) goto out;
@@ -91,23 +91,23 @@ static void batadv_gw_select(struct batadv_priv *bat_priv, { struct batadv_gw_node *curr_gw_node;
- spin_lock_bh(&bat_priv->gw_list_lock); + spin_lock_bh(&bat_priv->gw.list_lock);
if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount)) new_gw_node = NULL;
- curr_gw_node = rcu_dereference_protected(bat_priv->curr_gw, 1); - rcu_assign_pointer(bat_priv->curr_gw, new_gw_node); + curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1); + rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node);
if (curr_gw_node) batadv_gw_node_free_ref(curr_gw_node);
- spin_unlock_bh(&bat_priv->gw_list_lock); + spin_unlock_bh(&bat_priv->gw.list_lock); }
void batadv_gw_deselect(struct batadv_priv *bat_priv) { - atomic_set(&bat_priv->gw_reselect, 1); + atomic_set(&bat_priv->gw.reselect, 1); }
static struct batadv_gw_node * @@ -122,7 +122,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) struct batadv_orig_node *orig_node;
rcu_read_lock(); - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) { if (gw_node->deleted) continue;
@@ -202,7 +202,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
- if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect) && curr_gw) + if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw) goto out;
next_gw = batadv_gw_get_best_gw_node(bat_priv); @@ -321,9 +321,9 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv, gw_node->orig_node = orig_node; atomic_set(&gw_node->refcount, 1);
- spin_lock_bh(&bat_priv->gw_list_lock); - hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list); - spin_unlock_bh(&bat_priv->gw_list_lock); + spin_lock_bh(&bat_priv->gw.list_lock); + hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list); + spin_unlock_bh(&bat_priv->gw.list_lock);
batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up); batadv_dbg(BATADV_DBG_BATMAN, bat_priv, @@ -350,7 +350,7 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv, curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
rcu_read_lock(); - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) { if (gw_node->orig_node != orig_node) continue;
@@ -404,10 +404,10 @@ void batadv_gw_node_purge(struct batadv_priv *bat_priv)
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
- spin_lock_bh(&bat_priv->gw_list_lock); + spin_lock_bh(&bat_priv->gw.list_lock);
hlist_for_each_entry_safe(gw_node, node, node_tmp, - &bat_priv->gw_list, list) { + &bat_priv->gw.list, list) { if (((!gw_node->deleted) || (time_before(jiffies, gw_node->deleted + timeout))) && atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) @@ -420,7 +420,7 @@ void batadv_gw_node_purge(struct batadv_priv *bat_priv) batadv_gw_node_free_ref(gw_node); }
- spin_unlock_bh(&bat_priv->gw_list_lock); + spin_unlock_bh(&bat_priv->gw.list_lock);
/* gw_deselect() needs to acquire the gw_list_lock */ if (do_deselect) @@ -496,7 +496,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) primary_if->net_dev->dev_addr, net_dev->name);
rcu_read_lock(); - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) { if (gw_node->deleted) continue;
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 2c5a247..d112fd6 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -103,13 +103,14 @@ static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv, { struct batadv_vis_packet *vis_packet; struct batadv_hard_iface *primary_if; + struct sk_buff *skb;
primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out;
- vis_packet = (struct batadv_vis_packet *) - bat_priv->my_vis_info->skb_packet->data; + skb = bat_priv->vis.my_info->skb_packet; + vis_packet = (struct batadv_vis_packet *)skb->data; memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN); memcpy(vis_packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN); diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 2a1f243..b4aa470 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -94,20 +94,20 @@ int batadv_mesh_init(struct net_device *soft_iface)
spin_lock_init(&bat_priv->forw_bat_list_lock); spin_lock_init(&bat_priv->forw_bcast_list_lock); - spin_lock_init(&bat_priv->tt_changes_list_lock); - spin_lock_init(&bat_priv->tt_req_list_lock); - spin_lock_init(&bat_priv->tt_roam_list_lock); - spin_lock_init(&bat_priv->tt_buff_lock); - spin_lock_init(&bat_priv->gw_list_lock); - spin_lock_init(&bat_priv->vis_hash_lock); - spin_lock_init(&bat_priv->vis_list_lock); + spin_lock_init(&bat_priv->tt.changes_list_lock); + spin_lock_init(&bat_priv->tt.req_list_lock); + spin_lock_init(&bat_priv->tt.roam_list_lock); + spin_lock_init(&bat_priv->tt.last_changeset_lock); + spin_lock_init(&bat_priv->gw.list_lock); + spin_lock_init(&bat_priv->vis.hash_lock); + spin_lock_init(&bat_priv->vis.list_lock);
INIT_HLIST_HEAD(&bat_priv->forw_bat_list); INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); - INIT_HLIST_HEAD(&bat_priv->gw_list); - INIT_LIST_HEAD(&bat_priv->tt_changes_list); - INIT_LIST_HEAD(&bat_priv->tt_req_list); - INIT_LIST_HEAD(&bat_priv->tt_roam_list); + INIT_HLIST_HEAD(&bat_priv->gw.list); + INIT_LIST_HEAD(&bat_priv->tt.changes_list); + INIT_LIST_HEAD(&bat_priv->tt.req_list); + INIT_LIST_HEAD(&bat_priv->tt.roam_list);
ret = batadv_originator_init(bat_priv); if (ret < 0) @@ -128,7 +128,7 @@ int batadv_mesh_init(struct net_device *soft_iface) if (ret < 0) goto err;
- atomic_set(&bat_priv->gw_reselect, 0); + atomic_set(&bat_priv->gw.reselect, 0); atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
return 0; diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index bc2b88b..d5edee7 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -721,7 +721,7 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if) * been incremented yet. This flag will make me check all the incoming * packets for the correct destination. */ - bat_priv->tt_poss_change = true; + bat_priv->tt.poss_change = true;
batadv_orig_node_free_ref(orig_node); out: @@ -947,8 +947,8 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, unicast_packet = (struct batadv_unicast_packet *)skb->data;
if (batadv_is_my_mac(unicast_packet->dest)) { - tt_poss_change = bat_priv->tt_poss_change; - curr_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); + tt_poss_change = bat_priv->tt.poss_change; + curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); } else { orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->dest); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 2b3842b..6d44625 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -420,14 +420,15 @@ struct net_device *batadv_softif_create(const char *name)
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); atomic_set(&bat_priv->bcast_seqno, 1); - atomic_set(&bat_priv->ttvn, 0); - atomic_set(&bat_priv->tt_local_changes, 0); - atomic_set(&bat_priv->tt_ogm_append_cnt, 0); - atomic_set(&bat_priv->bla_num_requests, 0); - - bat_priv->tt_buff = NULL; - bat_priv->tt_buff_len = 0; - bat_priv->tt_poss_change = false; + atomic_set(&bat_priv->tt.vn, 0); + atomic_set(&bat_priv->tt.local_changes, 0); + atomic_set(&bat_priv->tt.ogm_append_cnt, 0); +#ifdef CONFIG_BATMAN_ADV_BLA + atomic_set(&bat_priv->bla.num_requests, 0); +#endif + bat_priv->tt.last_changeset = NULL; + bat_priv->tt.last_changeset_len = 0; + bat_priv->tt.poss_change = false;
bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0; diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index eb8490e..b01049a 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -46,8 +46,8 @@ static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
static void batadv_tt_start_timer(struct batadv_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->tt_work, batadv_tt_purge); - queue_delayed_work(batadv_event_workqueue, &bat_priv->tt_work, + INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); + queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, msecs_to_jiffies(5000)); }
@@ -88,7 +88,7 @@ batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data) struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_local_entry *tt_local_entry = NULL;
- tt_common_entry = batadv_tt_hash_find(bat_priv->tt_local_hash, data); + tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data); if (tt_common_entry) tt_local_entry = container_of(tt_common_entry, struct batadv_tt_local_entry, @@ -102,7 +102,7 @@ batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data) struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_global_entry *tt_global_entry = NULL;
- tt_common_entry = batadv_tt_hash_find(bat_priv->tt_global_hash, data); + tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data); if (tt_common_entry) tt_global_entry = container_of(tt_common_entry, struct batadv_tt_global_entry, @@ -177,8 +177,8 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv, del_op_requested = flags & BATADV_TT_CLIENT_DEL;
/* check for ADD+DEL or DEL+ADD events */ - spin_lock_bh(&bat_priv->tt_changes_list_lock); - list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, + spin_lock_bh(&bat_priv->tt.changes_list_lock); + list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, list) { if (!batadv_compare_eth(entry->change.addr, addr)) continue; @@ -205,15 +205,15 @@ del: }
/* track the change in the OGMinterval list */ - list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list); + list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list);
unlock: - spin_unlock_bh(&bat_priv->tt_changes_list_lock); + spin_unlock_bh(&bat_priv->tt.changes_list_lock);
if (event_removed) - atomic_dec(&bat_priv->tt_local_changes); + atomic_dec(&bat_priv->tt.local_changes); else - atomic_inc(&bat_priv->tt_local_changes); + atomic_inc(&bat_priv->tt.local_changes); }
int batadv_tt_len(int changes_num) @@ -223,12 +223,12 @@ int batadv_tt_len(int changes_num)
static int batadv_tt_local_init(struct batadv_priv *bat_priv) { - if (bat_priv->tt_local_hash) + if (bat_priv->tt.local_hash) return 0;
- bat_priv->tt_local_hash = batadv_hash_new(1024); + bat_priv->tt.local_hash = batadv_hash_new(1024);
- if (!bat_priv->tt_local_hash) + if (!bat_priv->tt.local_hash) return -ENOMEM;
return 0; @@ -260,7 +260,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
batadv_dbg(BATADV_DBG_TT, bat_priv, "Creating new local tt entry: %pM (ttvn: %d)\n", addr, - (uint8_t)atomic_read(&bat_priv->ttvn)); + (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; @@ -279,7 +279,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, */ tt_local_entry->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_entry->common, &tt_local_entry->common.hash_entry); @@ -350,7 +350,7 @@ static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv, primary_if = batadv_primary_if_get_selected(bat_priv);
req_len = min_packet_len; - req_len += batadv_tt_len(atomic_read(&bat_priv->tt_local_changes)); + req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
/* if we have too many changes for one packet don't send any * and wait for the tt table request which will be fragmented @@ -383,10 +383,10 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv, if (new_len > 0) tot_changes = new_len / batadv_tt_len(1);
- spin_lock_bh(&bat_priv->tt_changes_list_lock); - atomic_set(&bat_priv->tt_local_changes, 0); + spin_lock_bh(&bat_priv->tt.changes_list_lock); + atomic_set(&bat_priv->tt.local_changes, 0);
- list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, + list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, list) { if (count < tot_changes) { memcpy(tt_buff + batadv_tt_len(count), @@ -396,25 +396,25 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv, list_del(&entry->list); kfree(entry); } - spin_unlock_bh(&bat_priv->tt_changes_list_lock); + spin_unlock_bh(&bat_priv->tt.changes_list_lock);
/* Keep the buffer for possible tt_request */ - spin_lock_bh(&bat_priv->tt_buff_lock); - kfree(bat_priv->tt_buff); - bat_priv->tt_buff_len = 0; - bat_priv->tt_buff = NULL; + spin_lock_bh(&bat_priv->tt.last_changeset_lock); + kfree(bat_priv->tt.last_changeset); + bat_priv->tt.last_changeset_len = 0; + bat_priv->tt.last_changeset = NULL; /* check whether this new OGM has no changes due to size problems */ if (new_len > 0) { /* if kmalloc() fails we will reply with the full table * instead of providing the diff */ - bat_priv->tt_buff = kmalloc(new_len, GFP_ATOMIC); - if (bat_priv->tt_buff) { - memcpy(bat_priv->tt_buff, tt_buff, new_len); - bat_priv->tt_buff_len = new_len; + bat_priv->tt.last_changeset = kmalloc(new_len, GFP_ATOMIC); + if (bat_priv->tt.last_changeset) { + memcpy(bat_priv->tt.last_changeset, tt_buff, new_len); + bat_priv->tt.last_changeset_len = new_len; } } - spin_unlock_bh(&bat_priv->tt_buff_lock); + spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
return count; } @@ -423,7 +423,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; 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_hard_iface *primary_if; struct hlist_node *node; @@ -448,7 +448,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", - net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn)); + net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn));
for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -546,7 +546,7 @@ static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
static void batadv_tt_local_purge(struct batadv_priv *bat_priv) { - struct batadv_hashtable *hash = bat_priv->tt_local_hash; + struct batadv_hashtable *hash = bat_priv->tt.local_hash; struct hlist_head *head; spinlock_t *list_lock; /* protects write access to the hash lists */ uint32_t i; @@ -572,10 +572,10 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) struct hlist_head *head; uint32_t i;
- if (!bat_priv->tt_local_hash) + if (!bat_priv->tt.local_hash) return;
- hash = bat_priv->tt_local_hash; + hash = bat_priv->tt.local_hash;
for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -595,17 +595,17 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
batadv_hash_destroy(hash);
- bat_priv->tt_local_hash = NULL; + bat_priv->tt.local_hash = NULL; }
static int batadv_tt_global_init(struct batadv_priv *bat_priv) { - if (bat_priv->tt_global_hash) + if (bat_priv->tt.global_hash) return 0;
- bat_priv->tt_global_hash = batadv_hash_new(1024); + bat_priv->tt.global_hash = batadv_hash_new(1024);
- if (!bat_priv->tt_global_hash) + if (!bat_priv->tt.global_hash) return -ENOMEM;
return 0; @@ -615,16 +615,16 @@ static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv) { struct batadv_tt_change_node *entry, *safe;
- spin_lock_bh(&bat_priv->tt_changes_list_lock); + spin_lock_bh(&bat_priv->tt.changes_list_lock);
- list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, + list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, list) { list_del(&entry->list); kfree(entry); }
- atomic_set(&bat_priv->tt_local_changes, 0); - spin_unlock_bh(&bat_priv->tt_changes_list_lock); + atomic_set(&bat_priv->tt.local_changes, 0); + spin_unlock_bh(&bat_priv->tt.changes_list_lock); }
/* retrieves the orig_tt_list_entry belonging to orig_node from the @@ -733,7 +733,7 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, INIT_HLIST_HEAD(&tt_global_entry->orig_list); spin_lock_init(&tt_global_entry->list_lock);
- hash_added = batadv_hash_add(bat_priv->tt_global_hash, + hash_added = batadv_hash_add(bat_priv->tt.global_hash, batadv_compare_tt, batadv_choose_orig, common, &common->hash_entry); @@ -812,7 +812,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->tt_global_hash; + struct batadv_hashtable *hash = bat_priv->tt.global_hash; struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_global_entry *tt_global; struct batadv_hard_iface *primary_if; @@ -913,7 +913,7 @@ batadv_tt_global_del_struct(struct batadv_priv *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_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);
@@ -1024,7 +1024,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, struct batadv_tt_global_entry *tt_global; struct batadv_tt_common_entry *tt_common_entry; uint32_t i; - struct batadv_hashtable *hash = bat_priv->tt_global_hash; + struct batadv_hashtable *hash = bat_priv->tt.global_hash; struct hlist_node *node, *safe; struct hlist_head *head; spinlock_t *list_lock; /* protects write access to the hash lists */ @@ -1088,7 +1088,7 @@ static void batadv_tt_global_roam_purge_list(struct batadv_priv *bat_priv,
static void batadv_tt_global_roam_purge(struct batadv_priv *bat_priv) { - struct batadv_hashtable *hash = bat_priv->tt_global_hash; + struct batadv_hashtable *hash = bat_priv->tt.global_hash; struct hlist_head *head; spinlock_t *list_lock; /* protects write access to the hash lists */ uint32_t i; @@ -1114,10 +1114,10 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) struct hlist_head *head; uint32_t i;
- if (!bat_priv->tt_global_hash) + if (!bat_priv->tt.global_hash) return;
- hash = bat_priv->tt_global_hash; + hash = bat_priv->tt.global_hash;
for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -1137,7 +1137,7 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
batadv_hash_destroy(hash);
- bat_priv->tt_global_hash = NULL; + bat_priv->tt.global_hash = NULL; }
static bool @@ -1216,7 +1216,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv, struct batadv_orig_node *orig_node) { uint16_t total = 0, total_one; - struct batadv_hashtable *hash = bat_priv->tt_global_hash; + struct batadv_hashtable *hash = bat_priv->tt.global_hash; struct batadv_tt_common_entry *tt_common; struct batadv_tt_global_entry *tt_global; struct hlist_node *node; @@ -1263,7 +1263,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv, static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv) { uint16_t total = 0, total_one; - 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; struct hlist_node *node; struct hlist_head *head; @@ -1296,14 +1296,14 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv) { struct batadv_tt_req_node *node, *safe;
- spin_lock_bh(&bat_priv->tt_req_list_lock); + spin_lock_bh(&bat_priv->tt.req_list_lock);
- list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { + list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { list_del(&node->list); kfree(node); }
- spin_unlock_bh(&bat_priv->tt_req_list_lock); + spin_unlock_bh(&bat_priv->tt.req_list_lock); }
static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv, @@ -1333,15 +1333,15 @@ static void batadv_tt_req_purge(struct batadv_priv *bat_priv) { struct batadv_tt_req_node *node, *safe;
- spin_lock_bh(&bat_priv->tt_req_list_lock); - list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { + spin_lock_bh(&bat_priv->tt.req_list_lock); + 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); kfree(node); } } - spin_unlock_bh(&bat_priv->tt_req_list_lock); + spin_unlock_bh(&bat_priv->tt.req_list_lock); }
/* returns the pointer to the new tt_req_node struct if no request @@ -1353,8 +1353,8 @@ batadv_new_tt_req_node(struct batadv_priv *bat_priv, { struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
- spin_lock_bh(&bat_priv->tt_req_list_lock); - list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) { + spin_lock_bh(&bat_priv->tt.req_list_lock); + list_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) { if (batadv_compare_eth(tt_req_node_tmp, orig_node) && !batadv_has_timed_out(tt_req_node_tmp->issued_at, BATADV_TT_REQUEST_TIMEOUT)) @@ -1368,9 +1368,9 @@ batadv_new_tt_req_node(struct batadv_priv *bat_priv, memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN); tt_req_node->issued_at = jiffies;
- list_add(&tt_req_node->list, &bat_priv->tt_req_list); + list_add(&tt_req_node->list, &bat_priv->tt.req_list); unlock: - spin_unlock_bh(&bat_priv->tt_req_list_lock); + spin_unlock_bh(&bat_priv->tt.req_list_lock); return tt_req_node; }
@@ -1536,9 +1536,9 @@ out: if (ret) kfree_skb(skb); if (ret && tt_req_node) { - spin_lock_bh(&bat_priv->tt_req_list_lock); + spin_lock_bh(&bat_priv->tt.req_list_lock); list_del(&tt_req_node->list); - spin_unlock_bh(&bat_priv->tt_req_list_lock); + spin_unlock_bh(&bat_priv->tt.req_list_lock); kfree(tt_req_node); } return ret; @@ -1629,7 +1629,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
skb = batadv_tt_response_fill_table(tt_len, ttvn, - bat_priv->tt_global_hash, + bat_priv->tt.global_hash, primary_if, batadv_tt_global_valid, req_dst_orig_node); @@ -1700,7 +1700,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
- my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); + my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); req_ttvn = tt_request->ttvn;
orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); @@ -1719,7 +1719,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, * is too big send the whole local translation table */ if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || - !bat_priv->tt_buff) + !bat_priv->tt.last_changeset) full_table = true; else full_table = false; @@ -1728,8 +1728,8 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, * I'll send only one packet with as much TT entries as I can */ if (!full_table) { - spin_lock_bh(&bat_priv->tt_buff_lock); - tt_len = bat_priv->tt_buff_len; + spin_lock_bh(&bat_priv->tt.last_changeset_lock); + tt_len = bat_priv->tt.last_changeset_len; tt_tot = tt_len / sizeof(struct batadv_tt_change);
len = sizeof(*tt_response) + tt_len; @@ -1744,16 +1744,16 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, tt_response->tt_data = htons(tt_tot);
tt_buff = skb->data + sizeof(*tt_response); - memcpy(tt_buff, bat_priv->tt_buff, - bat_priv->tt_buff_len); - spin_unlock_bh(&bat_priv->tt_buff_lock); + memcpy(tt_buff, bat_priv->tt.last_changeset, + bat_priv->tt.last_changeset_len); + spin_unlock_bh(&bat_priv->tt.last_changeset_lock); } else { - tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt); + tt_len = (uint16_t)atomic_read(&bat_priv->tt.local_entry_num); tt_len *= sizeof(struct batadv_tt_change); - ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); + ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
skb = batadv_tt_response_fill_table(tt_len, ttvn, - bat_priv->tt_local_hash, + bat_priv->tt.local_hash, primary_if, batadv_tt_local_valid_entry, NULL); @@ -1785,7 +1785,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, goto out;
unlock: - spin_unlock_bh(&bat_priv->tt_buff_lock); + spin_unlock_bh(&bat_priv->tt.last_changeset_lock); out: if (orig_node) batadv_orig_node_free_ref(orig_node); @@ -1938,14 +1938,14 @@ void batadv_handle_tt_response(struct batadv_priv *bat_priv, }
/* Delete the tt_req_node from pending tt_requests list */ - spin_lock_bh(&bat_priv->tt_req_list_lock); - list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { + spin_lock_bh(&bat_priv->tt.req_list_lock); + list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { if (!batadv_compare_eth(node->addr, tt_response->src)) continue; list_del(&node->list); kfree(node); } - spin_unlock_bh(&bat_priv->tt_req_list_lock); + spin_unlock_bh(&bat_priv->tt.req_list_lock);
/* Recalculate the CRC for this orig_node and store it */ orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); @@ -1979,22 +1979,22 @@ static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv) { struct batadv_tt_roam_node *node, *safe;
- spin_lock_bh(&bat_priv->tt_roam_list_lock); + spin_lock_bh(&bat_priv->tt.roam_list_lock);
- list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { + list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { list_del(&node->list); kfree(node); }
- spin_unlock_bh(&bat_priv->tt_roam_list_lock); + spin_unlock_bh(&bat_priv->tt.roam_list_lock); }
static void batadv_tt_roam_purge(struct batadv_priv *bat_priv) { struct batadv_tt_roam_node *node, *safe;
- spin_lock_bh(&bat_priv->tt_roam_list_lock); - list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { + spin_lock_bh(&bat_priv->tt.roam_list_lock); + list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { if (!batadv_has_timed_out(node->first_time, BATADV_ROAMING_MAX_TIME)) continue; @@ -2002,7 +2002,7 @@ static void batadv_tt_roam_purge(struct batadv_priv *bat_priv) list_del(&node->list); kfree(node); } - spin_unlock_bh(&bat_priv->tt_roam_list_lock); + spin_unlock_bh(&bat_priv->tt.roam_list_lock); }
/* This function checks whether the client already reached the @@ -2017,11 +2017,11 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, struct batadv_tt_roam_node *tt_roam_node; bool ret = false;
- spin_lock_bh(&bat_priv->tt_roam_list_lock); + spin_lock_bh(&bat_priv->tt.roam_list_lock); /* The new tt_req will be issued only if I'm not waiting for a * reply from the same orig_node yet */ - list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) { + list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) { if (!batadv_compare_eth(tt_roam_node->addr, client)) continue;
@@ -2046,12 +2046,12 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, BATADV_ROAMING_MAX_COUNT - 1); memcpy(tt_roam_node->addr, client, ETH_ALEN);
- list_add(&tt_roam_node->list, &bat_priv->tt_roam_list); + list_add(&tt_roam_node->list, &bat_priv->tt.roam_list); ret = true; }
unlock: - spin_unlock_bh(&bat_priv->tt_roam_list_lock); + spin_unlock_bh(&bat_priv->tt.roam_list_lock); return ret; }
@@ -2115,10 +2115,12 @@ out: static void batadv_tt_purge(struct work_struct *work) { struct delayed_work *delayed_work; + struct batadv_priv_tt *priv_tt; struct batadv_priv *bat_priv;
delayed_work = container_of(work, struct delayed_work, work); - bat_priv = container_of(delayed_work, struct batadv_priv, tt_work); + priv_tt = container_of(delayed_work, struct batadv_priv_tt, work); + bat_priv = container_of(priv_tt, struct batadv_priv, tt);
batadv_tt_local_purge(bat_priv); batadv_tt_global_roam_purge(bat_priv); @@ -2130,7 +2132,7 @@ static void batadv_tt_purge(struct work_struct *work)
void batadv_tt_free(struct batadv_priv *bat_priv) { - cancel_delayed_work_sync(&bat_priv->tt_work); + cancel_delayed_work_sync(&bat_priv->tt.work);
batadv_tt_local_table_free(bat_priv); batadv_tt_global_table_free(bat_priv); @@ -2138,7 +2140,7 @@ void batadv_tt_free(struct batadv_priv *bat_priv) batadv_tt_changes_list_free(bat_priv); batadv_tt_roam_list_free(bat_priv);
- kfree(bat_priv->tt_buff); + kfree(bat_priv->tt.last_changeset); }
/* This function will enable or disable the specified flags for all the entries @@ -2182,7 +2184,7 @@ out: /* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) { - 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; struct batadv_tt_local_entry *tt_local; struct hlist_node *node, *node_tmp; @@ -2207,7 +2209,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) "Deleting local tt entry (%pM): pending\n", tt_common->addr);
- atomic_dec(&bat_priv->num_local_tt); + atomic_dec(&bat_priv->tt.local_entry_num); hlist_del_rcu(node); tt_local = container_of(tt_common, struct batadv_tt_local_entry, @@ -2225,26 +2227,26 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv, { uint16_t changed_num = 0;
- if (atomic_read(&bat_priv->tt_local_changes) < 1) + if (atomic_read(&bat_priv->tt.local_changes) < 1) return -ENOENT;
- changed_num = batadv_tt_set_flags(bat_priv->tt_local_hash, + changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash, BATADV_TT_CLIENT_NEW, false);
/* all reset entries have to be counted as local entries */ - atomic_add(changed_num, &bat_priv->num_local_tt); + atomic_add(changed_num, &bat_priv->tt.local_entry_num); batadv_tt_local_purge_pending_clients(bat_priv); - bat_priv->tt_crc = batadv_tt_local_crc(bat_priv); + bat_priv->tt.local_crc = batadv_tt_local_crc(bat_priv);
/* Increment the TTVN only once per OGM interval */ - atomic_inc(&bat_priv->ttvn); + atomic_inc(&bat_priv->tt.vn); batadv_dbg(BATADV_DBG_TT, bat_priv, "Local changes committed, updating to ttvn %u\n", - (uint8_t)atomic_read(&bat_priv->ttvn)); - bat_priv->tt_poss_change = false; + (uint8_t)atomic_read(&bat_priv->tt.vn)); + bat_priv->tt.poss_change = false;
/* reset the sending counter */ - atomic_set(&bat_priv->tt_ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); + atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
return batadv_tt_changes_fill_buff(bat_priv, packet_buff, packet_buff_len, packet_min_len); @@ -2264,7 +2266,7 @@ int batadv_tt_append_diff(struct batadv_priv *bat_priv,
/* if the changes have been sent often enough */ if ((tt_num_changes < 0) && - (!batadv_atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) { + (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) { batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, packet_min_len, packet_min_len); tt_num_changes = 0; diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 664ef81..97c4978 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -165,6 +165,67 @@ enum batadv_counters { BATADV_CNT_NUM, };
+/** + * struct batadv_priv_tt - per mesh interface translation table data + * @vn: translation table version number + * @local_changes: changes registered in an originator interval + * @poss_change: Detect an ongoing roaming phase. If true, then this node + * received a roaming_adv and has to inspect every packet directed to it to + * check whether it still is the true destination or not. This flag will be + * reset to false as soon as the this node's ttvn is increased + * @changes_list: tracks tt local changes within an originator interval + * @req_list: list of pending tt_requests + * @local_crc: Checksum of the local table, recomputed before sending a new OGM + */ +struct batadv_priv_tt { + atomic_t vn; + atomic_t ogm_append_cnt; + atomic_t local_changes; + bool poss_change; + struct list_head changes_list; + struct batadv_hashtable *local_hash; + struct batadv_hashtable *global_hash; + struct list_head req_list; + struct list_head roam_list; + spinlock_t changes_list_lock; /* protects changes */ + spinlock_t req_list_lock; /* protects req_list */ + spinlock_t roam_list_lock; /* protects roam_list */ + atomic_t local_entry_num; + uint16_t local_crc; + unsigned char *last_changeset; + int16_t last_changeset_len; + spinlock_t last_changeset_lock; /* protects last_changeset */ + struct delayed_work work; +}; + +#ifdef CONFIG_BATMAN_ADV_BLA +struct batadv_priv_bla { + atomic_t num_requests; /* number of bla requests in flight */ + struct batadv_hashtable *claim_hash; + struct batadv_hashtable *backbone_hash; + struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; + int bcast_duplist_curr; + struct batadv_bla_claim_dst claim_dest; + struct delayed_work work; +}; +#endif + +struct batadv_priv_gw { + struct hlist_head list; + spinlock_t list_lock; /* protects gw_list and curr_gw */ + struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */ + atomic_t reselect; +}; + +struct batadv_priv_vis { + struct list_head send_list; + struct batadv_hashtable *hash; + spinlock_t hash_lock; /* protects hash */ + spinlock_t list_lock; /* protects info::recv_list */ + struct delayed_work work; + struct batadv_vis_info *my_info; +}; + struct batadv_priv { atomic_t mesh_state; struct net_device_stats stats; @@ -184,64 +245,24 @@ struct batadv_priv { atomic_t bcast_seqno; atomic_t bcast_queue_left; atomic_t batman_queue_left; - atomic_t ttvn; /* translation table version number */ - atomic_t tt_ogm_append_cnt; - atomic_t tt_local_changes; /* changes registered in a OGM interval */ - atomic_t bla_num_requests; /* number of bla requests in flight */ - /* The tt_poss_change flag is used to detect an ongoing roaming phase. - * If true, then I received a Roaming_adv and I have to inspect every - * packet directed to me to check whether I am still the true - * destination or not. This flag will be reset to false as soon as I - * increase my TTVN - */ - bool tt_poss_change; char num_ifaces; struct batadv_debug_log *debug_log; struct kobject *mesh_obj; struct dentry *debug_dir; struct hlist_head forw_bat_list; struct hlist_head forw_bcast_list; - struct hlist_head gw_list; - struct list_head tt_changes_list; /* tracks changes in a OGM int */ - struct list_head vis_send_list; struct batadv_hashtable *orig_hash; - struct batadv_hashtable *tt_local_hash; - struct batadv_hashtable *tt_global_hash; -#ifdef CONFIG_BATMAN_ADV_BLA - struct batadv_hashtable *claim_hash; - struct batadv_hashtable *backbone_hash; -#endif - struct list_head tt_req_list; /* list of pending tt_requests */ - struct list_head tt_roam_list; - struct batadv_hashtable *vis_hash; -#ifdef CONFIG_BATMAN_ADV_BLA - struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; - int bcast_duplist_curr; - struct batadv_bla_claim_dst claim_dest; -#endif spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ spinlock_t forw_bcast_list_lock; /* protects */ - spinlock_t tt_changes_list_lock; /* protects tt_changes */ - spinlock_t tt_req_list_lock; /* protects tt_req_list */ - spinlock_t tt_roam_list_lock; /* protects tt_roam_list */ - spinlock_t gw_list_lock; /* protects gw_list and curr_gw */ - spinlock_t vis_hash_lock; /* protects vis_hash */ - spinlock_t vis_list_lock; /* protects vis_info::recv_list */ - atomic_t num_local_tt; - /* Checksum of the local table, recomputed before sending a new OGM */ - uint16_t tt_crc; - unsigned char *tt_buff; - int16_t tt_buff_len; - spinlock_t tt_buff_lock; /* protects tt_buff */ - struct delayed_work tt_work; struct delayed_work orig_work; - struct delayed_work vis_work; - struct delayed_work bla_work; - struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */ - atomic_t gw_reselect; struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */ - struct batadv_vis_info *my_vis_info; struct batadv_algo_ops *bat_algo_ops; +#ifdef CONFIG_BATMAN_ADV_BLA + struct batadv_priv_bla bla; +#endif + struct batadv_priv_gw gw; + struct batadv_priv_tt tt; + struct batadv_priv_vis vis; };
struct batadv_socket_client { diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 2a2ea06..4608c1b2 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -41,13 +41,13 @@ static void batadv_free_info(struct kref *ref) bat_priv = info->bat_priv;
list_del_init(&info->send_list); - spin_lock_bh(&bat_priv->vis_list_lock); + spin_lock_bh(&bat_priv->vis.list_lock); list_for_each_entry_safe(entry, tmp, &info->recv_list, list) { list_del(&entry->list); kfree(entry); }
- spin_unlock_bh(&bat_priv->vis_list_lock); + spin_unlock_bh(&bat_priv->vis.list_lock); kfree_skb(info->skb_packet); kfree(info); } @@ -94,7 +94,7 @@ static uint32_t batadv_vis_info_choose(const void *data, uint32_t size) static struct batadv_vis_info * batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data) { - struct batadv_hashtable *hash = bat_priv->vis_hash; + struct batadv_hashtable *hash = bat_priv->vis.hash; struct hlist_head *head; struct hlist_node *node; struct batadv_vis_info *vis_info, *vis_info_tmp = NULL; @@ -252,7 +252,7 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) struct hlist_head *head; struct net_device *net_dev = (struct net_device *)seq->private; struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->vis_hash; + struct batadv_hashtable *hash = bat_priv->vis.hash; uint32_t i; int ret = 0; int vis_server = atomic_read(&bat_priv->vis_mode); @@ -264,12 +264,12 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) if (vis_server == BATADV_VIS_TYPE_CLIENT_UPDATE) goto out;
- spin_lock_bh(&bat_priv->vis_hash_lock); + spin_lock_bh(&bat_priv->vis.hash_lock); for (i = 0; i < hash->size; i++) { head = &hash->table[i]; batadv_vis_seq_print_text_bucket(seq, head); } - spin_unlock_bh(&bat_priv->vis_hash_lock); + spin_unlock_bh(&bat_priv->vis.hash_lock);
out: if (primary_if) @@ -285,7 +285,7 @@ static void batadv_send_list_add(struct batadv_priv *bat_priv, { if (list_empty(&info->send_list)) { kref_get(&info->refcount); - list_add_tail(&info->send_list, &bat_priv->vis_send_list); + list_add_tail(&info->send_list, &bat_priv->vis.send_list); } }
@@ -311,9 +311,9 @@ static void batadv_recv_list_add(struct batadv_priv *bat_priv, return;
memcpy(entry->mac, mac, ETH_ALEN); - spin_lock_bh(&bat_priv->vis_list_lock); + spin_lock_bh(&bat_priv->vis.list_lock); list_add_tail(&entry->list, recv_list); - spin_unlock_bh(&bat_priv->vis_list_lock); + spin_unlock_bh(&bat_priv->vis.list_lock); }
/* returns 1 if this mac is in the recv_list */ @@ -323,14 +323,14 @@ static int batadv_recv_list_is_in(struct batadv_priv *bat_priv, { const struct batadv_recvlist_node *entry;
- spin_lock_bh(&bat_priv->vis_list_lock); + spin_lock_bh(&bat_priv->vis.list_lock); list_for_each_entry(entry, recv_list, list) { if (batadv_compare_eth(entry->mac, mac)) { - spin_unlock_bh(&bat_priv->vis_list_lock); + spin_unlock_bh(&bat_priv->vis.list_lock); return 1; } } - spin_unlock_bh(&bat_priv->vis_list_lock); + spin_unlock_bh(&bat_priv->vis.list_lock); return 0; }
@@ -354,7 +354,7 @@ batadv_add_packet(struct batadv_priv *bat_priv,
*is_new = 0; /* sanity check */ - if (!bat_priv->vis_hash) + if (!bat_priv->vis.hash) return NULL;
/* see if the packet is already in vis_hash */ @@ -385,7 +385,7 @@ batadv_add_packet(struct batadv_priv *bat_priv, } } /* remove old entry */ - batadv_hash_remove(bat_priv->vis_hash, batadv_vis_info_cmp, + batadv_hash_remove(bat_priv->vis.hash, batadv_vis_info_cmp, batadv_vis_info_choose, old_info); batadv_send_list_del(old_info); kref_put(&old_info->refcount, batadv_free_info); @@ -426,7 +426,7 @@ batadv_add_packet(struct batadv_priv *bat_priv, batadv_recv_list_add(bat_priv, &info->recv_list, packet->sender_orig);
/* try to add it */ - hash_added = batadv_hash_add(bat_priv->vis_hash, batadv_vis_info_cmp, + hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp, batadv_vis_info_choose, info, &info->hash_entry); if (hash_added != 0) { @@ -449,7 +449,7 @@ void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv,
make_broadcast = (vis_server == BATADV_VIS_TYPE_SERVER_SYNC);
- spin_lock_bh(&bat_priv->vis_hash_lock); + spin_lock_bh(&bat_priv->vis.hash_lock); info = batadv_add_packet(bat_priv, vis_packet, vis_info_len, &is_new, make_broadcast); if (!info) @@ -461,7 +461,7 @@ void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv, if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && is_new) batadv_send_list_add(bat_priv, info); end: - spin_unlock_bh(&bat_priv->vis_hash_lock); + spin_unlock_bh(&bat_priv->vis.hash_lock); }
/* handle an incoming client update packet and schedule forward if needed. */ @@ -484,7 +484,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv, batadv_is_my_mac(vis_packet->target_orig)) are_target = 1;
- spin_lock_bh(&bat_priv->vis_hash_lock); + spin_lock_bh(&bat_priv->vis.hash_lock); info = batadv_add_packet(bat_priv, vis_packet, vis_info_len, &is_new, are_target);
@@ -505,7 +505,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv, }
end: - spin_unlock_bh(&bat_priv->vis_hash_lock); + spin_unlock_bh(&bat_priv->vis.hash_lock); }
/* Walk the originators and find the VIS server with the best tq. Set the packet @@ -574,7 +574,7 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) struct hlist_head *head; struct batadv_orig_node *orig_node; struct batadv_neigh_node *router; - struct batadv_vis_info *info = bat_priv->my_vis_info; + struct batadv_vis_info *info = bat_priv->vis.my_info; struct batadv_vis_packet *packet; struct batadv_vis_info_entry *entry; struct batadv_tt_common_entry *tt_common_entry; @@ -636,7 +636,7 @@ next: rcu_read_unlock(); }
- hash = bat_priv->tt_local_hash; + hash = bat_priv->tt.local_hash;
for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -671,7 +671,7 @@ unlock: static void batadv_purge_vis_packets(struct batadv_priv *bat_priv) { uint32_t i; - struct batadv_hashtable *hash = bat_priv->vis_hash; + struct batadv_hashtable *hash = bat_priv->vis.hash; struct hlist_node *node, *node_tmp; struct hlist_head *head; struct batadv_vis_info *info; @@ -682,7 +682,7 @@ static void batadv_purge_vis_packets(struct batadv_priv *bat_priv) hlist_for_each_entry_safe(info, node, node_tmp, head, hash_entry) { /* never purge own data. */ - if (info == bat_priv->my_vis_info) + if (info == bat_priv->vis.my_info) continue;
if (batadv_has_timed_out(info->first_seen, @@ -817,31 +817,33 @@ static void batadv_send_vis_packets(struct work_struct *work) struct delayed_work *delayed_work = container_of(work, struct delayed_work, work); struct batadv_priv *bat_priv; + struct batadv_priv_vis *priv_vis; struct batadv_vis_info *info;
- bat_priv = container_of(delayed_work, struct batadv_priv, vis_work); - spin_lock_bh(&bat_priv->vis_hash_lock); + priv_vis = container_of(delayed_work, struct batadv_priv_vis, work); + bat_priv = container_of(priv_vis, struct batadv_priv, vis); + spin_lock_bh(&bat_priv->vis.hash_lock); batadv_purge_vis_packets(bat_priv);
if (batadv_generate_vis_packet(bat_priv) == 0) { /* schedule if generation was successful */ - batadv_send_list_add(bat_priv, bat_priv->my_vis_info); + batadv_send_list_add(bat_priv, bat_priv->vis.my_info); }
- while (!list_empty(&bat_priv->vis_send_list)) { - info = list_first_entry(&bat_priv->vis_send_list, + while (!list_empty(&bat_priv->vis.send_list)) { + info = list_first_entry(&bat_priv->vis.send_list, typeof(*info), send_list);
kref_get(&info->refcount); - spin_unlock_bh(&bat_priv->vis_hash_lock); + spin_unlock_bh(&bat_priv->vis.hash_lock);
batadv_send_vis_packet(bat_priv, info);
- spin_lock_bh(&bat_priv->vis_hash_lock); + spin_lock_bh(&bat_priv->vis.hash_lock); batadv_send_list_del(info); kref_put(&info->refcount, batadv_free_info); } - spin_unlock_bh(&bat_priv->vis_hash_lock); + spin_unlock_bh(&bat_priv->vis.hash_lock); batadv_start_vis_timer(bat_priv); }
@@ -856,37 +858,37 @@ int batadv_vis_init(struct batadv_priv *bat_priv) unsigned long first_seen; struct sk_buff *tmp_skb;
- if (bat_priv->vis_hash) + if (bat_priv->vis.hash) return 0;
- spin_lock_bh(&bat_priv->vis_hash_lock); + spin_lock_bh(&bat_priv->vis.hash_lock);
- bat_priv->vis_hash = batadv_hash_new(256); - if (!bat_priv->vis_hash) { + bat_priv->vis.hash = batadv_hash_new(256); + if (!bat_priv->vis.hash) { pr_err("Can't initialize vis_hash\n"); goto err; }
- bat_priv->my_vis_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC); - if (!bat_priv->my_vis_info) + bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC); + if (!bat_priv->vis.my_info) goto err;
len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN; - bat_priv->my_vis_info->skb_packet = dev_alloc_skb(len); - if (!bat_priv->my_vis_info->skb_packet) + bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len); + if (!bat_priv->vis.my_info->skb_packet) goto free_info;
- skb_reserve(bat_priv->my_vis_info->skb_packet, ETH_HLEN); - tmp_skb = bat_priv->my_vis_info->skb_packet; + skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN); + tmp_skb = bat_priv->vis.my_info->skb_packet; packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
/* prefill the vis info */ first_seen = jiffies - msecs_to_jiffies(BATADV_VIS_INTERVAL); - bat_priv->my_vis_info->first_seen = first_seen; - INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list); - INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list); - kref_init(&bat_priv->my_vis_info->refcount); - bat_priv->my_vis_info->bat_priv = bat_priv; + bat_priv->vis.my_info->first_seen = first_seen; + INIT_LIST_HEAD(&bat_priv->vis.my_info->recv_list); + INIT_LIST_HEAD(&bat_priv->vis.my_info->send_list); + kref_init(&bat_priv->vis.my_info->refcount); + bat_priv->vis.my_info->bat_priv = bat_priv; packet->header.version = BATADV_COMPAT_VERSION; packet->header.packet_type = BATADV_VIS; packet->header.ttl = BATADV_TTL; @@ -894,28 +896,28 @@ int batadv_vis_init(struct batadv_priv *bat_priv) packet->reserved = 0; packet->entries = 0;
- INIT_LIST_HEAD(&bat_priv->vis_send_list); + INIT_LIST_HEAD(&bat_priv->vis.send_list);
- hash_added = batadv_hash_add(bat_priv->vis_hash, batadv_vis_info_cmp, + hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp, batadv_vis_info_choose, - bat_priv->my_vis_info, - &bat_priv->my_vis_info->hash_entry); + bat_priv->vis.my_info, + &bat_priv->vis.my_info->hash_entry); if (hash_added != 0) { pr_err("Can't add own vis packet into hash\n"); /* not in hash, need to remove it manually. */ - kref_put(&bat_priv->my_vis_info->refcount, batadv_free_info); + kref_put(&bat_priv->vis.my_info->refcount, batadv_free_info); goto err; }
- spin_unlock_bh(&bat_priv->vis_hash_lock); + spin_unlock_bh(&bat_priv->vis.hash_lock); batadv_start_vis_timer(bat_priv); return 0;
free_info: - kfree(bat_priv->my_vis_info); - bat_priv->my_vis_info = NULL; + kfree(bat_priv->vis.my_info); + bat_priv->vis.my_info = NULL; err: - spin_unlock_bh(&bat_priv->vis_hash_lock); + spin_unlock_bh(&bat_priv->vis.hash_lock); batadv_vis_quit(bat_priv); return -ENOMEM; } @@ -933,23 +935,23 @@ static void batadv_free_info_ref(struct hlist_node *node, void *arg) /* shutdown vis-server */ void batadv_vis_quit(struct batadv_priv *bat_priv) { - if (!bat_priv->vis_hash) + if (!bat_priv->vis.hash) return;
- cancel_delayed_work_sync(&bat_priv->vis_work); + cancel_delayed_work_sync(&bat_priv->vis.work);
- spin_lock_bh(&bat_priv->vis_hash_lock); + spin_lock_bh(&bat_priv->vis.hash_lock); /* properly remove, kill timers ... */ - batadv_hash_delete(bat_priv->vis_hash, batadv_free_info_ref, NULL); - bat_priv->vis_hash = NULL; - bat_priv->my_vis_info = NULL; - spin_unlock_bh(&bat_priv->vis_hash_lock); + batadv_hash_delete(bat_priv->vis.hash, batadv_free_info_ref, NULL); + bat_priv->vis.hash = NULL; + bat_priv->vis.my_info = NULL; + spin_unlock_bh(&bat_priv->vis.hash_lock); }
/* schedule packets for (re)transmission */ static void batadv_start_vis_timer(struct batadv_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->vis_work, batadv_send_vis_packets); - queue_delayed_work(batadv_event_workqueue, &bat_priv->vis_work, + INIT_DELAYED_WORK(&bat_priv->vis.work, batadv_send_vis_packets); + queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work, msecs_to_jiffies(BATADV_VIS_INTERVAL)); }
From: Martin Hundebøll martin@hundeboll.net
batadv_check_unicast_packet() is needed in batadv_recv_tt_query(), so move the former to before the latter.
Signed-off-by: Martin Hundebøll martin@hundeboll.net Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/routing.c | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index d5edee7..a79ded5 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -579,6 +579,31 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, return router; }
+static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size) +{ + struct ethhdr *ethhdr; + + /* drop packet if it has not necessary minimum size */ + if (unlikely(!pskb_may_pull(skb, hdr_size))) + return -1; + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* packet with unicast indication but broadcast recipient */ + if (is_broadcast_ether_addr(ethhdr->h_dest)) + return -1; + + /* packet with broadcast sender address */ + if (is_broadcast_ether_addr(ethhdr->h_source)) + return -1; + + /* not for me */ + if (!batadv_is_my_mac(ethhdr->h_dest)) + return -1; + + return 0; +} + int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); @@ -819,31 +844,6 @@ err: return NULL; }
-static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size) -{ - struct ethhdr *ethhdr; - - /* drop packet if it has not necessary minimum size */ - if (unlikely(!pskb_may_pull(skb, hdr_size))) - return -1; - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* packet with unicast indication but broadcast recipient */ - if (is_broadcast_ether_addr(ethhdr->h_dest)) - return -1; - - /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) - return -1; - - /* not for me */ - if (!batadv_is_my_mac(ethhdr->h_dest)) - return -1; - - return 0; -} - static int batadv_route_unicast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) {
From: Martin Hundebøll martin@hundeboll.net
When enabling promiscuous mode, tt queries for other hosts might be received. Before this patch, "foreign" tt queries were processed like any other query and thus forwarded to its destination again and thereby causing a loop.
This patch adds a check to drop foreign tt queries.
Signed-off-by: Martin Hundebøll martin@hundeboll.net Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/routing.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index a79ded5..4961278 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -609,29 +609,17 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if) struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct batadv_tt_query_packet *tt_query; uint16_t tt_size; - struct ethhdr *ethhdr; + int hdr_size = sizeof(*tt_query); char tt_flag; size_t packet_size;
- /* drop packet if it has not necessary minimum size */ - if (unlikely(!pskb_may_pull(skb, - sizeof(struct batadv_tt_query_packet)))) - goto out; + if (batadv_check_unicast_packet(skb, hdr_size) < 0) + return NET_RX_DROP;
/* I could need to modify it */ if (skb_cow(skb, sizeof(struct batadv_tt_query_packet)) < 0) goto out;
- ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* packet with unicast indication but broadcast recipient */ - if (is_broadcast_ether_addr(ethhdr->h_dest)) - goto out; - - /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) - goto out; - tt_query = (struct batadv_tt_query_packet *)skb->data;
switch (tt_query->flags & BATADV_TT_QUERY_TYPE_MASK) {
From: Sven Eckelmann sven@narfation.org
Signed-off-by: Sven Eckelmann sven@narfation.org Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/bat_iv_ogm.c | 12 +++++++----- net/batman-adv/main.h | 18 +++++++++--------- net/batman-adv/packet.h | 30 +++++++++++++++--------------- 3 files changed, 31 insertions(+), 29 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index eb507c9..daaccc1 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -181,8 +181,8 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, /* we might have aggregated direct link packets with an * ordinary base packet */ - if ((forw_packet->direct_link_flags & (1 << packet_num)) && - (forw_packet->if_incoming == hard_iface)) + if (forw_packet->direct_link_flags & BIT(packet_num) && + forw_packet->if_incoming == hard_iface) batadv_ogm_packet->flags |= BATADV_DIRECTLINK; else batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK; @@ -454,6 +454,7 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr, int packet_len, bool direct_link) { unsigned char *skb_buff; + unsigned long new_direct_link_flag;
skb_buff = skb_put(forw_packet_aggr->skb, packet_len); memcpy(skb_buff, packet_buff, packet_len); @@ -461,9 +462,10 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr, forw_packet_aggr->num_packets++;
/* save packet direct link flag status */ - if (direct_link) - forw_packet_aggr->direct_link_flags |= - (1 << forw_packet_aggr->num_packets); + if (direct_link) { + new_direct_link_flag = BIT(forw_packet_aggr->num_packets); + forw_packet_aggr->direct_link_flags |= new_direct_link_flag; + } }
static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv, diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 4dfeae5..574fca1 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -123,15 +123,6 @@ enum batadv_uev_type { /* Append 'batman-adv: ' before kernel messages */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-/* all messages related to routing / flooding / broadcasting / etc */ -enum batadv_dbg_level { - BATADV_DBG_BATMAN = 1 << 0, - BATADV_DBG_ROUTES = 1 << 1, /* route added / changed / deleted */ - BATADV_DBG_TT = 1 << 2, /* translation table operations */ - BATADV_DBG_BLA = 1 << 3, /* bridge loop avoidance */ - BATADV_DBG_ALL = 15, -}; - /* Kernel headers */
#include <linux/mutex.h> /* mutex */ @@ -173,6 +164,15 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops); int batadv_algo_select(struct batadv_priv *bat_priv, char *name); int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
+/* all messages related to routing / flooding / broadcasting / etc */ +enum batadv_dbg_level { + BATADV_DBG_BATMAN = BIT(0), + BATADV_DBG_ROUTES = BIT(1), /* route added / changed / deleted */ + BATADV_DBG_TT = BIT(2), /* translation table operations */ + BATADV_DBG_BLA = BIT(3), /* bridge loop avoidance */ + BATADV_DBG_ALL = 15, +}; + #ifdef CONFIG_BATMAN_ADV_DEBUG int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) __printf(2, 3); diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 65d66e4..eb45934 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -37,10 +37,10 @@ enum batadv_packettype { #define BATADV_COMPAT_VERSION 14
enum batadv_iv_flags { - BATADV_NOT_BEST_NEXT_HOP = 1 << 3, - BATADV_PRIMARIES_FIRST_HOP = 1 << 4, - BATADV_VIS_SERVER = 1 << 5, - BATADV_DIRECTLINK = 1 << 6, + BATADV_NOT_BEST_NEXT_HOP = BIT(3), + BATADV_PRIMARIES_FIRST_HOP = BIT(4), + BATADV_VIS_SERVER = BIT(5), + BATADV_DIRECTLINK = BIT(6), };
/* ICMP message types */ @@ -60,8 +60,8 @@ enum batadv_vis_packettype {
/* fragmentation defines */ enum batadv_unicast_frag_flags { - BATADV_UNI_FRAG_HEAD = 1 << 0, - BATADV_UNI_FRAG_LARGETAIL = 1 << 1, + BATADV_UNI_FRAG_HEAD = BIT(0), + BATADV_UNI_FRAG_LARGETAIL = BIT(1), };
/* TT_QUERY subtypes */ @@ -74,20 +74,20 @@ enum batadv_tt_query_packettype {
/* TT_QUERY flags */ enum batadv_tt_query_flags { - BATADV_TT_FULL_TABLE = 1 << 2, + BATADV_TT_FULL_TABLE = BIT(2), };
/* BATADV_TT_CLIENT flags. - * Flags from 1 to 1 << 7 are sent on the wire, while flags from 1 << 8 to - * 1 << 15 are used for local computation only + * Flags from BIT(0) to BIT(7) are sent on the wire, while flags from BIT(8) to + * BIT(15) are used for local computation only */ enum batadv_tt_client_flags { - BATADV_TT_CLIENT_DEL = 1 << 0, - BATADV_TT_CLIENT_ROAM = 1 << 1, - BATADV_TT_CLIENT_WIFI = 1 << 2, - BATADV_TT_CLIENT_NOPURGE = 1 << 8, - BATADV_TT_CLIENT_NEW = 1 << 9, - BATADV_TT_CLIENT_PENDING = 1 << 10, + BATADV_TT_CLIENT_DEL = BIT(0), + BATADV_TT_CLIENT_ROAM = BIT(1), + BATADV_TT_CLIENT_WIFI = BIT(2), + BATADV_TT_CLIENT_NOPURGE = BIT(8), + BATADV_TT_CLIENT_NEW = BIT(9), + BATADV_TT_CLIENT_PENDING = BIT(10), };
/* claim frame types for the bridge loop avoidance */
From: Sven Eckelmann sven@narfation.org
Signed-off-by: Sven Eckelmann sven@narfation.org Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/bat_iv_ogm.c | 39 +++++++++++++++++--------------- net/batman-adv/bridge_loop_avoidance.c | 7 +++--- net/batman-adv/send.c | 8 +++---- net/batman-adv/soft-interface.c | 5 ++-- net/batman-adv/unicast.c | 11 +++++---- net/batman-adv/vis.c | 4 ++-- 6 files changed, 39 insertions(+), 35 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index daaccc1..616d52d 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -588,6 +588,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) struct batadv_ogm_packet *batadv_ogm_packet; struct batadv_hard_iface *primary_if; int vis_server, tt_num_changes = 0; + uint32_t seqno; + uint8_t bandwidth;
vis_server = atomic_read(&bat_priv->vis_mode); primary_if = batadv_primary_if_get_selected(bat_priv); @@ -601,8 +603,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff;
/* change sequence number to network order */ - batadv_ogm_packet->seqno = - htonl((uint32_t)atomic_read(&hard_iface->seqno)); + seqno = (uint32_t)atomic_read(&hard_iface->seqno); + batadv_ogm_packet->seqno = htonl(seqno); atomic_inc(&hard_iface->seqno);
batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn); @@ -615,12 +617,13 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) else batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER;
- if ((hard_iface == primary_if) && - (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER)) - batadv_ogm_packet->gw_flags = - (uint8_t)atomic_read(&bat_priv->gw_bandwidth); - else + if (hard_iface == primary_if && + atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER) { + bandwidth = (uint8_t)atomic_read(&bat_priv->gw_bandwidth); + batadv_ogm_packet->gw_flags = bandwidth; + } else { batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS; + }
batadv_slide_own_bcast_window(hard_iface); batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, @@ -644,8 +647,9 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, struct batadv_neigh_node *router = NULL; struct batadv_orig_node *orig_node_tmp; struct hlist_node *node; - uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; + uint8_t sum_orig, sum_neigh; uint8_t *neigh_addr; + uint8_t tq_avg;
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "update_originator(): Searching and updating originator entry of received packet\n"); @@ -669,8 +673,8 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, spin_lock_bh(&tmp_neigh_node->lq_update_lock); batadv_ring_buffer_set(tmp_neigh_node->tq_recv, &tmp_neigh_node->tq_index, 0); - tmp_neigh_node->tq_avg = - batadv_ring_buffer_avg(tmp_neigh_node->tq_recv); + tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->tq_recv); + tmp_neigh_node->tq_avg = tq_avg; spin_unlock_bh(&tmp_neigh_node->lq_update_lock); }
@@ -729,17 +733,15 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, if (router && (neigh_node->tq_avg == router->tq_avg)) { orig_node_tmp = router->orig_node; spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); - bcast_own_sum_orig = - orig_node_tmp->bcast_own_sum[if_incoming->if_num]; + sum_orig = orig_node_tmp->bcast_own_sum[if_incoming->if_num]; spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
orig_node_tmp = neigh_node->orig_node; spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); - bcast_own_sum_neigh = - orig_node_tmp->bcast_own_sum[if_incoming->if_num]; + sum_neigh = orig_node_tmp->bcast_own_sum[if_incoming->if_num]; spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
- if (bcast_own_sum_orig >= bcast_own_sum_neigh) + if (sum_orig >= sum_neigh) goto update_tt; }
@@ -912,6 +914,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, int set_mark, ret = -1; uint32_t seqno = ntohl(batadv_ogm_packet->seqno); uint8_t *neigh_addr; + uint8_t packet_count;
orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); if (!orig_node) @@ -946,9 +949,9 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, tmp_neigh_node->real_bits, seq_diff, set_mark);
- tmp_neigh_node->real_packet_count = - bitmap_weight(tmp_neigh_node->real_bits, - BATADV_TQ_LOCAL_WINDOW_SIZE); + packet_count = bitmap_weight(tmp_neigh_node->real_bits, + BATADV_TQ_LOCAL_WINDOW_SIZE); + tmp_neigh_node->real_packet_count = packet_count; } rcu_read_unlock();
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index ad18017..7a93b2a 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -579,8 +579,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv, "bla_add_claim(): changing ownership for %pM, vid %d\n", mac, vid);
- 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);
} @@ -1102,8 +1101,7 @@ static void batadv_bla_start_timer(struct batadv_priv *bat_priv) */ static void batadv_bla_periodic_work(struct work_struct *work) { - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); + struct delayed_work *delayed_work; struct batadv_priv *bat_priv; struct batadv_priv_bla *priv_bla; struct hlist_node *node; @@ -1113,6 +1111,7 @@ static void batadv_bla_periodic_work(struct work_struct *work) struct batadv_hard_iface *primary_if; int i;
+ delayed_work = container_of(work, struct delayed_work, work); priv_bla = container_of(delayed_work, struct batadv_priv_bla, work); bat_priv = container_of(priv_bla, struct batadv_priv, bla); primary_if = batadv_primary_if_get_selected(bat_priv); diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 3b4b2da..570a8bc 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -190,13 +190,13 @@ out: static void batadv_send_outstanding_bcast_packet(struct work_struct *work) { struct batadv_hard_iface *hard_iface; - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); + struct delayed_work *delayed_work; struct batadv_forw_packet *forw_packet; struct sk_buff *skb1; struct net_device *soft_iface; struct batadv_priv *bat_priv;
+ delayed_work = container_of(work, struct delayed_work, work); forw_packet = container_of(delayed_work, struct batadv_forw_packet, delayed_work); soft_iface = forw_packet->if_incoming->soft_iface; @@ -239,11 +239,11 @@ out:
void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work) { - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); + struct delayed_work *delayed_work; struct batadv_forw_packet *forw_packet; struct batadv_priv *bat_priv;
+ delayed_work = container_of(work, struct delayed_work, work); forw_packet = container_of(delayed_work, struct batadv_forw_packet, delayed_work); bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 6d44625..03b0763 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -149,6 +149,7 @@ static int batadv_interface_tx(struct sk_buff *skb, int data_len = skb->len, ret; short vid __maybe_unused = -1; bool do_bcast = false; + uint32_t seqno;
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) goto dropped; @@ -230,8 +231,8 @@ static int batadv_interface_tx(struct sk_buff *skb, primary_if->net_dev->dev_addr, ETH_ALEN);
/* set broadcast sequence number */ - bcast_packet->seqno = - htonl(atomic_inc_return(&bat_priv->bcast_seqno)); + seqno = atomic_inc_return(&bat_priv->bcast_seqno); + bcast_packet->seqno = htonl(seqno);
batadv_add_bcast_packet_to_list(bat_priv, skb, 1);
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 0016464..d7904bd 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -121,6 +121,7 @@ batadv_frag_search_packet(struct list_head *head, { struct batadv_frag_packet_list_entry *tfp; struct batadv_unicast_frag_packet *tmp_up = NULL; + int is_head_tmp, is_head; uint16_t search_seqno;
if (up->flags & BATADV_UNI_FRAG_HEAD) @@ -128,6 +129,8 @@ batadv_frag_search_packet(struct list_head *head, else search_seqno = ntohs(up->seqno)-1;
+ is_head = !!(up->flags & BATADV_UNI_FRAG_HEAD); + list_for_each_entry(tfp, head, list) {
if (!tfp->skb) @@ -139,9 +142,8 @@ batadv_frag_search_packet(struct list_head *head, tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data;
if (tfp->seqno == search_seqno) { - - if ((tmp_up->flags & BATADV_UNI_FRAG_HEAD) != - (up->flags & BATADV_UNI_FRAG_HEAD)) + is_head_tmp = !!(tmp_up->flags & BATADV_UNI_FRAG_HEAD); + if (is_head_tmp != is_head) return tfp; else goto mov_tail; @@ -334,8 +336,7 @@ find_router: /* copy the destination for faster routing */ memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); /* set the destination tt version number */ - unicast_packet->ttvn = - (uint8_t)atomic_read(&orig_node->last_ttvn); + unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
/* inform the destination node that we are still missing a correct route * for this client. The destination will receive this packet and will diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 4608c1b2..55cc51b 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -814,12 +814,12 @@ out: /* called from timer; send (and maybe generate) vis packet. */ static void batadv_send_vis_packets(struct work_struct *work) { - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); + struct delayed_work *delayed_work; struct batadv_priv *bat_priv; struct batadv_priv_vis *priv_vis; struct batadv_vis_info *info;
+ delayed_work = container_of(work, struct delayed_work, work); priv_vis = container_of(delayed_work, struct batadv_priv_vis, work); bat_priv = container_of(priv_vis, struct batadv_priv, vis); spin_lock_bh(&bat_priv->vis.hash_lock);
From: Sven Eckelmann sven@narfation.org
Signed-off-by: Sven Eckelmann sven@narfation.org Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/bat_iv_ogm.c | 41 ++++++++++++++++++++------------ net/batman-adv/bridge_loop_avoidance.c | 3 +-- net/batman-adv/gateway_client.c | 21 +++++++++------- net/batman-adv/routing.c | 3 +-- net/batman-adv/translation-table.c | 10 ++++---- net/batman-adv/unicast.c | 5 ++-- net/batman-adv/vis.c | 10 ++++---- 7 files changed, 55 insertions(+), 38 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 616d52d..df79300 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -166,13 +166,15 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, int16_t buff_pos; struct batadv_ogm_packet *batadv_ogm_packet; struct sk_buff *skb; + uint8_t *packet_pos;
if (hard_iface->if_status != BATADV_IF_ACTIVE) return;
packet_num = 0; buff_pos = 0; - batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data; + packet_pos = forw_packet->skb->data; + batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
/* adjust all flags and log packets */ while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, @@ -187,9 +189,11 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, else batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
- fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? - "Sending own" : - "Forwarding")); + if (packet_num > 0 || !forw_packet->own) + fwd_str = "Forwarding"; + else + fwd_str = "Sending own"; + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n", fwd_str, (packet_num > 0 ? "aggregated " : ""), @@ -204,8 +208,8 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, buff_pos += BATADV_OGM_HLEN; buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes); packet_num++; - batadv_ogm_packet = (struct batadv_ogm_packet *) - (forw_packet->skb->data + buff_pos); + packet_pos = forw_packet->skb->data + buff_pos; + batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos; }
/* create clone because function is called more than once */ @@ -227,9 +231,10 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet) struct batadv_hard_iface *primary_if = NULL; struct batadv_ogm_packet *batadv_ogm_packet; unsigned char directlink; + uint8_t *packet_pos;
- batadv_ogm_packet = (struct batadv_ogm_packet *) - (forw_packet->skb->data); + packet_pos = forw_packet->skb->data; + batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos; directlink = (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) { @@ -839,8 +844,10 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, spin_unlock_bh(&orig_node->ogm_cnt_lock);
/* pay attention to not get a value bigger than 100 % */ - total_count = (orig_eq_count > neigh_rq_count ? - neigh_rq_count : orig_eq_count); + if (orig_eq_count > neigh_rq_count) + total_count = neigh_rq_count; + else + total_count = orig_eq_count;
/* if we have too few packets (too less data) we set tq_own to zero * if we receive too few packets it is not considered bidirectional @@ -1168,9 +1175,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, /* if sender is a direct neighbor the sender mac equals * originator mac */ - orig_neigh_node = (is_single_hop_neigh ? - orig_node : - batadv_get_orig_node(bat_priv, ethhdr->h_source)); + if (is_single_hop_neigh) + orig_neigh_node = orig_node; + else + orig_neigh_node = batadv_get_orig_node(bat_priv, + ethhdr->h_source); + if (!orig_neigh_node) goto out;
@@ -1256,6 +1266,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, int buff_pos = 0, packet_len; unsigned char *tt_buff, *packet_buff; bool ret; + uint8_t *packet_pos;
ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN); if (!ret) @@ -1286,8 +1297,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, buff_pos += BATADV_OGM_HLEN; buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes);
- batadv_ogm_packet = (struct batadv_ogm_packet *) - (packet_buff + buff_pos); + packet_pos = packet_buff + buff_pos; + batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos; } while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len, batadv_ogm_packet->tt_num_changes));
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 7a93b2a..0a9084a 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1345,8 +1345,7 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb, if (!pskb_may_pull(skb, hdr_size + sizeof(struct vlan_ethhdr))) return 0;
- vhdr = (struct vlan_ethhdr *)(((uint8_t *)skb->data) + - hdr_size); + vhdr = (struct vlan_ethhdr *)(skb->data + hdr_size); vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; }
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index eef7cc7..15d67ab 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -117,10 +117,15 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) struct hlist_node *node; struct batadv_gw_node *gw_node, *curr_gw = NULL; uint32_t max_gw_factor = 0, tmp_gw_factor = 0; + uint32_t gw_divisor; uint8_t max_tq = 0; int down, up; + 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, node, &bat_priv->gw.list, list) { if (gw_node->deleted) @@ -134,19 +139,19 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) if (!atomic_inc_not_zero(&gw_node->refcount)) goto next;
+ tq_avg = router->tq_avg; + switch (atomic_read(&bat_priv->gw_sel_class)) { case 1: /* fast connection */ batadv_gw_bandwidth_to_kbit(orig_node->gw_flags, &down, &up);
- tmp_gw_factor = (router->tq_avg * router->tq_avg * - down * 100 * 100) / - (BATADV_TQ_LOCAL_WINDOW_SIZE * - BATADV_TQ_LOCAL_WINDOW_SIZE * 64); + tmp_gw_factor = tq_avg * tq_avg * down * 100 * 100; + tmp_gw_factor /= gw_divisor;
if ((tmp_gw_factor > max_gw_factor) || ((tmp_gw_factor == max_gw_factor) && - (router->tq_avg > max_tq))) { + (tq_avg > max_tq))) { if (curr_gw) batadv_gw_node_free_ref(curr_gw); curr_gw = gw_node; @@ -161,7 +166,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) * soon as a better gateway appears which has * $routing_class more tq points) */ - if (router->tq_avg > max_tq) { + if (tq_avg > max_tq) { if (curr_gw) batadv_gw_node_free_ref(curr_gw); curr_gw = gw_node; @@ -170,8 +175,8 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) break; }
- if (router->tq_avg > max_tq) - max_tq = router->tq_avg; + if (tq_avg > max_tq) + max_tq = tq_avg;
if (tmp_gw_factor > max_gw_factor) max_gw_factor = tmp_gw_factor; diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 4961278..9f933c9 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -981,8 +981,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, } else { memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); - curr_ttvn = (uint8_t) - atomic_read(&orig_node->last_ttvn); + curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); batadv_orig_node_free_ref(orig_node); }
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index b01049a..cb429d1 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1559,6 +1559,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, uint16_t tt_len, tt_tot; struct sk_buff *skb = NULL; struct batadv_tt_query_packet *tt_response; + uint8_t *packet_pos; size_t len;
batadv_dbg(BATADV_DBG_TT, bat_priv, @@ -1612,8 +1613,8 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, goto unlock;
skb_reserve(skb, ETH_HLEN); - tt_response = (struct batadv_tt_query_packet *)skb_put(skb, - len); + packet_pos = skb_put(skb, len); + tt_response = (struct batadv_tt_query_packet *)packet_pos; tt_response->ttvn = req_ttvn; tt_response->tt_data = htons(tt_tot);
@@ -1692,6 +1693,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, uint16_t tt_len, tt_tot; struct sk_buff *skb = NULL; struct batadv_tt_query_packet *tt_response; + uint8_t *packet_pos; size_t len;
batadv_dbg(BATADV_DBG_TT, bat_priv, @@ -1738,8 +1740,8 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, goto unlock;
skb_reserve(skb, ETH_HLEN); - tt_response = (struct batadv_tt_query_packet *)skb_put(skb, - len); + packet_pos = skb_put(skb, len); + tt_response = (struct batadv_tt_query_packet *)packet_pos; tt_response->ttvn = req_ttvn; tt_response->tt_data = htons(tt_tot);
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index d7904bd..f397232 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -39,6 +39,7 @@ batadv_frag_merge_packet(struct list_head *head, struct batadv_unicast_packet *unicast_packet; int hdr_len = sizeof(*unicast_packet); int uni_diff = sizeof(*up) - hdr_len; + uint8_t *packet_pos;
up = (struct batadv_unicast_frag_packet *)skb->data; /* set skb to the first part and tmp_skb to the second part */ @@ -65,8 +66,8 @@ batadv_frag_merge_packet(struct list_head *head, kfree_skb(tmp_skb);
memmove(skb->data + uni_diff, skb->data, hdr_len); - unicast_packet = (struct batadv_unicast_packet *)skb_pull(skb, - uni_diff); + packet_pos = skb_pull(skb, uni_diff); + unicast_packet = (struct batadv_unicast_packet *)packet_pos; unicast_packet->header.packet_type = BATADV_UNICAST;
return skb; diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 55cc51b..5abd145 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -578,6 +578,7 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) struct batadv_vis_packet *packet; struct batadv_vis_info_entry *entry; struct batadv_tt_common_entry *tt_common_entry; + uint8_t *packet_pos; int best_tq = -1; uint32_t i;
@@ -618,8 +619,8 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) goto next;
/* fill one entry into buffer. */ - entry = (struct batadv_vis_info_entry *) - skb_put(info->skb_packet, sizeof(*entry)); + packet_pos = skb_put(info->skb_packet, sizeof(*entry)); + entry = (struct batadv_vis_info_entry *)packet_pos; memcpy(entry->src, router->if_incoming->net_dev->dev_addr, ETH_ALEN); @@ -644,9 +645,8 @@ next: rcu_read_lock(); hlist_for_each_entry_rcu(tt_common_entry, node, head, hash_entry) { - entry = (struct batadv_vis_info_entry *) - skb_put(info->skb_packet, - sizeof(*entry)); + packet_pos = skb_put(info->skb_packet, sizeof(*entry)); + entry = (struct batadv_vis_info_entry *)packet_pos; memset(entry->src, 0, ETH_ALEN); memcpy(entry->dest, tt_common_entry->addr, ETH_ALEN); entry->quality = 0; /* 0 means TT */
With the current TT mechanism a new client joining the network is not immediately able to communicate with other hosts because its MAC address has not been announced yet. This situation holds until the first OGM containing its joining event will be spread over the mesh network.
This behaviour can be acceptable in networks where the originator interval is a small value (e.g. 1sec) but if that value is set to an higher time (e.g. 5secs) the client could suffer from several malfunctions like DHCP client timeouts, etc.
This patch adds an early detection mechanism that makes nodes in the network able to recognise "not yet announced clients" by means of the broadcast packets they emitted on connection (e.g. ARP or DHCP request). The added client will then be confirmed upon receiving the OGM claiming it or purged if such OGM is not received within a fixed amount of time.
Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/main.h | 1 + net/batman-adv/packet.h | 1 + net/batman-adv/translation-table.c | 127 +++++++++++++++++++++++++++--------- net/batman-adv/translation-table.h | 4 +- net/batman-adv/types.h | 1 + 5 files changed, 101 insertions(+), 33 deletions(-)
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 574fca1..61a0cfd 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -43,6 +43,7 @@ #define BATADV_PURGE_TIMEOUT 200000 /* 200 seconds */ #define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */ #define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */ +#define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */ /* sliding packet range of received originator messages in sequence numbers * (should be a multiple of our word size) */ diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index eb45934..2d23a14 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -85,6 +85,7 @@ enum batadv_tt_client_flags { BATADV_TT_CLIENT_DEL = BIT(0), BATADV_TT_CLIENT_ROAM = BIT(1), BATADV_TT_CLIENT_WIFI = BIT(2), + BATADV_TT_CLIENT_TEMP = BIT(3), BATADV_TT_CLIENT_NOPURGE = BIT(8), BATADV_TT_CLIENT_NEW = BIT(9), BATADV_TT_CLIENT_PENDING = BIT(10), diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index cb429d1..112edd3 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -34,6 +34,10 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, static void batadv_tt_purge(struct work_struct *work); static void batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry); +static void batadv_tt_global_del(struct batadv_priv *bat_priv, + struct batadv_orig_node *orig_node, + const unsigned char *addr, + const char *message, bool roaming);
/* returns 1 if they are the same mac addr */ static int batadv_compare_tt(const struct hlist_node *node, const void *data2) @@ -268,6 +272,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, tt_local_entry->common.flags |= BATADV_TT_CLIENT_WIFI; atomic_set(&tt_local_entry->common.refcount, 2); tt_local_entry->last_seen = jiffies; + tt_local_entry->common.added_at = tt_local_entry->last_seen;
/* the batman interface mac address should never be purged */ if (batadv_compare_eth(addr, soft_iface->dev_addr)) @@ -682,8 +687,13 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, struct batadv_tt_orig_list_entry *orig_entry;
orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node); - if (orig_entry) + if (orig_entry) { + /* refresh the ttvn: the current value could be a bogus one that + * was added during a "temporary client detection" + */ + orig_entry->ttvn = ttvn; goto out; + }
orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC); if (!orig_entry) @@ -729,6 +739,7 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, common->flags = flags; tt_global_entry->roam_at = 0; atomic_set(&common->refcount, 2); + common->added_at = jiffies;
INIT_HLIST_HEAD(&tt_global_entry->orig_list); spin_lock_init(&tt_global_entry->list_lock); @@ -744,7 +755,19 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, goto out_remove; } } else { - /* there is already a global entry, use this one. */ + /* If there is already a global entry, we can use this one for + * our processing. + * But if we are trying to add a temporary client we can exit + * directly because the temporary information should never + * override any already known client state (whatever it is) + */ + if (flags & BATADV_TT_CLIENT_TEMP) + goto out; + + /* if the client was temporary added before receiving the first + * OGM announcing it, we have to clear the TEMP flag + */ + tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP;
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only * one originator left in the list and we previously received a @@ -758,9 +781,8 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; tt_global_entry->roam_at = 0; } - } - /* add the new orig_entry (if needed) */ + /* add the new orig_entry (if needed) or update it */ batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
batadv_dbg(BATADV_DBG_TT, bat_priv, @@ -800,11 +822,12 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry, hlist_for_each_entry_rcu(orig_entry, node, head, list) { flags = tt_common_entry->flags; last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn); - seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c]\n", + seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c%c]\n", tt_global_entry->common.addr, orig_entry->ttvn, orig_entry->orig_node->orig, last_ttvn, (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), - (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.')); + (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'), + (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.')); } }
@@ -1059,49 +1082,63 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, orig_node->tt_initialised = false; }
-static void batadv_tt_global_roam_purge_list(struct batadv_priv *bat_priv, - struct hlist_head *head) +static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global, + char **msg) { - struct batadv_tt_common_entry *tt_common_entry; - struct batadv_tt_global_entry *tt_global_entry; - struct hlist_node *node, *node_tmp; + bool purge = false; + unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT; + unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT;
- hlist_for_each_entry_safe(tt_common_entry, node, node_tmp, head, - hash_entry) { - tt_global_entry = container_of(tt_common_entry, - struct batadv_tt_global_entry, - common); - if (!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM)) - continue; - if (!batadv_has_timed_out(tt_global_entry->roam_at, - BATADV_TT_CLIENT_ROAM_TIMEOUT)) - continue; - - batadv_dbg(BATADV_DBG_TT, bat_priv, - "Deleting global tt entry (%pM): Roaming timeout\n", - tt_global_entry->common.addr); + if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) && + batadv_has_timed_out(tt_global->roam_at, roam_timeout)) { + purge = true; + *msg = "Roaming timeout\n"; + }
- hlist_del_rcu(node); - batadv_tt_global_entry_free_ref(tt_global_entry); + if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) && + batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) { + purge = true; + *msg = "Temporary client timeout\n"; } + + return purge; }
-static void batadv_tt_global_roam_purge(struct batadv_priv *bat_priv) +static void batadv_tt_global_purge(struct batadv_priv *bat_priv) { struct batadv_hashtable *hash = bat_priv->tt.global_hash; struct hlist_head *head; + struct hlist_node *node, *node_tmp; spinlock_t *list_lock; /* protects write access to the hash lists */ uint32_t i; + char *msg = NULL; + struct batadv_tt_common_entry *tt_common; + struct batadv_tt_global_entry *tt_global;
for (i = 0; i < hash->size; i++) { head = &hash->table[i]; list_lock = &hash->list_locks[i];
spin_lock_bh(list_lock); - batadv_tt_global_roam_purge_list(bat_priv, head); + hlist_for_each_entry_safe(tt_common, node, node_tmp, head, + hash_entry) { + tt_global = container_of(tt_common, + struct batadv_tt_global_entry, + common); + + if (!batadv_tt_global_to_purge(tt_global, &msg)) + continue; + + batadv_dbg(BATADV_DBG_TT, bat_priv, + "Deleting global tt entry (%pM): %s\n", + tt_global->common.addr, msg); + + hlist_del_rcu(node); + + batadv_tt_global_entry_free_ref(tt_global); + } spin_unlock_bh(list_lock); } - }
static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) @@ -1239,6 +1276,12 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv, */ if (tt_common->flags & BATADV_TT_CLIENT_ROAM) continue; + /* Temporary clients have not been announced yet, so + * they have to be skipped while computing the global + * crc + */ + if (tt_common->flags & BATADV_TT_CLIENT_TEMP) + continue;
/* find out if this global entry is announced by this * originator @@ -1392,7 +1435,8 @@ static int batadv_tt_global_valid(const void *entry_ptr, const struct batadv_tt_global_entry *tt_global_entry; const struct batadv_orig_node *orig_node = data_ptr;
- if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM) + if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || + tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) return 0;
tt_global_entry = container_of(tt_common_entry, @@ -2125,7 +2169,7 @@ static void batadv_tt_purge(struct work_struct *work) bat_priv = container_of(priv_tt, struct batadv_priv, tt);
batadv_tt_local_purge(bat_priv); - batadv_tt_global_roam_purge(bat_priv); + batadv_tt_global_purge(bat_priv); batadv_tt_req_purge(bat_priv); batadv_tt_roam_purge(bat_priv);
@@ -2399,3 +2443,22 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, out: return ret; } + +bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, + struct batadv_orig_node *orig_node, + const unsigned char *addr) +{ + bool ret = false; + + if (!batadv_tt_global_add(bat_priv, orig_node, addr, + BATADV_TT_CLIENT_TEMP, + atomic_read(&orig_node->last_ttvn))) + goto out; + + batadv_dbg(BATADV_DBG_TT, bat_priv, + "Added temporary global client (addr: %pM orig: %pM)\n", + addr, orig_node->orig); + ret = true; +out: + return ret; +} diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index ffa8735..811fffd 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h @@ -59,6 +59,8 @@ int batadv_tt_append_diff(struct batadv_priv *bat_priv, int packet_min_len); bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, uint8_t *addr); - +bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, + struct batadv_orig_node *orig_node, + const unsigned char *addr);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 97c4978..2ed82ca 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -284,6 +284,7 @@ struct batadv_tt_common_entry { uint8_t addr[ETH_ALEN]; struct hlist_node hash_entry; uint16_t flags; + unsigned long added_at; atomic_t refcount; struct rcu_head rcu; };
In order to understand where a broadcast packet is coming from and use this information to detect not yet announced clients, this patch modifies the interface_rx() function by passing a new argument: the orig node corresponding to the node that originated the received packet (if known). This new argument if not NULL for broadcast packets only (other packets does not have source field).
Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/routing.c | 10 ++++++---- net/batman-adv/soft-interface.c | 6 +++++- net/batman-adv/soft-interface.h | 5 +++-- 3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 9f933c9..939fc01 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -1012,8 +1012,9 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
/* packet for me */ if (batadv_is_my_mac(unicast_packet->dest)) { - batadv_interface_rx(recv_if->soft_iface, skb, recv_if, - hdr_size); + batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, + NULL); + return NET_RX_SUCCESS; }
@@ -1050,7 +1051,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, return NET_RX_SUCCESS;
batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, - sizeof(struct batadv_unicast_packet)); + sizeof(struct batadv_unicast_packet), NULL); return NET_RX_SUCCESS; }
@@ -1137,7 +1138,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, goto out;
/* broadcast for me */ - batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); + batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, + orig_node); ret = NET_RX_SUCCESS; goto out;
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 03b0763..7b683e0 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -270,7 +270,7 @@ end:
void batadv_interface_rx(struct net_device *soft_iface, struct sk_buff *skb, struct batadv_hard_iface *recv_if, - int hdr_size) + int hdr_size, struct batadv_orig_node *orig_node) { struct batadv_priv *bat_priv = netdev_priv(soft_iface); struct ethhdr *ethhdr; @@ -322,6 +322,10 @@ void batadv_interface_rx(struct net_device *soft_iface,
soft_iface->last_rx = jiffies;
+ if (orig_node) + batadv_tt_add_temporary_global_entry(bat_priv, orig_node, + ethhdr->h_source); + if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) goto dropped;
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h index 852c683..07a08fe 100644 --- a/net/batman-adv/soft-interface.h +++ b/net/batman-adv/soft-interface.h @@ -21,8 +21,9 @@ #define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
int batadv_skb_head_push(struct sk_buff *skb, unsigned int len); -void batadv_interface_rx(struct net_device *soft_iface, struct sk_buff *skb, - struct batadv_hard_iface *recv_if, int hdr_size); +void batadv_interface_rx(struct net_device *soft_iface, + struct sk_buff *skb, struct batadv_hard_iface *recv_if, + int hdr_size, struct batadv_orig_node *orig_node); struct net_device *batadv_softif_create(const char *name); void batadv_softif_destroy(struct net_device *soft_iface); int batadv_softif_is_valid(const struct net_device *net_dev);
From: Sven Eckelmann sven@narfation.org
Signed-off-by: Sven Eckelmann sven@narfation.org Signed-off-by: Antonio Quartulli ordex@autistici.org --- net/batman-adv/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 61a0cfd..d57b746 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -26,7 +26,7 @@ #define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION -#define BATADV_SOURCE_VERSION "2012.3.0" +#define BATADV_SOURCE_VERSION "2012.4.0" #endif
/* B.A.T.M.A.N. parameters */
From: Antonio Quartulli ordex@autistici.org Date: Thu, 23 Aug 2012 15:10:09 +0200
this is our set of changes intended for net-next/linux-3.7. It is mostly composed by style fixes and cleanups. Other than that you have a patch introducing a new table in debugfs (backbone gateways table for the Bridge Loop Avoidance) and a new mechanism for the TranslationTable component. The latter allows mesh nodes to immediately detect new clients joining the network, without waiting for any periodic advertisement.
Pulled, thanks Antonio.
b.a.t.m.a.n@lists.open-mesh.org