void hna_local_add(uint8_t *addr) { struct hna_local_entry *hna_local_entry; struct hna_global_entry *hna_global_entry; struct hashtable_t *swaphash; char hna_str[ETH_STR_LEN]; unsigned long flags; spin_lock_irqsave(&hna_local_hash_lock, flags); hna_local_entry = ((struct hna_local_entry *)hash_find(hna_local_hash, addr)); spin_unlock_irqrestore(&hna_local_hash_lock, flags); if (hna_local_entry != NULL) { hna_local_entry->last_seen = jiffies; return; } addr_to_string(hna_str, addr); /* 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. */ if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) || (num_hna + 1 > 255)) { debug_log(LOG_TYPE_ROUTES, "Can't add new local hna entry (%s): number of local hna entries exceeds packet size \n", hna_str); return; } debug_log(LOG_TYPE_ROUTES, "Creating new local hna entry: %s \n", hna_str); 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_device->dev_addr)) hna_local_entry->never_purge = 1; else hna_local_entry->never_purge = 0; spin_lock_irqsave(&hna_local_hash_lock, flags); hash_add(hna_local_hash, hna_local_entry); num_hna++; atomic_set(&hna_local_changed, 1); if (hna_local_hash->elements * 4 > hna_local_hash->size) { swaphash = hash_resize(hna_local_hash, hna_local_hash->size * 2); if (swaphash == NULL) debug_log(LOG_TYPE_CRIT, "Couldn't resize local hna hash table \n"); else hna_local_hash = swaphash; } spin_unlock_irqrestore(&hna_local_hash_lock, flags); /* remove address from global hash if present */ spin_lock_irqsave(&hna_global_hash_lock, flags); hna_global_entry = ((struct hna_global_entry *)hash_find(hna_global_hash, addr)); if (hna_global_entry != NULL) _hna_global_del_orig(hna_global_entry, "local hna received"); spin_unlock_irqrestore(&hna_global_hash_lock, flags); }
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); }