diff options
Diffstat (limited to 'drivers/staging/batman-adv/translation-table.c')
-rw-r--r-- | drivers/staging/batman-adv/translation-table.c | 518 |
1 files changed, 0 insertions, 518 deletions
diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c deleted file mode 100644 index 681ccbda3ea..00000000000 --- a/drivers/staging/batman-adv/translation-table.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "translation-table.h" -#include "soft-interface.h" -#include "types.h" -#include "hash.h" - -static void hna_local_purge(struct work_struct *work); -static void _hna_global_del_orig(struct bat_priv *bat_priv, - struct hna_global_entry *hna_global_entry, - char *message); - -static void hna_local_start_timer(struct bat_priv *bat_priv) -{ - INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge); - queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ); -} - -int hna_local_init(struct bat_priv *bat_priv) -{ - if (bat_priv->hna_local_hash) - return 1; - - bat_priv->hna_local_hash = hash_new(128, compare_orig, choose_orig); - - if (!bat_priv->hna_local_hash) - return 0; - - atomic_set(&bat_priv->hna_local_changed, 0); - hna_local_start_timer(bat_priv); - - return 1; -} - -void hna_local_add(struct net_device *soft_iface, uint8_t *addr) -{ - struct bat_priv *bat_priv = netdev_priv(soft_iface); - struct hna_local_entry *hna_local_entry; - struct hna_global_entry *hna_global_entry; - struct hashtable_t *swaphash; - unsigned long flags; - int required_bytes; - - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); - hna_local_entry = - ((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash, - addr)); - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); - - if (hna_local_entry) { - hna_local_entry->last_seen = jiffies; - return; - } - - /* only announce as many hosts as possible in the batman-packet and - space in batman_packet->num_hna That also should give a limit to - MAC-flooding. */ - required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN; - required_bytes += BAT_PACKET_LEN; - - if ((required_bytes > ETH_DATA_LEN) || - (atomic_read(&bat_priv->aggregation_enabled) && - required_bytes > MAX_AGGREGATION_BYTES) || - (bat_priv->num_local_hna + 1 > 255)) { - bat_dbg(DBG_ROUTES, bat_priv, - "Can't add new local hna entry (%pM): " - "number of local hna entries exceeds packet size\n", - addr); - return; - } - - bat_dbg(DBG_ROUTES, bat_priv, - "Creating new local hna entry: %pM\n", addr); - - hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); - if (!hna_local_entry) - return; - - memcpy(hna_local_entry->addr, addr, ETH_ALEN); - hna_local_entry->last_seen = jiffies; - - /* the batman interface mac address should never be purged */ - if (compare_orig(addr, soft_iface->dev_addr)) - hna_local_entry->never_purge = 1; - else - hna_local_entry->never_purge = 0; - - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); - - hash_add(bat_priv->hna_local_hash, hna_local_entry); - bat_priv->num_local_hna++; - atomic_set(&bat_priv->hna_local_changed, 1); - - if (bat_priv->hna_local_hash->elements * 4 > - bat_priv->hna_local_hash->size) { - swaphash = hash_resize(bat_priv->hna_local_hash, - bat_priv->hna_local_hash->size * 2); - - if (!swaphash) - pr_err("Couldn't resize local hna hash table\n"); - else - bat_priv->hna_local_hash = swaphash; - } - - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); - - /* remove address from global hash if present */ - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); - - hna_global_entry = ((struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, addr)); - - if (hna_global_entry) - _hna_global_del_orig(bat_priv, hna_global_entry, - "local hna received"); - - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); -} - -int hna_local_fill_buffer(struct bat_priv *bat_priv, - unsigned char *buff, int buff_len) -{ - struct hna_local_entry *hna_local_entry; - HASHIT(hashit); - int i = 0; - unsigned long flags; - - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); - - while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { - - if (buff_len < (i + 1) * ETH_ALEN) - break; - - hna_local_entry = hashit.bucket->data; - memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN); - - i++; - } - - /* if we did not get all new local hnas see you next time ;-) */ - if (i == bat_priv->num_local_hna) - atomic_set(&bat_priv->hna_local_changed, 0); - - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); - return i; -} - -int hna_local_seq_print_text(struct seq_file *seq, void *offset) -{ - struct net_device *net_dev = (struct net_device *)seq->private; - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct hna_local_entry *hna_local_entry; - HASHIT(hashit); - HASHIT(hashit_count); - unsigned long flags; - size_t buf_size, pos; - char *buff; - - if (!bat_priv->primary_if) { - return seq_printf(seq, "BATMAN mesh %s disabled - " - "please specify interfaces to enable it\n", - net_dev->name); - } - - seq_printf(seq, "Locally retrieved addresses (from %s) " - "announced via HNA:\n", - net_dev->name); - - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); - - buf_size = 1; - /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */ - while (hash_iterate(bat_priv->hna_local_hash, &hashit_count)) - buf_size += 21; - - buff = kmalloc(buf_size, GFP_ATOMIC); - if (!buff) { - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); - return -ENOMEM; - } - buff[0] = '\0'; - pos = 0; - - while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { - hna_local_entry = hashit.bucket->data; - - pos += snprintf(buff + pos, 22, " * %pM\n", - hna_local_entry->addr); - } - - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); - - seq_printf(seq, "%s", buff); - kfree(buff); - return 0; -} - -static void _hna_local_del(void *data, void *arg) -{ - struct bat_priv *bat_priv = (struct bat_priv *)arg; - - kfree(data); - bat_priv->num_local_hna--; - atomic_set(&bat_priv->hna_local_changed, 1); -} - -static void hna_local_del(struct bat_priv *bat_priv, - struct hna_local_entry *hna_local_entry, - char *message) -{ - bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n", - hna_local_entry->addr, message); - - hash_remove(bat_priv->hna_local_hash, hna_local_entry->addr); - _hna_local_del(hna_local_entry, bat_priv); -} - -void hna_local_remove(struct bat_priv *bat_priv, - uint8_t *addr, char *message) -{ - struct hna_local_entry *hna_local_entry; - unsigned long flags; - - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); - - hna_local_entry = (struct hna_local_entry *) - hash_find(bat_priv->hna_local_hash, addr); - if (hna_local_entry) - hna_local_del(bat_priv, hna_local_entry, message); - - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); -} - -static void hna_local_purge(struct work_struct *work) -{ - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); - struct bat_priv *bat_priv = - container_of(delayed_work, struct bat_priv, hna_work); - struct hna_local_entry *hna_local_entry; - HASHIT(hashit); - unsigned long flags; - unsigned long timeout; - - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); - - while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { - hna_local_entry = hashit.bucket->data; - - timeout = hna_local_entry->last_seen + LOCAL_HNA_TIMEOUT * HZ; - - if ((!hna_local_entry->never_purge) && - time_after(jiffies, timeout)) - hna_local_del(bat_priv, hna_local_entry, - "address timed out"); - } - - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); - hna_local_start_timer(bat_priv); -} - -void hna_local_free(struct bat_priv *bat_priv) -{ - if (!bat_priv->hna_local_hash) - return; - - cancel_delayed_work_sync(&bat_priv->hna_work); - hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv); - bat_priv->hna_local_hash = NULL; -} - -int hna_global_init(struct bat_priv *bat_priv) -{ - if (bat_priv->hna_global_hash) - return 1; - - bat_priv->hna_global_hash = hash_new(128, compare_orig, choose_orig); - - if (!bat_priv->hna_global_hash) - return 0; - - return 1; -} - -void hna_global_add_orig(struct bat_priv *bat_priv, - struct orig_node *orig_node, - unsigned char *hna_buff, int hna_buff_len) -{ - struct hna_global_entry *hna_global_entry; - struct hna_local_entry *hna_local_entry; - struct hashtable_t *swaphash; - int hna_buff_count = 0; - unsigned long flags; - unsigned char *hna_ptr; - - while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); - - hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); - hna_global_entry = (struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, hna_ptr); - - if (!hna_global_entry) { - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, - flags); - - hna_global_entry = - kmalloc(sizeof(struct hna_global_entry), - GFP_ATOMIC); - - if (!hna_global_entry) - break; - - memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); - - bat_dbg(DBG_ROUTES, bat_priv, - "Creating new global hna entry: " - "%pM (via %pM)\n", - hna_global_entry->addr, orig_node->orig); - - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); - hash_add(bat_priv->hna_global_hash, hna_global_entry); - - } - - hna_global_entry->orig_node = orig_node; - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); - - /* remove address from local hash if present */ - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); - - hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); - hna_local_entry = (struct hna_local_entry *) - hash_find(bat_priv->hna_local_hash, hna_ptr); - - if (hna_local_entry) - hna_local_del(bat_priv, hna_local_entry, - "global hna received"); - - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); - - hna_buff_count++; - } - - /* initialize, and overwrite if malloc succeeds */ - orig_node->hna_buff = NULL; - orig_node->hna_buff_len = 0; - - if (hna_buff_len > 0) { - orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC); - if (orig_node->hna_buff) { - memcpy(orig_node->hna_buff, hna_buff, hna_buff_len); - orig_node->hna_buff_len = hna_buff_len; - } - } - - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); - - if (bat_priv->hna_global_hash->elements * 4 > - bat_priv->hna_global_hash->size) { - swaphash = hash_resize(bat_priv->hna_global_hash, - bat_priv->hna_global_hash->size * 2); - - if (!swaphash) - pr_err("Couldn't resize global hna hash table\n"); - else - bat_priv->hna_global_hash = swaphash; - } - - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); -} - -int hna_global_seq_print_text(struct seq_file *seq, void *offset) -{ - struct net_device *net_dev = (struct net_device *)seq->private; - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct hna_global_entry *hna_global_entry; - HASHIT(hashit); - HASHIT(hashit_count); - unsigned long flags; - size_t buf_size, pos; - char *buff; - - if (!bat_priv->primary_if) { - return seq_printf(seq, "BATMAN mesh %s disabled - " - "please specify interfaces to enable it\n", - net_dev->name); - } - - seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", - net_dev->name); - - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); - - buf_size = 1; - /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/ - while (hash_iterate(bat_priv->hna_global_hash, &hashit_count)) - buf_size += 43; - - buff = kmalloc(buf_size, GFP_ATOMIC); - if (!buff) { - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); - return -ENOMEM; - } - buff[0] = '\0'; - pos = 0; - - while (hash_iterate(bat_priv->hna_global_hash, &hashit)) { - hna_global_entry = hashit.bucket->data; - - pos += snprintf(buff + pos, 44, - " * %pM via %pM\n", hna_global_entry->addr, - hna_global_entry->orig_node->orig); - } - - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); - - seq_printf(seq, "%s", buff); - kfree(buff); - return 0; -} - -static void _hna_global_del_orig(struct bat_priv *bat_priv, - struct hna_global_entry *hna_global_entry, - char *message) -{ - bat_dbg(DBG_ROUTES, bat_priv, - "Deleting global hna entry %pM (via %pM): %s\n", - hna_global_entry->addr, hna_global_entry->orig_node->orig, - message); - - hash_remove(bat_priv->hna_global_hash, hna_global_entry->addr); - kfree(hna_global_entry); -} - -void hna_global_del_orig(struct bat_priv *bat_priv, - struct orig_node *orig_node, char *message) -{ - struct hna_global_entry *hna_global_entry; - int hna_buff_count = 0; - unsigned long flags; - unsigned char *hna_ptr; - - if (orig_node->hna_buff_len == 0) - return; - - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); - - while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) { - hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); - hna_global_entry = (struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, hna_ptr); - - if ((hna_global_entry) && - (hna_global_entry->orig_node == orig_node)) - _hna_global_del_orig(bat_priv, hna_global_entry, - message); - - hna_buff_count++; - } - - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); - - orig_node->hna_buff_len = 0; - kfree(orig_node->hna_buff); - orig_node->hna_buff = NULL; -} - -static void hna_global_del(void *data, void *arg) -{ - kfree(data); -} - -void hna_global_free(struct bat_priv *bat_priv) -{ - if (!bat_priv->hna_global_hash) - return; - - hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL); - bat_priv->hna_global_hash = NULL; -} - -struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr) -{ - struct hna_global_entry *hna_global_entry; - unsigned long flags; - - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); - hna_global_entry = (struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, addr); - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); - - if (!hna_global_entry) - return NULL; - - return hna_global_entry->orig_node; -} |