/* only modify transtable if it has been initialized before */
        if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
-               batadv_tt_local_remove(bat_priv, old_addr,
+               batadv_tt_local_remove(bat_priv, old_addr, BATADV_NO_FLAGS,
                                       "mac address changed", false);
-               batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX);
+               batadv_tt_local_add(dev, addr->sa_data, BATADV_NO_FLAGS,
+                                   BATADV_NULL_IFINDEX);
        }
 
        return 0;
 static int batadv_interface_tx(struct sk_buff *skb,
                               struct net_device *soft_iface)
 {
-       struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
+       struct ethhdr *ethhdr;
        struct batadv_priv *bat_priv = netdev_priv(soft_iface);
        struct batadv_hard_iface *primary_if = NULL;
        struct batadv_bcast_packet *bcast_packet;
-       struct vlan_ethhdr *vhdr;
        __be16 ethertype = htons(ETH_P_BATMAN);
        static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00,
                                                   0x00, 0x00};
        static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00,
                                                    0x00, 0x00};
+       struct vlan_ethhdr *vhdr;
        unsigned int header_len = 0;
        int data_len = skb->len, ret;
-       unsigned short vid __maybe_unused = BATADV_NO_FLAGS;
+       unsigned long brd_delay = 1;
        bool do_bcast = false;
+       unsigned short vid;
        uint32_t seqno;
-       unsigned long brd_delay = 1;
 
        if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
                goto dropped;
 
        soft_iface->trans_start = jiffies;
+       vid = batadv_get_vid(skb, 0);
+       ethhdr = (struct ethhdr *)skb->data;
 
        switch (ntohs(ethhdr->h_proto)) {
        case ETH_P_8021Q:
                vhdr = (struct vlan_ethhdr *)skb->data;
-               vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
-               vid |= BATADV_VLAN_HAS_TAG;
 
                if (vhdr->h_vlan_encapsulated_proto != ethertype)
                        break;
 
        /* Register the client MAC in the transtable */
        if (!is_multicast_ether_addr(ethhdr->h_source))
-               batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
+               batadv_tt_local_add(soft_iface, ethhdr->h_source, vid,
+                                   skb->skb_iif);
 
        /* don't accept stp packets. STP does not help in meshes.
         * better use the bridge loop avoidance ...
 
                batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
 
-               ret = batadv_send_skb_unicast(bat_priv, skb);
+               ret = batadv_send_skb_unicast(bat_priv, skb, vid);
                if (ret != 0)
                        goto dropped_freed;
        }
                         struct sk_buff *skb, struct batadv_hard_iface *recv_if,
                         int hdr_size, struct batadv_orig_node *orig_node)
 {
-       struct batadv_priv *bat_priv = netdev_priv(soft_iface);
-       struct ethhdr *ethhdr;
-       struct vlan_ethhdr *vhdr;
        struct batadv_header *batadv_header = (struct batadv_header *)skb->data;
-       unsigned short vid __maybe_unused = BATADV_NO_FLAGS;
+       struct batadv_priv *bat_priv = netdev_priv(soft_iface);
        __be16 ethertype = htons(ETH_P_BATMAN);
+       struct vlan_ethhdr *vhdr;
+       struct ethhdr *ethhdr;
+       unsigned short vid;
        bool is_bcast;
 
        is_bcast = (batadv_header->packet_type == BATADV_BCAST);
        skb_pull_rcsum(skb, hdr_size);
        skb_reset_mac_header(skb);
 
+       vid = batadv_get_vid(skb, hdr_size);
        ethhdr = eth_hdr(skb);
 
        switch (ntohs(ethhdr->h_proto)) {
        case ETH_P_8021Q:
                vhdr = (struct vlan_ethhdr *)skb->data;
-               vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
-               vid |= BATADV_VLAN_HAS_TAG;
 
                if (vhdr->h_vlan_encapsulated_proto != ethertype)
                        break;
 
        if (orig_node)
                batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
-                                                    ethhdr->h_source);
+                                                    ethhdr->h_source, vid);
 
        if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
                goto dropped;
 
 static struct lock_class_key batadv_tt_global_hash_lock_class_key;
 
 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
+                                unsigned short vid,
                                 struct batadv_orig_node *orig_node);
 static void batadv_tt_purge(struct work_struct *work);
 static void
 static void batadv_tt_global_del(struct batadv_priv *bat_priv,
                                 struct batadv_orig_node *orig_node,
                                 const unsigned char *addr,
-                                const char *message, bool roaming);
+                                unsigned short vid, const char *message,
+                                bool roaming);
 
 /* returns 1 if they are the same mac addr */
 static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
        return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
 }
 
