diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index d475f8efd44d..67e4ade5ae99 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1832,6 +1832,57 @@ out: spin_unlock_bh(&tt_global->list_lock); } +/** + * batadv_tt_global_merge_flags() - merge announced flags into a global TT entry + * @tt_global_entry: the global TT entry to update + * @flags: TT flags announced for this non-mesh client + * + * Return: true if the originator list of @tt_global_entry has to be purged + * before the announced originator is added, false otherwise. + */ +static bool +batadv_tt_global_merge_flags(struct batadv_tt_global_entry *tt_global_entry, + u16 flags) +{ + struct batadv_tt_common_entry *common = &tt_global_entry->common; + bool delete = false; + + scoped_guard(spinlock_bh, &common->flags_lock) { + /* if the client was temporary added before receiving the first + * OGM announcing it, we have to clear the TEMP flag. Also, + * remove the previous temporary orig node and re-add it + * if required. If the orig entry changed, the new one which + * is a non-temporary entry is preferred. + */ + if (common->flags & BATADV_TT_CLIENT_TEMP) { + delete = true; + common->flags &= ~BATADV_TT_CLIENT_TEMP; + } + + /* the change can carry possible "attribute" flags like the + * TT_CLIENT_TEMP, therefore they have to be copied in the + * client entry + */ + if (!is_multicast_ether_addr(common->addr)) + common->flags |= flags & (~BATADV_TT_SYNC_MASK); + + /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only + * one originator left in the list and we previously received a + * delete + roaming change for this originator. + * + * We should first delete the old originator before adding the + * new one. + */ + if (common->flags & BATADV_TT_CLIENT_ROAM) { + delete = true; + tt_global_entry->roam_at = 0; + common->flags &= ~BATADV_TT_CLIENT_ROAM; + } + } + + return delete; +} + /** * batadv_tt_global_create() - allocate and initialize a global TT entry * @tt_addr: the mac address of the non-mesh client @@ -1974,41 +2025,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, goto add_orig_entry; } - delete = false; - - spin_lock_bh(&common->flags_lock); - /* if the client was temporary added before receiving the first - * OGM announcing it, we have to clear the TEMP flag. Also, - * remove the previous temporary orig node and re-add it - * if required. If the orig entry changed, the new one which - * is a non-temporary entry is preferred. - */ - if (common->flags & BATADV_TT_CLIENT_TEMP) { - delete = true; - common->flags &= ~BATADV_TT_CLIENT_TEMP; - } - - /* the change can carry possible "attribute" flags like the - * TT_CLIENT_TEMP, therefore they have to be copied in the - * client entry - */ - if (!is_multicast_ether_addr(common->addr)) - common->flags |= flags & (~BATADV_TT_SYNC_MASK); - - /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only - * one originator left in the list and we previously received a - * delete + roaming change for this originator. - * - * We should first delete the old originator before adding the - * new one. - */ - if (common->flags & BATADV_TT_CLIENT_ROAM) { - delete = true; - tt_global_entry->roam_at = 0; - common->flags &= ~BATADV_TT_CLIENT_ROAM; - } - spin_unlock_bh(&common->flags_lock); - + delete = batadv_tt_global_merge_flags(tt_global_entry, flags); if (delete) batadv_tt_global_del_orig_list(tt_global_entry); }