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_remove(uint8_t *addr, char *message) { struct hna_local_entry *hna_local_entry; unsigned long flags; spin_lock_irqsave(&hna_local_hash_lock, flags); hna_local_entry = (struct hna_local_entry *) hash_find(hna_local_hash, addr); if (hna_local_entry) hna_local_del(hna_local_entry, message); spin_unlock_irqrestore(&hna_local_hash_lock, flags); }
void hna_local_purge(struct work_struct *work) { struct hna_local_entry *hna_local_entry; struct hash_it_t *hashit = NULL; unsigned long flags; unsigned long timeout; spin_lock_irqsave(&hna_local_hash_lock, flags); while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) { hna_local_entry = hashit->bucket->data; timeout = hna_local_entry->last_seen + ((LOCAL_HNA_TIMEOUT / 1000) * HZ); if ((!hna_local_entry->never_purge) && time_after(jiffies, timeout)) hna_local_del(hna_local_entry, "address timed out"); } spin_unlock_irqrestore(&hna_local_hash_lock, flags); hna_local_start_timer(); }
void hna_global_add_orig(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; char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN]; int hna_buff_count = 0; unsigned long flags; unsigned char *hna_ptr; addr_to_string(orig_str, orig_node->orig); while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { spin_lock_irqsave(&hna_global_hash_lock, flags); hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); hna_global_entry = (struct hna_global_entry *) hash_find(hna_global_hash, hna_ptr); if (hna_global_entry == NULL) { spin_unlock_irqrestore(&hna_global_hash_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); addr_to_string(hna_str, hna_global_entry->addr); debug_log(LOG_TYPE_ROUTES, "Creating new global hna entry: %s (via %s)\n", hna_str, orig_str); spin_lock_irqsave(&hna_global_hash_lock, flags); hash_add(hna_global_hash, hna_global_entry); } hna_global_entry->orig_node = orig_node; spin_unlock_irqrestore(&hna_global_hash_lock, flags); /* remove address from local hash if present */ spin_lock_irqsave(&hna_local_hash_lock, flags); hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); hna_local_entry = (struct hna_local_entry *) hash_find(hna_local_hash, hna_ptr); if (hna_local_entry != NULL) hna_local_del(hna_local_entry, "global hna received"); spin_unlock_irqrestore(&hna_local_hash_lock, flags); hna_buff_count++; } orig_node->hna_buff_len = hna_buff_len; if (orig_node->hna_buff_len > 0) { orig_node->hna_buff = kmalloc(orig_node->hna_buff_len, GFP_ATOMIC); memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len); } else { orig_node->hna_buff = NULL; } spin_lock_irqsave(&hna_global_hash_lock, flags); if (hna_global_hash->elements * 4 > hna_global_hash->size) { swaphash = hash_resize(hna_global_hash, hna_global_hash->size * 2); if (swaphash == NULL) debug_log(LOG_TYPE_CRIT, "Couldn't resize global hna hash table \n"); else hna_global_hash = swaphash; } spin_unlock_irqrestore(&hna_global_hash_lock, flags); }
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); }