+/**
+ * batadv_choose_tt - return the index of the tt entry in the hash table
+ * @data: pointer to the tt_common_entry object to map
+ * @size: the size of the hash table
+ *
+ * Returns the hash index where the object represented by 'data' should be
+ * stored at.
+ */
+static inline uint32_t batadv_choose_tt(const void *data, uint32_t size)
+{
+       struct batadv_tt_common_entry *tt;
+       uint32_t hash = 0;
+
+       tt = (struct batadv_tt_common_entry *)data;
+       hash = batadv_hash_bytes(hash, &tt->addr, ETH_ALEN);
+       hash = batadv_hash_bytes(hash, &tt->vid, sizeof(tt->vid));
+
+       hash += (hash << 3);
+       hash ^= (hash >> 11);
+       hash += (hash << 15);
+
+       return hash % size;
+}
+
+/**
+ * batadv_tt_hash_find - look for a client in the given hash table
+ * @hash: the hash table to search
+ * @addr: the mac address of the client to look for
+ * @vid: VLAN identifier
+ *
+ * Returns a pointer to the tt_common struct belonging to the searched client if
+ * found, NULL otherwise.
+ */
 static struct batadv_tt_common_entry *
-batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data)
+batadv_tt_hash_find(struct batadv_hashtable *hash, const uint8_t *addr,
+                   unsigned short vid)
 {
        struct hlist_head *head;
-       struct batadv_tt_common_entry *tt_common_entry;
-       struct batadv_tt_common_entry *tt_common_entry_tmp = NULL;
+       struct batadv_tt_common_entry to_search, *tt, *tt_tmp = NULL;
        uint32_t index;
 
        if (!hash)
                return NULL;
 
-       index = batadv_choose_orig(data, hash->size);
+       memcpy(to_search.addr, addr, ETH_ALEN);
+       to_search.vid = vid;
+
+       index = batadv_choose_tt(&to_search, hash->size);
        head = &hash->table[index];
 
        rcu_read_lock();
-       hlist_for_each_entry_rcu(tt_common_entry, head, hash_entry) {
-               if (!batadv_compare_eth(tt_common_entry, data))
+       hlist_for_each_entry_rcu(tt, head, hash_entry) {
+               if (!batadv_compare_eth(tt, addr))
+                       continue;
+
+               if (tt->vid != vid)
                        continue;
 
-               if (!atomic_inc_not_zero(&tt_common_entry->refcount))
+               if (!atomic_inc_not_zero(&tt->refcount))
                        continue;
 
-               tt_common_entry_tmp = tt_common_entry;
+               tt_tmp = tt;
                break;
        }
        rcu_read_unlock();
 
-       return tt_common_entry_tmp;
+       return tt_tmp;
 }
 
+/**
+ * batadv_tt_local_hash_find - search the local table for a given client
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the mac address of the client to look for
+ * @vid: VLAN identifier
+ *
+ * Returns a pointer to the corresponding tt_local_entry struct if the client is
+ * found, NULL otherwise.
+ */
 static struct batadv_tt_local_entry *
-batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data)
+batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
+                         unsigned short vid)
 {
        struct batadv_tt_common_entry *tt_common_entry;
        struct batadv_tt_local_entry *tt_local_entry = NULL;
 
-       tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data);
+       tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr,
+                                             vid);
        if (tt_common_entry)
                tt_local_entry = container_of(tt_common_entry,
                                              struct batadv_tt_local_entry,
        return tt_local_entry;
 }
 
