diff options
Diffstat (limited to 'net/batman-adv/translation-table.c')
-rw-r--r-- | net/batman-adv/translation-table.c | 371 |
1 files changed, 233 insertions, 138 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index baae71585804..582f13405df9 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -238,92 +238,134 @@ static int batadv_tt_local_init(struct batadv_priv *bat_priv) return 0; } +static void batadv_tt_global_free(struct batadv_priv *bat_priv, + struct batadv_tt_global_entry *tt_global, + const char *message) +{ + batadv_dbg(BATADV_DBG_TT, bat_priv, + "Deleting global tt entry %pM: %s\n", + tt_global->common.addr, message); + + batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt, + batadv_choose_orig, tt_global->common.addr); + batadv_tt_global_entry_free_ref(tt_global); + +} + void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, int ifindex) { struct batadv_priv *bat_priv = netdev_priv(soft_iface); - struct batadv_tt_local_entry *tt_local_entry = NULL; - struct batadv_tt_global_entry *tt_global_entry = NULL; + struct batadv_tt_local_entry *tt_local; + struct batadv_tt_global_entry *tt_global; struct hlist_head *head; struct hlist_node *node; struct batadv_tt_orig_list_entry *orig_entry; int hash_added; + bool roamed_back = false; - tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); + tt_local = batadv_tt_local_hash_find(bat_priv, addr); + tt_global = batadv_tt_global_hash_find(bat_priv, addr); - if (tt_local_entry) { - tt_local_entry->last_seen = jiffies; - /* possibly unset the BATADV_TT_CLIENT_PENDING flag */ - tt_local_entry->common.flags &= ~BATADV_TT_CLIENT_PENDING; - goto out; + if (tt_local) { + tt_local->last_seen = jiffies; + if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) { + batadv_dbg(BATADV_DBG_TT, bat_priv, + "Re-adding pending client %pM\n", addr); + /* whatever the reason why the PENDING flag was set, + * this is a client which was enqueued to be removed in + * this orig_interval. Since it popped up again, the + * flag can be reset like it was never enqueued + */ + tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING; + goto add_event; + } + + if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) { + batadv_dbg(BATADV_DBG_TT, bat_priv, + "Roaming client %pM came back to its original location\n", + addr); + /* the ROAM flag is set because this client roamed away + * and the node got a roaming_advertisement message. Now + * that the client popped up again at its original + * location such flag can be unset + */ + tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM; + roamed_back = true; + } + goto check_roaming; } - tt_local_entry = kmalloc(sizeof(*tt_local_entry), GFP_ATOMIC); - if (!tt_local_entry) + tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC); + if (!tt_local) goto out; batadv_dbg(BATADV_DBG_TT, bat_priv, "Creating new local tt entry: %pM (ttvn: %d)\n", addr, (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; + memcpy(tt_local->common.addr, addr, ETH_ALEN); + tt_local->common.flags = BATADV_NO_FLAGS; if (batadv_is_wifi_iface(ifindex)) - 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; + tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; + atomic_set(&tt_local->common.refcount, 2); + tt_local->last_seen = jiffies; + tt_local->common.added_at = tt_local->last_seen; /* the batman interface mac address should never be purged */ if (batadv_compare_eth(addr, soft_iface->dev_addr)) - tt_local_entry->common.flags |= BATADV_TT_CLIENT_NOPURGE; + tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE; /* The local entry has to be marked as NEW to avoid to send it in * a full table response going out before the next ttvn increment * (consistency check) */ - tt_local_entry->common.flags |= BATADV_TT_CLIENT_NEW; + tt_local->common.flags |= BATADV_TT_CLIENT_NEW; 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); + batadv_choose_orig, &tt_local->common, + &tt_local->common.hash_entry); if (unlikely(hash_added != 0)) { /* remove the reference for the hash */ - batadv_tt_local_entry_free_ref(tt_local_entry); + batadv_tt_local_entry_free_ref(tt_local); goto out; } - batadv_tt_local_event(bat_priv, addr, tt_local_entry->common.flags); +add_event: + batadv_tt_local_event(bat_priv, addr, tt_local->common.flags); - /* remove address from global hash if present */ - tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); - - /* Check whether it is a roaming! */ - if (tt_global_entry) { +check_roaming: + /* Check whether it is a roaming, but don't do anything if the roaming + * process has already been handled + */ + if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) { /* These node are probably going to update their tt table */ - head = &tt_global_entry->orig_list; + head = &tt_global->orig_list; rcu_read_lock(); hlist_for_each_entry_rcu(orig_entry, node, head, list) { - orig_entry->orig_node->tt_poss_change = true; - - batadv_send_roam_adv(bat_priv, - tt_global_entry->common.addr, + batadv_send_roam_adv(bat_priv, tt_global->common.addr, orig_entry->orig_node); } rcu_read_unlock(); - /* The global entry has to be marked as ROAMING and - * has to be kept for consistency purpose - */ - tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM; - tt_global_entry->roam_at = jiffies; + if (roamed_back) { + batadv_tt_global_free(bat_priv, tt_global, + "Roaming canceled"); + tt_global = NULL; + } else { + /* The global entry has to be marked as ROAMING and + * has to be kept for consistency purpose + */ + tt_global->common.flags |= BATADV_TT_CLIENT_ROAM; + tt_global->roam_at = jiffies; + } } + out: - if (tt_local_entry) - batadv_tt_local_entry_free_ref(tt_local_entry); - if (tt_global_entry) - batadv_tt_global_entry_free_ref(tt_global_entry); + if (tt_local) + batadv_tt_local_entry_free_ref(tt_local); + if (tt_global) + batadv_tt_global_entry_free_ref(tt_global); } static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff, @@ -434,22 +476,10 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) struct hlist_node *node; struct hlist_head *head; uint32_t i; - int ret = 0; - 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); + primary_if = batadv_seq_print_text_primary_if_get(seq); + if (!primary_if) goto out; - } seq_printf(seq, "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", @@ -479,7 +509,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) out: if (primary_if) batadv_hardif_free_ref(primary_if); - return ret; + return 0; } static void @@ -501,24 +531,57 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv, tt_local_entry->common.addr, message); } -void batadv_tt_local_remove(struct batadv_priv *bat_priv, const uint8_t *addr, - const char *message, bool roaming) +/** + * batadv_tt_local_remove - logically remove an entry from the local table + * @bat_priv: the bat priv with all the soft interface information + * @addr: the MAC address of the client to remove + * @message: message to append to the log on deletion + * @roaming: true if the deletion is due to a roaming event + * + * Returns the flags assigned to the local entry before being deleted + */ +uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, + const uint8_t *addr, const char *message, + bool roaming) { - struct batadv_tt_local_entry *tt_local_entry = NULL; - uint16_t flags; + struct batadv_tt_local_entry *tt_local_entry; + uint16_t flags, curr_flags = BATADV_NO_FLAGS; tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); if (!tt_local_entry) goto out; + curr_flags = tt_local_entry->common.flags; + flags = BATADV_TT_CLIENT_DEL; - if (roaming) + /* if this global entry addition is due to a roaming, the node has to + * mark the local entry as "roamed" in order to correctly reroute + * packets later + */ + if (roaming) { flags |= BATADV_TT_CLIENT_ROAM; + /* mark the local client as ROAMed */ + tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM; + } + + if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) { + batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, + message); + goto out; + } + /* if this client has been added right now, it is possible to + * immediately purge it + */ + batadv_tt_local_event(bat_priv, tt_local_entry->common.addr, + curr_flags | BATADV_TT_CLIENT_DEL); + hlist_del_rcu(&tt_local_entry->common.hash_entry); + batadv_tt_local_entry_free_ref(tt_local_entry); - batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message); out: if (tt_local_entry) batadv_tt_local_entry_free_ref(tt_local_entry); + + return curr_flags; } static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, @@ -721,12 +784,23 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, const unsigned char *tt_addr, uint8_t flags, uint8_t ttvn) { - struct batadv_tt_global_entry *tt_global_entry = NULL; + struct batadv_tt_global_entry *tt_global_entry; + struct batadv_tt_local_entry *tt_local_entry; int ret = 0; int hash_added; struct batadv_tt_common_entry *common; + uint16_t local_flags; tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); + tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr); + + /* if the node already has a local client for this entry, it has to wait + * for a roaming advertisement instead of manually messing up the global + * table + */ + if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry && + !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) + goto out; if (!tt_global_entry) { tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC); @@ -738,6 +812,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, common->flags = flags; tt_global_entry->roam_at = 0; + /* node must store current time in case of roaming. This is + * needed to purge this entry out on timeout (if nobody claims + * it) + */ + if (flags & BATADV_TT_CLIENT_ROAM) + tt_global_entry->roam_at = jiffies; atomic_set(&common->refcount, 2); common->added_at = jiffies; @@ -755,19 +835,31 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, goto out_remove; } } else { + common = &tt_global_entry->common; /* 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) + * But if we are trying to add a temporary client then here are + * two options at this point: + * 1) the global client is not a temporary client: the global + * client has to be left as it is, temporary information + * should never override any already known client state + * 2) the global client is a temporary client: purge the + * originator list and add the new one orig_entry */ - if (flags & BATADV_TT_CLIENT_TEMP) - goto out; + if (flags & BATADV_TT_CLIENT_TEMP) { + if (!(common->flags & BATADV_TT_CLIENT_TEMP)) + goto out; + if (batadv_tt_global_entry_has_orig(tt_global_entry, + orig_node)) + goto out_remove; + batadv_tt_global_del_orig_list(tt_global_entry); + goto add_orig_entry; + } /* 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; + common->flags &= ~BATADV_TT_CLIENT_TEMP; /* the change can carry possible "attribute" flags like the * TT_CLIENT_WIFI, therefore they have to be copied in the @@ -782,28 +874,40 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, * We should first delete the old originator before adding the * new one. */ - if (tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM) { + if (common->flags & BATADV_TT_CLIENT_ROAM) { batadv_tt_global_del_orig_list(tt_global_entry); - tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; + common->flags &= ~BATADV_TT_CLIENT_ROAM; tt_global_entry->roam_at = 0; } } +add_orig_entry: /* 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, "Creating new global tt entry: %pM (via %pM)\n", - tt_global_entry->common.addr, orig_node->orig); + common->addr, orig_node->orig); + ret = 1; out_remove: + /* remove address from local hash if present */ - batadv_tt_local_remove(bat_priv, tt_global_entry->common.addr, - "global tt received", - flags & BATADV_TT_CLIENT_ROAM); - ret = 1; + local_flags = batadv_tt_local_remove(bat_priv, tt_addr, + "global tt received", + !!(flags & BATADV_TT_CLIENT_ROAM)); + tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; + + if (!(flags & BATADV_TT_CLIENT_ROAM)) + /* this is a normal global add. Therefore the client is not in a + * roaming state anymore. + */ + tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; + out: if (tt_global_entry) batadv_tt_global_entry_free_ref(tt_global_entry); + if (tt_local_entry) + batadv_tt_local_entry_free_ref(tt_local_entry); return ret; } @@ -848,22 +952,10 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) struct hlist_node *node; struct hlist_head *head; uint32_t i; - int ret = 0; - 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); + primary_if = batadv_seq_print_text_primary_if_get(seq); + if (!primary_if) 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; - } seq_printf(seq, "Globally announced TT entries received via the mesh %s\n", @@ -887,7 +979,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) out: if (primary_if) batadv_hardif_free_ref(primary_if); - return ret; + return 0; } /* deletes the orig list of a tt_global_entry */ @@ -933,21 +1025,6 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv, spin_unlock_bh(&tt_global_entry->list_lock); } -static void -batadv_tt_global_del_struct(struct batadv_priv *bat_priv, - struct batadv_tt_global_entry *tt_global_entry, - const char *message) -{ - batadv_dbg(BATADV_DBG_TT, 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_choose_orig, tt_global_entry->common.addr); - batadv_tt_global_entry_free_ref(tt_global_entry); - -} - /* If the client is to be deleted, we check if it is the last origantor entry * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the * timer, otherwise we simply remove the originator scheduled for deletion. @@ -996,7 +1073,7 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv, const unsigned char *addr, const char *message, bool roaming) { - struct batadv_tt_global_entry *tt_global_entry = NULL; + struct batadv_tt_global_entry *tt_global_entry; struct batadv_tt_local_entry *local_entry = NULL; tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); @@ -1008,8 +1085,8 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv, orig_node, message); if (hlist_empty(&tt_global_entry->orig_list)) - batadv_tt_global_del_struct(bat_priv, tt_global_entry, - message); + batadv_tt_global_free(bat_priv, tt_global_entry, + message); goto out; } @@ -1032,7 +1109,7 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv, if (local_entry) { /* local entry exists, case 2: client roamed to us. */ batadv_tt_global_del_orig_list(tt_global_entry); - batadv_tt_global_del_struct(bat_priv, tt_global_entry, message); + batadv_tt_global_free(bat_priv, tt_global_entry, message); } else /* no local entry exists, case 1: check for roaming */ batadv_tt_global_del_roaming(bat_priv, tt_global_entry, @@ -1211,7 +1288,8 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, if (src && atomic_read(&bat_priv->ap_isolation)) { tt_local_entry = batadv_tt_local_hash_find(bat_priv, src); - if (!tt_local_entry) + if (!tt_local_entry || + (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)) goto out; } @@ -1477,11 +1555,11 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, tt_tot = tt_len / sizeof(struct batadv_tt_change); len = tt_query_size + tt_len; - skb = dev_alloc_skb(len + ETH_HLEN); + skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN); if (!skb) goto out; - skb_reserve(skb, ETH_HLEN); + skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len); tt_response->ttvn = ttvn; @@ -1543,11 +1621,11 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv, if (!tt_req_node) goto out; - skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN); + skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN + NET_IP_ALIGN); if (!skb) goto out; - skb_reserve(skb, ETH_HLEN); + skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); tt_req_len = sizeof(*tt_request); tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len); @@ -1598,7 +1676,7 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv, struct batadv_tt_query_packet *tt_request) { - struct batadv_orig_node *req_dst_orig_node = NULL; + struct batadv_orig_node *req_dst_orig_node; struct batadv_orig_node *res_dst_orig_node = NULL; struct batadv_neigh_node *neigh_node = NULL; struct batadv_hard_iface *primary_if = NULL; @@ -1658,11 +1736,11 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, tt_tot = tt_len / sizeof(struct batadv_tt_change); len = sizeof(*tt_response) + tt_len; - skb = dev_alloc_skb(len + ETH_HLEN); + skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN); if (!skb) goto unlock; - skb_reserve(skb, ETH_HLEN); + skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); packet_pos = skb_put(skb, len); tt_response = (struct batadv_tt_query_packet *)packet_pos; tt_response->ttvn = req_ttvn; @@ -1733,7 +1811,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv, struct batadv_tt_query_packet *tt_request) { - struct batadv_orig_node *orig_node = NULL; + struct batadv_orig_node *orig_node; struct batadv_neigh_node *neigh_node = NULL; struct batadv_hard_iface *primary_if = NULL; uint8_t my_ttvn, req_ttvn, ttvn; @@ -1785,11 +1863,11 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, tt_tot = tt_len / sizeof(struct batadv_tt_change); len = sizeof(*tt_response) + tt_len; - skb = dev_alloc_skb(len + ETH_HLEN); + skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN); if (!skb) goto unlock; - skb_reserve(skb, ETH_HLEN); + skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); packet_pos = skb_put(skb, len); tt_response = (struct batadv_tt_query_packet *)packet_pos; tt_response->ttvn = req_ttvn; @@ -1899,7 +1977,7 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv, static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv, struct batadv_tt_query_packet *tt_response) { - struct batadv_orig_node *orig_node = NULL; + struct batadv_orig_node *orig_node; orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); if (!orig_node) @@ -1941,7 +2019,7 @@ static void batadv_tt_update_changes(struct batadv_priv *bat_priv, bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr) { - struct batadv_tt_local_entry *tt_local_entry = NULL; + struct batadv_tt_local_entry *tt_local_entry; bool ret = false; tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); @@ -1950,7 +2028,8 @@ bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr) /* Check if the client has been logically deleted (but is kept for * consistency purpose) */ - if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) + if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) || + (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM)) goto out; ret = true; out: @@ -2001,10 +2080,6 @@ void batadv_handle_tt_response(struct batadv_priv *bat_priv, /* Recalculate the CRC for this orig_node and store it */ orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); - /* Roaming phase is over: tables are in sync again. I can - * unset the flag - */ - orig_node->tt_poss_change = false; out: if (orig_node) batadv_orig_node_free_ref(orig_node); @@ -2123,11 +2198,11 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, if (!batadv_tt_check_roam_count(bat_priv, client)) goto out; - skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN); + skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN + NET_IP_ALIGN); if (!skb) goto out; - skb_reserve(skb, ETH_HLEN); + skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len); @@ -2295,7 +2370,6 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv, batadv_dbg(BATADV_DBG_TT, bat_priv, "Local changes committed, updating to ttvn %u\n", (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); @@ -2407,11 +2481,6 @@ void batadv_tt_update_orig(struct batadv_priv *bat_priv, */ if (orig_node->tt_crc != tt_crc) goto request_table; - - /* Roaming phase is over: tables are in sync again. I can - * unset the flag - */ - orig_node->tt_poss_change = false; } else { /* if we missed more than one change or our tables are not * in sync anymore -> request fresh tt data @@ -2444,12 +2513,38 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, if (!tt_global_entry) goto out; - ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; + ret = !!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM); batadv_tt_global_entry_free_ref(tt_global_entry); out: return ret; } +/** + * batadv_tt_local_client_is_roaming - tells whether the client is roaming + * @bat_priv: the bat priv with all the soft interface information + * @addr: the MAC address of the local client to query + * + * Returns true if the local client is known to be roaming (it is not served by + * this node anymore) or not. If yes, the client is still present in the table + * to keep the latter consistent with the node TTVN + */ +bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, + uint8_t *addr) +{ + struct batadv_tt_local_entry *tt_local_entry; + bool ret = false; + + tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); + if (!tt_local_entry) + goto out; + + ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM; + batadv_tt_local_entry_free_ref(tt_local_entry); +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) |