diff options
Diffstat (limited to 'net/batman-adv/translation-table.c')
-rw-r--r-- | net/batman-adv/translation-table.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index cc87acf02431..46a2b3791d9c 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -242,9 +242,10 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, | |||
242 | if (tt_global_entry) { | 242 | if (tt_global_entry) { |
243 | /* This node is probably going to update its tt table */ | 243 | /* This node is probably going to update its tt table */ |
244 | tt_global_entry->orig_node->tt_poss_change = true; | 244 | tt_global_entry->orig_node->tt_poss_change = true; |
245 | /* The global entry has to be marked as PENDING and has to be | 245 | /* The global entry has to be marked as ROAMING and has to be |
246 | * kept for consistency purpose */ | 246 | * kept for consistency purpose */ |
247 | tt_global_entry->common.flags |= TT_CLIENT_PENDING; | 247 | tt_global_entry->common.flags |= TT_CLIENT_PENDING; |
248 | tt_global_entry->roam_at = jiffies; | ||
248 | send_roam_adv(bat_priv, tt_global_entry->common.addr, | 249 | send_roam_adv(bat_priv, tt_global_entry->common.addr, |
249 | tt_global_entry->orig_node); | 250 | tt_global_entry->orig_node); |
250 | } | 251 | } |
@@ -661,6 +662,7 @@ void tt_global_del(struct bat_priv *bat_priv, | |||
661 | const char *message, bool roaming) | 662 | const char *message, bool roaming) |
662 | { | 663 | { |
663 | struct tt_global_entry *tt_global_entry = NULL; | 664 | struct tt_global_entry *tt_global_entry = NULL; |
665 | struct tt_local_entry *tt_local_entry = NULL; | ||
664 | 666 | ||
665 | tt_global_entry = tt_global_hash_find(bat_priv, addr); | 667 | tt_global_entry = tt_global_hash_find(bat_priv, addr); |
666 | if (!tt_global_entry) | 668 | if (!tt_global_entry) |
@@ -668,15 +670,29 @@ void tt_global_del(struct bat_priv *bat_priv, | |||
668 | 670 | ||
669 | if (tt_global_entry->orig_node == orig_node) { | 671 | if (tt_global_entry->orig_node == orig_node) { |
670 | if (roaming) { | 672 | if (roaming) { |
671 | tt_global_entry->common.flags |= TT_CLIENT_ROAM; | 673 | /* if we are deleting a global entry due to a roam |
672 | tt_global_entry->roam_at = jiffies; | 674 | * event, there are two possibilities: |
673 | goto out; | 675 | * 1) the client roamed from node A to node B => we mark |
676 | * it with TT_CLIENT_ROAM, we start a timer and we | ||
677 | * wait for node B to claim it. In case of timeout | ||
678 | * the entry is purged. | ||
679 | * 2) the client roamed to us => we can directly delete | ||
680 | * the global entry, since it is useless now. */ | ||
681 | tt_local_entry = tt_local_hash_find(bat_priv, | ||
682 | tt_global_entry->common.addr); | ||
683 | if (!tt_local_entry) { | ||
684 | tt_global_entry->common.flags |= TT_CLIENT_ROAM; | ||
685 | tt_global_entry->roam_at = jiffies; | ||
686 | goto out; | ||
687 | } | ||
674 | } | 688 | } |
675 | _tt_global_del(bat_priv, tt_global_entry, message); | 689 | _tt_global_del(bat_priv, tt_global_entry, message); |
676 | } | 690 | } |
677 | out: | 691 | out: |
678 | if (tt_global_entry) | 692 | if (tt_global_entry) |
679 | tt_global_entry_free_ref(tt_global_entry); | 693 | tt_global_entry_free_ref(tt_global_entry); |
694 | if (tt_local_entry) | ||
695 | tt_local_entry_free_ref(tt_local_entry); | ||
680 | } | 696 | } |
681 | 697 | ||
682 | void tt_global_del_orig(struct bat_priv *bat_priv, | 698 | void tt_global_del_orig(struct bat_priv *bat_priv, |