+/**
+ * batadv_tt_global_hash_find - search the global table for a given client
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the mac address of the client to look for
+ * @vid: VLAN identifier
+ *
+ * Returns a pointer to the corresponding tt_global_entry struct if the client
+ * is found, NULL otherwise.
+ */
 static struct batadv_tt_global_entry *
-batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data)
+batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
+                          unsigned short vid)
 {
        struct batadv_tt_common_entry *tt_common_entry;
        struct batadv_tt_global_entry *tt_global_entry = NULL;
 
-       tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data);
+       tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr,
+                                             vid);
        if (tt_common_entry)
                tt_global_entry = container_of(tt_common_entry,
                                               struct batadv_tt_global_entry,
        tt_change_node->change.flags = flags;
        tt_change_node->change.reserved = 0;
        memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
+       tt_change_node->change.vid = htons(common->vid);
 
        del_op_requested = flags & BATADV_TT_CLIENT_DEL;
 
                   tt_global->common.addr, message);
 
        batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
-                          batadv_choose_orig, tt_global->common.addr);
+                          batadv_choose_tt, &tt_global->common);
        batadv_tt_global_entry_free_ref(tt_global);
 }
 
+/**
+ * batadv_tt_local_add - add a new client to the local table or update an
+ *  existing client
+ * @soft_iface: netdev struct of the mesh interface
+ * @addr: the mac address of the client to add
+ * @vid: VLAN identifier
+ * @ifindex: index of the interface where the client is connected to (useful to
+ *  identify wireless clients)
+ */
 void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
-                        int ifindex)
+                        unsigned short vid, int ifindex)
 {
        struct batadv_priv *bat_priv = netdev_priv(soft_iface);
        struct batadv_tt_local_entry *tt_local;
        int hash_added;
        bool roamed_back = false;
 
-       tt_local = batadv_tt_local_hash_find(bat_priv, addr);
-       tt_global = batadv_tt_global_hash_find(bat_priv, addr);
+       tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
+       tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
 
        if (tt_local) {
                tt_local->last_seen = jiffies;
         * (consistency check)
         */
        tt_local->common.flags = BATADV_TT_CLIENT_NEW;
+       tt_local->common.vid = vid;
        if (batadv_is_wifi_iface(ifindex))
                tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
        atomic_set(&tt_local->common.refcount, 2);
                tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
 
        hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
-                                    batadv_choose_orig, &tt_local->common,
+                                    batadv_choose_tt, &tt_local->common,
                                     &tt_local->common.hash_entry);
 
        if (unlikely(hash_added != 0)) {
                rcu_read_lock();
                hlist_for_each_entry_rcu(orig_entry, head, list) {
                        batadv_send_roam_adv(bat_priv, tt_global->common.addr,
+                                            tt_global->common.vid,
                                             orig_entry->orig_node);
                }
                rcu_read_unlock();
  * 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
+ * @vid: VLAN identifier
  * @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)
+                               const uint8_t *addr, unsigned short vid,
+                               const char *message, bool roaming)
 {
        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);
+       tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
        if (!tt_local_entry)
                goto out;
 
  * @bat_priv: the bat priv with all the soft interface information
  * @orig_node: the originator announcing the client
  * @tt_addr: the mac address of the non-mesh client
+ * @vid: VLAN identifier
  * @flags: TT flags that have to be set for this non-mesh client
  * @ttvn: the tt version number ever announcing this non-mesh client
  *
  */
 static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
                                 struct batadv_orig_node *orig_node,
-                                const unsigned char *tt_addr, uint16_t flags,
+                                const unsigned char *tt_addr,
+                                unsigned short vid, uint16_t flags,
                                 uint8_t ttvn)
 {
        struct batadv_tt_global_entry *tt_global_entry;
        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);
+       tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr, vid);
+       tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr, vid);
 
        /* 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
 
                common = &tt_global_entry->common;
                memcpy(common->addr, tt_addr, ETH_ALEN);
+               common->vid = vid;
 
                common->flags = flags;
                tt_global_entry->roam_at = 0;
 
                hash_added = batadv_hash_add(bat_priv->tt.global_hash,
                                             batadv_compare_tt,
-                                            batadv_choose_orig, common,
+                                            batadv_choose_tt, common,
                                             &common->hash_entry);
 
                if (unlikely(hash_added != 0)) {
 out_remove:
 
        /* remove address from local hash if present */
-       local_flags = batadv_tt_local_remove(bat_priv, tt_addr,
+       local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid,
                                             "global tt received",
                                             flags & BATADV_TT_CLIENT_ROAM);
        tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
                                                orig_node, message);
 }
 
-
-
+/**
+ * batadv_tt_global_del - remove a client from the global table
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: an originator serving this client
+ * @addr: the mac address of the client
+ * @vid: VLAN identifier
+ * @message: a message explaining the reason for deleting the client to print
+ *  for debugging purpose
+ * @roaming: true if the deletion has been triggered by a roaming event
+ */
 static void batadv_tt_global_del(struct batadv_priv *bat_priv,
                                 struct batadv_orig_node *orig_node,
-                                const unsigned char *addr,
+                                const unsigned char *addr, unsigned short vid,
                                 const char *message, bool roaming)
 {
        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);
+       tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
        if (!tt_global_entry)
                goto out;
 
         *    the global entry, since it is useless now.
         */
        local_entry = batadv_tt_local_hash_find(bat_priv,
-                                               tt_global_entry->common.addr);
+                                               tt_global_entry->common.addr,
+                                               vid);
        if (local_entry) {
                /* local entry exists, case 2: client roamed to us. */
                batadv_tt_global_del_orig_list(tt_global_entry);
        return ret;
 }
 
+/**
+ * batadv_transtable_search - get the mesh destination for a given client
+ * @bat_priv: the bat priv with all the soft interface information
+ * @src: mac address of the source client
+ * @addr: mac address of the destination client
+ * @vid: VLAN identifier
+ *
+ * Returns a pointer to the originator that was selected as destination in the
+ * mesh for contacting the client 'addr', NULL otherwise.
+ * In case of multiple originators serving the same client, the function returns
+ * the best one (best in terms of metric towards the destination node).
+ *
+ * If the two clients are AP isolated the function returns NULL.
+ */
 struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
                                                  const uint8_t *src,
-                                                 const uint8_t *addr)
+                                                 const uint8_t *addr,
+                                                 unsigned short vid)
 {
        struct batadv_tt_local_entry *tt_local_entry = NULL;
        struct batadv_tt_global_entry *tt_global_entry = NULL;
        struct batadv_tt_orig_list_entry *best_entry;
 
        if (src && atomic_read(&bat_priv->ap_isolation)) {
-               tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
+               tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid);
                if (!tt_local_entry ||
                    (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
                        goto out;
        }
 
-       tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
+       tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
        if (!tt_global_entry)
                goto out;
 
                        memcpy(tt_change->addr, tt_common_entry->addr,
                               ETH_ALEN);
                        tt_change->flags = tt_common_entry->flags;
+                       tt_change->vid = htons(tt_common_entry->vid);
                        tt_change->reserved = 0;
 
                        tt_num_entries++;
                        roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
                        batadv_tt_global_del(bat_priv, orig_node,
                                             (tt_change + i)->addr,
+                                            ntohs((tt_change + i)->vid),
                                             "tt removed by changes",
                                             roams);
                } else {
                        if (!batadv_tt_global_add(bat_priv, orig_node,
                                                  (tt_change + i)->addr,
+                                                 ntohs((tt_change + i)->vid),
                                                  (tt_change + i)->flags, ttvn))
                                /* In case of problem while storing a
                                 * global_entry, we stop the updating
        atomic_set(&orig_node->last_ttvn, ttvn);
 }
 
-bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr)
+/**
+ * batadv_is_my_client - check if a client is served by the local node
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the mac adress of the client to check
+ * @vid: VLAN identifier
+ *
+ * Returns true if the client is served by this node, false otherwise.
+ */
+bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
+                        unsigned short vid)
 {
        struct batadv_tt_local_entry *tt_local_entry;
        bool ret = false;
 
-       tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
+       tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
        if (!tt_local_entry)
                goto out;
        /* Check if the client has been logically deleted (but is kept for
        return ret;
 }
 
+/**
+ * batadv_send_roam_adv - send a roaming advertisement message
+ * @bat_priv: the bat priv with all the soft interface information
+ * @client: mac address of the roaming client
+ * @vid: VLAN identifier
+ * @orig_node: message destination
+ *
+ * Send a ROAMING_ADV message to the node which was previously serving this
+ * client. This is done to inform the node that from now on all traffic destined
+ * for this particular roamed client has to be forwarded to the sender of the
+ * roaming message.
+ */
 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
+                                unsigned short vid,
                                 struct batadv_orig_node *orig_node)
 {
        struct batadv_hard_iface *primary_if;
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
 
        memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client));
-       tvlv_roam.reserved = 0;
+       tvlv_roam.vid = htons(vid);
 
        batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
                                 orig_node->orig, BATADV_TVLV_ROAM, 1,
        if (!atomic_read(&bat_priv->ap_isolation))
                goto out;
 
-       tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst);
+       tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst,
+                                                  BATADV_NO_FLAGS);
        if (!tt_local_entry)
                goto out;
 
-       tt_global_entry = batadv_tt_global_hash_find(bat_priv, src);
+       tt_global_entry = batadv_tt_global_hash_find(bat_priv, src,
+                                                    BATADV_NO_FLAGS);
        if (!tt_global_entry)
                goto out;
 
        }
 }
 
-/* returns true whether we know that the client has moved from its old
- * originator to another one. This entry is kept is still kept for consistency
- * purposes
+/**
+ * batadv_tt_global_client_is_roaming - check if a client is marked as roaming
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the mac address of the client to check
+ * @vid: VLAN identifier
+ *
+ * Returns true if we know that the client has moved from its old originator
+ * to another one. This entry is still kept for consistency purposes and will be
+ * deleted later by a DEL or because of timeout
  */
 bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
-                                       uint8_t *addr)
+                                       uint8_t *addr, unsigned short vid)
 {
        struct batadv_tt_global_entry *tt_global_entry;
        bool ret = false;
 
-       tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
+       tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
        if (!tt_global_entry)
                goto out;
 
 /**
  * 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
+ * @addr: the mac address of the local client to query
+ * @vid: VLAN identifier
  *
  * 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)
+                                      uint8_t *addr, unsigned short vid)
 {
        struct batadv_tt_local_entry *tt_local_entry;
        bool ret = false;
 
-       tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
+       tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
        if (!tt_local_entry)
                goto out;
 
 
 bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
                                          struct batadv_orig_node *orig_node,
-                                         const unsigned char *addr)
+                                         const unsigned char *addr,
+                                         unsigned short vlan)
 {
        bool ret = false;
 
        if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
                goto out;
 
-       if (!batadv_tt_global_add(bat_priv, orig_node, addr,
+       if (!batadv_tt_global_add(bat_priv, orig_node, addr, vlan,
                                  BATADV_TT_CLIENT_TEMP,
                                  atomic_read(&orig_node->last_ttvn)))
                goto out;
                   src, roaming_adv->client);
 
        batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client,
-                            BATADV_TT_CLIENT_ROAM,
+                            ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM,
                             atomic_read(&orig_node->last_ttvn) + 1);
 
 out: