aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAntonio Quartulli <antonio@open-mesh.com>2013-06-04 06:11:39 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-19 09:11:21 -0400
commitc018ad3de61a1dc4194879a53e5559e094aa7b1a (patch)
tree4edb9c156b618dae46d38249a5c817e0d1f1e2b0 /net
parentbc58eeef744df93e141678ef44452f0869cd563d (diff)
batman-adv: add the VLAN ID attribute to the TT entry
To make the translation table code VLAN-aware, each entry must carry the VLAN ID which it belongs to. This patch adds such attribute to the related TT structures. Signed-off-by: Antonio Quartulli <antonio@open-mesh.com> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c35
-rw-r--r--net/batman-adv/distributed-arp-table.c11
-rw-r--r--net/batman-adv/gateway_client.c3
-rw-r--r--net/batman-adv/main.c29
-rw-r--r--net/batman-adv/main.h9
-rw-r--r--net/batman-adv/packet.h14
-rw-r--r--net/batman-adv/routing.c26
-rw-r--r--net/batman-adv/send.c8
-rw-r--r--net/batman-adv/send.h16
-rw-r--r--net/batman-adv/soft-interface.c35
-rw-r--r--net/batman-adv/translation-table.c240
-rw-r--r--net/batman-adv/translation-table.h19
-rw-r--r--net/batman-adv/types.h2
13 files changed, 312 insertions, 135 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 5bb58d7bdd56..e8a6458081e8 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -858,27 +858,25 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
858 struct batadv_hard_iface *primary_if, 858 struct batadv_hard_iface *primary_if,
859 struct sk_buff *skb) 859 struct sk_buff *skb)
860{ 860{
861 struct ethhdr *ethhdr; 861 struct batadv_bla_claim_dst *bla_dst;
862 uint8_t *hw_src, *hw_dst;
862 struct vlan_ethhdr *vhdr; 863 struct vlan_ethhdr *vhdr;
864 struct ethhdr *ethhdr;
863 struct arphdr *arphdr; 865 struct arphdr *arphdr;
864 uint8_t *hw_src, *hw_dst; 866 unsigned short vid;
865 struct batadv_bla_claim_dst *bla_dst;
866 __be16 proto; 867 __be16 proto;
867 int headlen; 868 int headlen;
868 unsigned short vid = BATADV_NO_FLAGS;
869 int ret; 869 int ret;
870 870
871 vid = batadv_get_vid(skb, 0);
871 ethhdr = eth_hdr(skb); 872 ethhdr = eth_hdr(skb);
872 873
873 if (ethhdr->h_proto == htons(ETH_P_8021Q)) { 874 proto = ethhdr->h_proto;
875 headlen = ETH_HLEN;
876 if (vid & BATADV_VLAN_HAS_TAG) {
874 vhdr = (struct vlan_ethhdr *)ethhdr; 877 vhdr = (struct vlan_ethhdr *)ethhdr;
875 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
876 vid |= BATADV_VLAN_HAS_TAG;
877 proto = vhdr->h_vlan_encapsulated_proto; 878 proto = vhdr->h_vlan_encapsulated_proto;
878 headlen = sizeof(*vhdr); 879 headlen += VLAN_HLEN;
879 } else {
880 proto = ethhdr->h_proto;
881 headlen = ETH_HLEN;
882 } 880 }
883 881
884 if (proto != htons(ETH_P_ARP)) 882 if (proto != htons(ETH_P_ARP))
@@ -1365,10 +1363,8 @@ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
1365int batadv_bla_is_backbone_gw(struct sk_buff *skb, 1363int batadv_bla_is_backbone_gw(struct sk_buff *skb,
1366 struct batadv_orig_node *orig_node, int hdr_size) 1364 struct batadv_orig_node *orig_node, int hdr_size)
1367{ 1365{
1368 struct ethhdr *ethhdr;
1369 struct vlan_ethhdr *vhdr;
1370 struct batadv_bla_backbone_gw *backbone_gw; 1366 struct batadv_bla_backbone_gw *backbone_gw;
1371 unsigned short vid = BATADV_NO_FLAGS; 1367 unsigned short vid;
1372 1368
1373 if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance)) 1369 if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
1374 return 0; 1370 return 0;
@@ -1377,16 +1373,7 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb,
1377 if (!pskb_may_pull(skb, hdr_size + ETH_HLEN)) 1373 if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
1378 return 0; 1374 return 0;
1379 1375
1380 ethhdr = (struct ethhdr *)(((uint8_t *)skb->data) + hdr_size); 1376 vid = batadv_get_vid(skb, hdr_size);
1381
1382 if (ethhdr->h_proto == htons(ETH_P_8021Q)) {
1383 if (!pskb_may_pull(skb, hdr_size + VLAN_ETH_HLEN))
1384 return 0;
1385
1386 vhdr = (struct vlan_ethhdr *)(skb->data + hdr_size);
1387 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
1388 vid |= BATADV_VLAN_HAS_TAG;
1389 }
1390 1377
1391 /* see if this originator is a backbone gw for this VLAN */ 1378 /* see if this originator is a backbone gw for this VLAN */
1392 backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv, 1379 backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 99da41290f82..1b590f01f824 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -905,7 +905,8 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
905 * additional DAT answer may trigger kernel warnings about 905 * additional DAT answer may trigger kernel warnings about
906 * a packet coming from the wrong port. 906 * a packet coming from the wrong port.
907 */ 907 */
908 if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) { 908 if (batadv_is_my_client(bat_priv, dat_entry->mac_addr,
909 BATADV_NO_FLAGS)) {
909 ret = true; 910 ret = true;
910 goto out; 911 goto out;
911 } 912 }
@@ -990,9 +991,11 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
990 */ 991 */
991 if (hdr_size == sizeof(struct batadv_unicast_4addr_packet)) 992 if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
992 err = batadv_send_skb_unicast_4addr(bat_priv, skb_new, 993 err = batadv_send_skb_unicast_4addr(bat_priv, skb_new,
993 BATADV_P_DAT_CACHE_REPLY); 994 BATADV_P_DAT_CACHE_REPLY,
995 BATADV_NO_FLAGS);
994 else 996 else
995 err = batadv_send_skb_unicast(bat_priv, skb_new); 997 err = batadv_send_skb_unicast(bat_priv, skb_new,
998 BATADV_NO_FLAGS);
996 999
997 if (!err) { 1000 if (!err) {
998 batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX); 1001 batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX);
@@ -1080,7 +1083,7 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
1080 /* if this REPLY is directed to a client of mine, let's deliver the 1083 /* if this REPLY is directed to a client of mine, let's deliver the
1081 * packet to the interface 1084 * packet to the interface
1082 */ 1085 */
1083 ret = !batadv_is_my_client(bat_priv, hw_dst); 1086 ret = !batadv_is_my_client(bat_priv, hw_dst, BATADV_NO_FLAGS);
1084out: 1087out:
1085 if (ret) 1088 if (ret)
1086 kfree_skb(skb); 1089 kfree_skb(skb);
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 053bb318c7a7..a9209466ddaf 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -744,7 +744,8 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
744 744
745 ethhdr = (struct ethhdr *)skb->data; 745 ethhdr = (struct ethhdr *)skb->data;
746 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source, 746 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
747 ethhdr->h_dest); 747 ethhdr->h_dest,
748 BATADV_NO_FLAGS);
748 if (!orig_dst_node) 749 if (!orig_dst_node)
749 goto out; 750 goto out;
750 751
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 7f3a5c426615..80f60d1144f0 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -132,7 +132,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
132 goto err; 132 goto err;
133 133
134 batadv_tt_local_add(soft_iface, soft_iface->dev_addr, 134 batadv_tt_local_add(soft_iface, soft_iface->dev_addr,
135 BATADV_NULL_IFINDEX); 135 BATADV_NO_FLAGS, BATADV_NULL_IFINDEX);
136 136
137 ret = batadv_bla_init(bat_priv); 137 ret = batadv_bla_init(bat_priv);
138 if (ret < 0) 138 if (ret < 0)
@@ -1144,6 +1144,33 @@ out:
1144 batadv_orig_node_free_ref(orig_node); 1144 batadv_orig_node_free_ref(orig_node);
1145} 1145}
1146 1146
1147/**
1148 * batadv_get_vid - extract the VLAN identifier from skb if any
1149 * @skb: the buffer containing the packet
1150 * @header_len: length of the batman header preceding the ethernet header
1151 *
1152 * If the packet embedded in the skb is vlan tagged this function returns the
1153 * VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS is returned.
1154 */
1155unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len)
1156{
1157 struct ethhdr *ethhdr = (struct ethhdr *)(skb->data + header_len);
1158 struct vlan_ethhdr *vhdr;
1159 unsigned short vid;
1160
1161 if (ethhdr->h_proto != htons(ETH_P_8021Q))
1162 return BATADV_NO_FLAGS;
1163
1164 if (!pskb_may_pull(skb, header_len + VLAN_ETH_HLEN))
1165 return BATADV_NO_FLAGS;
1166
1167 vhdr = (struct vlan_ethhdr *)(skb->data + header_len);
1168 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
1169 vid |= BATADV_VLAN_HAS_TAG;
1170
1171 return vid;
1172}
1173
1147static int batadv_param_set_ra(const char *val, const struct kernel_param *kp) 1174static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
1148{ 1175{
1149 struct batadv_algo_ops *bat_algo_ops; 1176 struct batadv_algo_ops *bat_algo_ops;
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index ff55dccbf6e4..2774d7f4ee0b 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -169,14 +169,6 @@ enum batadv_uev_type {
169#include <linux/seq_file.h> 169#include <linux/seq_file.h>
170#include "types.h" 170#include "types.h"
171 171
172/**
173 * batadv_vlan_flags - flags for the four MSB of any vlan ID field
174 * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not
175 */
176enum batadv_vlan_flags {
177 BATADV_VLAN_HAS_TAG = BIT(15),
178};
179
180#define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \ 172#define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \
181 (int)(vid & VLAN_VID_MASK) : -1) 173 (int)(vid & VLAN_VID_MASK) : -1)
182 174
@@ -368,5 +360,6 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
368void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src, 360void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src,
369 uint8_t *dst, uint8_t type, uint8_t version, 361 uint8_t *dst, uint8_t type, uint8_t version,
370 void *tvlv_value, uint16_t tvlv_value_len); 362 void *tvlv_value, uint16_t tvlv_value_len);
363unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len);
371 364
372#endif /* _NET_BATMAN_ADV_MAIN_H_ */ 365#endif /* _NET_BATMAN_ADV_MAIN_H_ */
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 65e723ed030b..6311642f3ee8 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -122,6 +122,14 @@ enum batadv_tt_client_flags {
122 BATADV_TT_CLIENT_TEMP = BIT(11), 122 BATADV_TT_CLIENT_TEMP = BIT(11),
123}; 123};
124 124
125/**
126 * batadv_vlan_flags - flags for the four MSB of any vlan ID field
127 * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not
128 */
129enum batadv_vlan_flags {
130 BATADV_VLAN_HAS_TAG = BIT(15),
131};
132
125/* claim frame types for the bridge loop avoidance */ 133/* claim frame types for the bridge loop avoidance */
126enum batadv_bla_claimframe { 134enum batadv_bla_claimframe {
127 BATADV_CLAIM_TYPE_CLAIM = 0x00, 135 BATADV_CLAIM_TYPE_CLAIM = 0x00,
@@ -399,21 +407,23 @@ struct batadv_tvlv_tt_data {
399 * batadv_tt_client_flags) 407 * batadv_tt_client_flags)
400 * @reserved: reserved field 408 * @reserved: reserved field
401 * @addr: mac address of non-mesh client that triggered this tt change 409 * @addr: mac address of non-mesh client that triggered this tt change
410 * @vid: VLAN identifier
402 */ 411 */
403struct batadv_tvlv_tt_change { 412struct batadv_tvlv_tt_change {
404 uint8_t flags; 413 uint8_t flags;
405 uint8_t reserved; 414 uint8_t reserved;
406 uint8_t addr[ETH_ALEN]; 415 uint8_t addr[ETH_ALEN];
416 __be16 vid;
407}; 417};
408 418
409/** 419/**
410 * struct batadv_tvlv_roam_adv - roaming advertisement 420 * struct batadv_tvlv_roam_adv - roaming advertisement
411 * @client: mac address of roaming client 421 * @client: mac address of roaming client
412 * @reserved: field reserved for future use 422 * @vid: VLAN identifier
413 */ 423 */
414struct batadv_tvlv_roam_adv { 424struct batadv_tvlv_roam_adv {
415 uint8_t client[ETH_ALEN]; 425 uint8_t client[ETH_ALEN];
416 uint16_t reserved; 426 __be16 vid;
417}; 427};
418 428
419#endif /* _NET_BATMAN_ADV_PACKET_H_ */ 429#endif /* _NET_BATMAN_ADV_PACKET_H_ */
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 3281a504c20a..149ef57e78c3 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -30,6 +30,8 @@
30#include "network-coding.h" 30#include "network-coding.h"
31#include "fragmentation.h" 31#include "fragmentation.h"
32 32
33#include <linux/if_vlan.h>
34
33static int batadv_route_unicast_packet(struct sk_buff *skb, 35static int batadv_route_unicast_packet(struct sk_buff *skb,
34 struct batadv_hard_iface *recv_if); 36 struct batadv_hard_iface *recv_if);
35 37
@@ -724,6 +726,7 @@ out:
724 * @bat_priv: the bat priv with all the soft interface information 726 * @bat_priv: the bat priv with all the soft interface information
725 * @unicast_packet: the unicast header to be updated 727 * @unicast_packet: the unicast header to be updated
726 * @dst_addr: the payload destination 728 * @dst_addr: the payload destination
729 * @vid: VLAN identifier
727 * 730 *
728 * Search the translation table for dst_addr and update the unicast header with 731 * Search the translation table for dst_addr and update the unicast header with
729 * the new corresponding information (originator address where the destination 732 * the new corresponding information (originator address where the destination
@@ -734,21 +737,22 @@ out:
734static bool 737static bool
735batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, 738batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
736 struct batadv_unicast_packet *unicast_packet, 739 struct batadv_unicast_packet *unicast_packet,
737 uint8_t *dst_addr) 740 uint8_t *dst_addr, unsigned short vid)
738{ 741{
739 struct batadv_orig_node *orig_node = NULL; 742 struct batadv_orig_node *orig_node = NULL;
740 struct batadv_hard_iface *primary_if = NULL; 743 struct batadv_hard_iface *primary_if = NULL;
741 bool ret = false; 744 bool ret = false;
742 uint8_t *orig_addr, orig_ttvn; 745 uint8_t *orig_addr, orig_ttvn;
743 746
744 if (batadv_is_my_client(bat_priv, dst_addr)) { 747 if (batadv_is_my_client(bat_priv, dst_addr, vid)) {
745 primary_if = batadv_primary_if_get_selected(bat_priv); 748 primary_if = batadv_primary_if_get_selected(bat_priv);
746 if (!primary_if) 749 if (!primary_if)
747 goto out; 750 goto out;
748 orig_addr = primary_if->net_dev->dev_addr; 751 orig_addr = primary_if->net_dev->dev_addr;
749 orig_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 752 orig_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
750 } else { 753 } else {
751 orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr); 754 orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr,
755 vid);
752 if (!orig_node) 756 if (!orig_node)
753 goto out; 757 goto out;
754 758
@@ -775,11 +779,12 @@ out:
775 779
776static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, 780static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
777 struct sk_buff *skb, int hdr_len) { 781 struct sk_buff *skb, int hdr_len) {
778 uint8_t curr_ttvn, old_ttvn; 782 struct batadv_unicast_packet *unicast_packet;
783 struct batadv_hard_iface *primary_if;
779 struct batadv_orig_node *orig_node; 784 struct batadv_orig_node *orig_node;
785 uint8_t curr_ttvn, old_ttvn;
780 struct ethhdr *ethhdr; 786 struct ethhdr *ethhdr;
781 struct batadv_hard_iface *primary_if; 787 unsigned short vid;
782 struct batadv_unicast_packet *unicast_packet;
783 int is_old_ttvn; 788 int is_old_ttvn;
784 789
785 /* check if there is enough data before accessing it */ 790 /* check if there is enough data before accessing it */
@@ -791,6 +796,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
791 return 0; 796 return 0;
792 797
793 unicast_packet = (struct batadv_unicast_packet *)skb->data; 798 unicast_packet = (struct batadv_unicast_packet *)skb->data;
799 vid = batadv_get_vid(skb, hdr_len);
794 ethhdr = (struct ethhdr *)(skb->data + hdr_len); 800 ethhdr = (struct ethhdr *)(skb->data + hdr_len);
795 801
796 /* check if the destination client was served by this node and it is now 802 /* check if the destination client was served by this node and it is now
@@ -798,9 +804,9 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
798 * message and that it knows the new destination in the mesh to re-route 804 * message and that it knows the new destination in the mesh to re-route
799 * the packet to 805 * the packet to
800 */ 806 */
801 if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest)) { 807 if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) {
802 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet, 808 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
803 ethhdr->h_dest)) 809 ethhdr->h_dest, vid))
804 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, 810 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT,
805 bat_priv, 811 bat_priv,
806 "Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n", 812 "Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n",
@@ -846,7 +852,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
846 * target host 852 * target host
847 */ 853 */
848 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet, 854 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
849 ethhdr->h_dest)) { 855 ethhdr->h_dest, vid)) {
850 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv, 856 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv,
851 "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", 857 "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
852 unicast_packet->dest, ethhdr->h_dest, 858 unicast_packet->dest, ethhdr->h_dest,
@@ -858,7 +864,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
858 * currently served by this node or there is no destination at all and 864 * currently served by this node or there is no destination at all and
859 * it is possible to drop the packet 865 * it is possible to drop the packet
860 */ 866 */
861 if (!batadv_is_my_client(bat_priv, ethhdr->h_dest)) 867 if (!batadv_is_my_client(bat_priv, ethhdr->h_dest, vid))
862 return 0; 868 return 0;
863 869
864 /* update the header in order to let the packet be delivered to this 870 /* update the header in order to let the packet be delivered to this
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index d765d53f8201..acaa7ffff245 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -240,12 +240,14 @@ out:
240 * @packet_type: the batman unicast packet type to use 240 * @packet_type: the batman unicast packet type to use
241 * @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast 241 * @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast
242 * 4addr packets) 242 * 4addr packets)
243 * @vid: the vid to be used to search the translation table
243 * 244 *
244 * Returns 1 in case of error or 0 otherwise. 245 * Returns 1 in case of error or 0 otherwise.
245 */ 246 */
246int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv, 247int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
247 struct sk_buff *skb, int packet_type, 248 struct sk_buff *skb, int packet_type,
248 int packet_subtype) 249 int packet_subtype,
250 unsigned short vid)
249{ 251{
250 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 252 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
251 struct batadv_unicast_packet *unicast_packet; 253 struct batadv_unicast_packet *unicast_packet;
@@ -260,7 +262,7 @@ int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
260 * returns NULL in case of AP isolation 262 * returns NULL in case of AP isolation
261 */ 263 */
262 orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source, 264 orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
263 ethhdr->h_dest); 265 ethhdr->h_dest, vid);
264 266
265 if (!orig_node) 267 if (!orig_node)
266 goto out; 268 goto out;
@@ -290,7 +292,7 @@ int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
290 * try to reroute it because the ttvn contained in the header is less 292 * try to reroute it because the ttvn contained in the header is less
291 * than the current one 293 * than the current one
292 */ 294 */
293 if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) 295 if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest, vid))
294 unicast_packet->ttvn = unicast_packet->ttvn - 1; 296 unicast_packet->ttvn = unicast_packet->ttvn - 1;
295 297
296 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 298 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index ad63184a4dd9..c030cb72ff45 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -40,21 +40,23 @@ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv,
40 int packet_subtype); 40 int packet_subtype);
41int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv, 41int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
42 struct sk_buff *skb, int packet_type, 42 struct sk_buff *skb, int packet_type,
43 int packet_subtype); 43 int packet_subtype,
44 44 unsigned short vid);
45 45
46/** 46/**
47 * batadv_send_unicast_skb - send the skb encapsulated in a unicast packet 47 * batadv_send_unicast_skb - send the skb encapsulated in a unicast packet
48 * @bat_priv: the bat priv with all the soft interface information 48 * @bat_priv: the bat priv with all the soft interface information
49 * @skb: the payload to send 49 * @skb: the payload to send
50 * @vid: the vid to be used to search the translation table
50 * 51 *
51 * Returns 1 in case of error or 0 otherwise. 52 * Returns 1 in case of error or 0 otherwise.
52 */ 53 */
53static inline int batadv_send_skb_unicast(struct batadv_priv *bat_priv, 54static inline int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
54 struct sk_buff *skb) 55 struct sk_buff *skb,
56 unsigned short vid)
55{ 57{
56 return batadv_send_skb_generic_unicast(bat_priv, skb, BATADV_UNICAST, 58 return batadv_send_skb_generic_unicast(bat_priv, skb, BATADV_UNICAST,
57 0); 59 0, vid);
58} 60}
59 61
60/** 62/**
@@ -63,16 +65,18 @@ static inline int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
63 * @bat_priv: the bat priv with all the soft interface information 65 * @bat_priv: the bat priv with all the soft interface information
64 * @skb: the payload to send 66 * @skb: the payload to send
65 * @packet_subtype: the unicast 4addr packet subtype to use 67 * @packet_subtype: the unicast 4addr packet subtype to use
68 * @vid: the vid to be used to search the translation table
66 * 69 *
67 * Returns 1 in case of error or 0 otherwise. 70 * Returns 1 in case of error or 0 otherwise.
68 */ 71 */
69static inline int batadv_send_skb_unicast_4addr(struct batadv_priv *bat_priv, 72static inline int batadv_send_skb_unicast_4addr(struct batadv_priv *bat_priv,
70 struct sk_buff *skb, 73 struct sk_buff *skb,
71 int packet_subtype) 74 int packet_subtype,
75 unsigned short vid)
72{ 76{
73 return batadv_send_skb_generic_unicast(bat_priv, skb, 77 return batadv_send_skb_generic_unicast(bat_priv, skb,
74 BATADV_UNICAST_4ADDR, 78 BATADV_UNICAST_4ADDR,
75 packet_subtype); 79 packet_subtype, vid);
76} 80}
77 81
78#endif /* _NET_BATMAN_ADV_SEND_H_ */ 82#endif /* _NET_BATMAN_ADV_SEND_H_ */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index e8a2bd699d40..279e91d570a7 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -118,9 +118,10 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
118 118
119 /* only modify transtable if it has been initialized before */ 119 /* only modify transtable if it has been initialized before */
120 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { 120 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
121 batadv_tt_local_remove(bat_priv, old_addr, 121 batadv_tt_local_remove(bat_priv, old_addr, BATADV_NO_FLAGS,
122 "mac address changed", false); 122 "mac address changed", false);
123 batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX); 123 batadv_tt_local_add(dev, addr->sa_data, BATADV_NO_FLAGS,
124 BATADV_NULL_IFINDEX);
124 } 125 }
125 126
126 return 0; 127 return 0;
@@ -152,33 +153,33 @@ static void batadv_interface_set_rx_mode(struct net_device *dev)
152static int batadv_interface_tx(struct sk_buff *skb, 153static int batadv_interface_tx(struct sk_buff *skb,
153 struct net_device *soft_iface) 154 struct net_device *soft_iface)
154{ 155{
155 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 156 struct ethhdr *ethhdr;
156 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 157 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
157 struct batadv_hard_iface *primary_if = NULL; 158 struct batadv_hard_iface *primary_if = NULL;
158 struct batadv_bcast_packet *bcast_packet; 159 struct batadv_bcast_packet *bcast_packet;
159 struct vlan_ethhdr *vhdr;
160 __be16 ethertype = htons(ETH_P_BATMAN); 160 __be16 ethertype = htons(ETH_P_BATMAN);
161 static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 161 static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00,
162 0x00, 0x00}; 162 0x00, 0x00};
163 static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, 163 static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00,
164 0x00, 0x00}; 164 0x00, 0x00};
165 struct vlan_ethhdr *vhdr;
165 unsigned int header_len = 0; 166 unsigned int header_len = 0;
166 int data_len = skb->len, ret; 167 int data_len = skb->len, ret;
167 unsigned short vid __maybe_unused = BATADV_NO_FLAGS; 168 unsigned long brd_delay = 1;
168 bool do_bcast = false; 169 bool do_bcast = false;
170 unsigned short vid;
169 uint32_t seqno; 171 uint32_t seqno;
170 unsigned long brd_delay = 1;
171 172
172 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 173 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
173 goto dropped; 174 goto dropped;
174 175
175 soft_iface->trans_start = jiffies; 176 soft_iface->trans_start = jiffies;
177 vid = batadv_get_vid(skb, 0);
178 ethhdr = (struct ethhdr *)skb->data;
176 179
177 switch (ntohs(ethhdr->h_proto)) { 180 switch (ntohs(ethhdr->h_proto)) {
178 case ETH_P_8021Q: 181 case ETH_P_8021Q:
179 vhdr = (struct vlan_ethhdr *)skb->data; 182 vhdr = (struct vlan_ethhdr *)skb->data;
180 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
181 vid |= BATADV_VLAN_HAS_TAG;
182 183
183 if (vhdr->h_vlan_encapsulated_proto != ethertype) 184 if (vhdr->h_vlan_encapsulated_proto != ethertype)
184 break; 185 break;
@@ -196,7 +197,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
196 197
197 /* Register the client MAC in the transtable */ 198 /* Register the client MAC in the transtable */
198 if (!is_multicast_ether_addr(ethhdr->h_source)) 199 if (!is_multicast_ether_addr(ethhdr->h_source))
199 batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); 200 batadv_tt_local_add(soft_iface, ethhdr->h_source, vid,
201 skb->skb_iif);
200 202
201 /* don't accept stp packets. STP does not help in meshes. 203 /* don't accept stp packets. STP does not help in meshes.
202 * better use the bridge loop avoidance ... 204 * better use the bridge loop avoidance ...
@@ -296,7 +298,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
296 298
297 batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); 299 batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
298 300
299 ret = batadv_send_skb_unicast(bat_priv, skb); 301 ret = batadv_send_skb_unicast(bat_priv, skb, vid);
300 if (ret != 0) 302 if (ret != 0)
301 goto dropped_freed; 303 goto dropped_freed;
302 } 304 }
@@ -319,12 +321,12 @@ void batadv_interface_rx(struct net_device *soft_iface,
319 struct sk_buff *skb, struct batadv_hard_iface *recv_if, 321 struct sk_buff *skb, struct batadv_hard_iface *recv_if,
320 int hdr_size, struct batadv_orig_node *orig_node) 322 int hdr_size, struct batadv_orig_node *orig_node)
321{ 323{
322 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
323 struct ethhdr *ethhdr;
324 struct vlan_ethhdr *vhdr;
325 struct batadv_header *batadv_header = (struct batadv_header *)skb->data; 324 struct batadv_header *batadv_header = (struct batadv_header *)skb->data;
326 unsigned short vid __maybe_unused = BATADV_NO_FLAGS; 325 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
327 __be16 ethertype = htons(ETH_P_BATMAN); 326 __be16 ethertype = htons(ETH_P_BATMAN);
327 struct vlan_ethhdr *vhdr;
328 struct ethhdr *ethhdr;
329 unsigned short vid;
328 bool is_bcast; 330 bool is_bcast;
329 331
330 is_bcast = (batadv_header->packet_type == BATADV_BCAST); 332 is_bcast = (batadv_header->packet_type == BATADV_BCAST);
@@ -336,13 +338,12 @@ void batadv_interface_rx(struct net_device *soft_iface,
336 skb_pull_rcsum(skb, hdr_size); 338 skb_pull_rcsum(skb, hdr_size);
337 skb_reset_mac_header(skb); 339 skb_reset_mac_header(skb);
338 340
341 vid = batadv_get_vid(skb, hdr_size);
339 ethhdr = eth_hdr(skb); 342 ethhdr = eth_hdr(skb);
340 343
341 switch (ntohs(ethhdr->h_proto)) { 344 switch (ntohs(ethhdr->h_proto)) {
342 case ETH_P_8021Q: 345 case ETH_P_8021Q:
343 vhdr = (struct vlan_ethhdr *)skb->data; 346 vhdr = (struct vlan_ethhdr *)skb->data;
344 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
345 vid |= BATADV_VLAN_HAS_TAG;
346 347
347 if (vhdr->h_vlan_encapsulated_proto != ethertype) 348 if (vhdr->h_vlan_encapsulated_proto != ethertype)
348 break; 349 break;
@@ -378,7 +379,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
378 379
379 if (orig_node) 380 if (orig_node)
380 batadv_tt_add_temporary_global_entry(bat_priv, orig_node, 381 batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
381 ethhdr->h_source); 382 ethhdr->h_source, vid);
382 383
383 if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) 384 if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
384 goto dropped; 385 goto dropped;
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index b521afb186d4..63adb97a7677 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -34,6 +34,7 @@ static struct lock_class_key batadv_tt_local_hash_lock_class_key;
34static struct lock_class_key batadv_tt_global_hash_lock_class_key; 34static struct lock_class_key batadv_tt_global_hash_lock_class_key;
35 35
36static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 36static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
37 unsigned short vid,
37 struct batadv_orig_node *orig_node); 38 struct batadv_orig_node *orig_node);
38static void batadv_tt_purge(struct work_struct *work); 39static void batadv_tt_purge(struct work_struct *work);
39static void 40static void
@@ -41,7 +42,8 @@ batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
41static void batadv_tt_global_del(struct batadv_priv *bat_priv, 42static void batadv_tt_global_del(struct batadv_priv *bat_priv,
42 struct batadv_orig_node *orig_node, 43 struct batadv_orig_node *orig_node,
43 const unsigned char *addr, 44 const unsigned char *addr,
44 const char *message, bool roaming); 45 unsigned short vid, const char *message,
46 bool roaming);
45 47
46/* returns 1 if they are the same mac addr */ 48/* returns 1 if they are the same mac addr */
47static int batadv_compare_tt(const struct hlist_node *node, const void *data2) 49static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
@@ -52,43 +54,93 @@ static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
52 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 54 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
53} 55}
54 56
57/**
58 * batadv_choose_tt - return the index of the tt entry in the hash table
59 * @data: pointer to the tt_common_entry object to map
60 * @size: the size of the hash table
61 *
62 * Returns the hash index where the object represented by 'data' should be
63 * stored at.
64 */
65static inline uint32_t batadv_choose_tt(const void *data, uint32_t size)
66{
67 struct batadv_tt_common_entry *tt;
68 uint32_t hash = 0;
69
70 tt = (struct batadv_tt_common_entry *)data;
71 hash = batadv_hash_bytes(hash, &tt->addr, ETH_ALEN);
72 hash = batadv_hash_bytes(hash, &tt->vid, sizeof(tt->vid));
73
74 hash += (hash << 3);
75 hash ^= (hash >> 11);
76 hash += (hash << 15);
77
78 return hash % size;
79}
80
81/**
82 * batadv_tt_hash_find - look for a client in the given hash table
83 * @hash: the hash table to search
84 * @addr: the mac address of the client to look for
85 * @vid: VLAN identifier
86 *
87 * Returns a pointer to the tt_common struct belonging to the searched client if
88 * found, NULL otherwise.
89 */
55static struct batadv_tt_common_entry * 90static struct batadv_tt_common_entry *
56batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data) 91batadv_tt_hash_find(struct batadv_hashtable *hash, const uint8_t *addr,
92 unsigned short vid)
57{ 93{
58 struct hlist_head *head; 94 struct hlist_head *head;
59 struct batadv_tt_common_entry *tt_common_entry; 95 struct batadv_tt_common_entry to_search, *tt, *tt_tmp = NULL;
60 struct batadv_tt_common_entry *tt_common_entry_tmp = NULL;
61 uint32_t index; 96 uint32_t index;
62 97
63 if (!hash) 98 if (!hash)
64 return NULL; 99 return NULL;
65 100
66 index = batadv_choose_orig(data, hash->size); 101 memcpy(to_search.addr, addr, ETH_ALEN);
102 to_search.vid = vid;
103
104 index = batadv_choose_tt(&to_search, hash->size);
67 head = &hash->table[index]; 105 head = &hash->table[index];
68 106
69 rcu_read_lock(); 107 rcu_read_lock();
70 hlist_for_each_entry_rcu(tt_common_entry, head, hash_entry) { 108 hlist_for_each_entry_rcu(tt, head, hash_entry) {
71 if (!batadv_compare_eth(tt_common_entry, data)) 109 if (!batadv_compare_eth(tt, addr))
110 continue;
111
112 if (tt->vid != vid)
72 continue; 113 continue;
73 114
74 if (!atomic_inc_not_zero(&tt_common_entry->refcount)) 115 if (!atomic_inc_not_zero(&tt->refcount))
75 continue; 116 continue;
76 117
77 tt_common_entry_tmp = tt_common_entry; 118 tt_tmp = tt;
78 break; 119 break;
79 } 120 }
80 rcu_read_unlock(); 121 rcu_read_unlock();
81 122
82 return tt_common_entry_tmp; 123 return tt_tmp;
83} 124}
84 125
126/**
127 * batadv_tt_local_hash_find - search the local table for a given client
128 * @bat_priv: the bat priv with all the soft interface information
129 * @addr: the mac address of the client to look for
130 * @vid: VLAN identifier
131 *
132 * Returns a pointer to the corresponding tt_local_entry struct if the client is
133 * found, NULL otherwise.
134 */
85static struct batadv_tt_local_entry * 135static struct batadv_tt_local_entry *
86batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data) 136batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
137 unsigned short vid)
87{ 138{
88 struct batadv_tt_common_entry *tt_common_entry; 139 struct batadv_tt_common_entry *tt_common_entry;
89 struct batadv_tt_local_entry *tt_local_entry = NULL; 140 struct batadv_tt_local_entry *tt_local_entry = NULL;
90 141
91 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data); 142 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr,
143 vid);
92 if (tt_common_entry) 144 if (tt_common_entry)
93 tt_local_entry = container_of(tt_common_entry, 145 tt_local_entry = container_of(tt_common_entry,
94 struct batadv_tt_local_entry, 146 struct batadv_tt_local_entry,
@@ -96,13 +148,24 @@ batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data)
96 return tt_local_entry; 148 return tt_local_entry;
97} 149}
98 150
151/**
152 * batadv_tt_global_hash_find - search the global table for a given client
153 * @bat_priv: the bat priv with all the soft interface information
154 * @addr: the mac address of the client to look for
155 * @vid: VLAN identifier
156 *
157 * Returns a pointer to the corresponding tt_global_entry struct if the client
158 * is found, NULL otherwise.
159 */
99static struct batadv_tt_global_entry * 160static struct batadv_tt_global_entry *
100batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data) 161batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
162 unsigned short vid)
101{ 163{
102 struct batadv_tt_common_entry *tt_common_entry; 164 struct batadv_tt_common_entry *tt_common_entry;
103 struct batadv_tt_global_entry *tt_global_entry = NULL; 165 struct batadv_tt_global_entry *tt_global_entry = NULL;
104 166
105 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data); 167 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr,
168 vid);
106 if (tt_common_entry) 169 if (tt_common_entry)
107 tt_global_entry = container_of(tt_common_entry, 170 tt_global_entry = container_of(tt_common_entry,
108 struct batadv_tt_global_entry, 171 struct batadv_tt_global_entry,
@@ -178,6 +241,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
178 tt_change_node->change.flags = flags; 241 tt_change_node->change.flags = flags;
179 tt_change_node->change.reserved = 0; 242 tt_change_node->change.reserved = 0;
180 memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN); 243 memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
244 tt_change_node->change.vid = htons(common->vid);
181 245
182 del_op_requested = flags & BATADV_TT_CLIENT_DEL; 246 del_op_requested = flags & BATADV_TT_CLIENT_DEL;
183 247
@@ -268,12 +332,21 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv,
268 tt_global->common.addr, message); 332 tt_global->common.addr, message);
269 333
270 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt, 334 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
271 batadv_choose_orig, tt_global->common.addr); 335 batadv_choose_tt, &tt_global->common);
272 batadv_tt_global_entry_free_ref(tt_global); 336 batadv_tt_global_entry_free_ref(tt_global);
273} 337}
274 338
339/**
340 * batadv_tt_local_add - add a new client to the local table or update an
341 * existing client
342 * @soft_iface: netdev struct of the mesh interface
343 * @addr: the mac address of the client to add
344 * @vid: VLAN identifier
345 * @ifindex: index of the interface where the client is connected to (useful to
346 * identify wireless clients)
347 */
275void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 348void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
276 int ifindex) 349 unsigned short vid, int ifindex)
277{ 350{
278 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 351 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
279 struct batadv_tt_local_entry *tt_local; 352 struct batadv_tt_local_entry *tt_local;
@@ -283,8 +356,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
283 int hash_added; 356 int hash_added;
284 bool roamed_back = false; 357 bool roamed_back = false;
285 358
286 tt_local = batadv_tt_local_hash_find(bat_priv, addr); 359 tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
287 tt_global = batadv_tt_global_hash_find(bat_priv, addr); 360 tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
288 361
289 if (tt_local) { 362 if (tt_local) {
290 tt_local->last_seen = jiffies; 363 tt_local->last_seen = jiffies;
@@ -329,6 +402,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
329 * (consistency check) 402 * (consistency check)
330 */ 403 */
331 tt_local->common.flags = BATADV_TT_CLIENT_NEW; 404 tt_local->common.flags = BATADV_TT_CLIENT_NEW;
405 tt_local->common.vid = vid;
332 if (batadv_is_wifi_iface(ifindex)) 406 if (batadv_is_wifi_iface(ifindex))
333 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; 407 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
334 atomic_set(&tt_local->common.refcount, 2); 408 atomic_set(&tt_local->common.refcount, 2);
@@ -340,7 +414,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
340 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE; 414 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
341 415
342 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt, 416 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
343 batadv_choose_orig, &tt_local->common, 417 batadv_choose_tt, &tt_local->common,
344 &tt_local->common.hash_entry); 418 &tt_local->common.hash_entry);
345 419
346 if (unlikely(hash_added != 0)) { 420 if (unlikely(hash_added != 0)) {
@@ -362,6 +436,7 @@ check_roaming:
362 rcu_read_lock(); 436 rcu_read_lock();
363 hlist_for_each_entry_rcu(orig_entry, head, list) { 437 hlist_for_each_entry_rcu(orig_entry, head, list) {
364 batadv_send_roam_adv(bat_priv, tt_global->common.addr, 438 batadv_send_roam_adv(bat_priv, tt_global->common.addr,
439 tt_global->common.vid,
365 orig_entry->orig_node); 440 orig_entry->orig_node);
366 } 441 }
367 rcu_read_unlock(); 442 rcu_read_unlock();
@@ -550,19 +625,20 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
550 * batadv_tt_local_remove - logically remove an entry from the local table 625 * batadv_tt_local_remove - logically remove an entry from the local table
551 * @bat_priv: the bat priv with all the soft interface information 626 * @bat_priv: the bat priv with all the soft interface information
552 * @addr: the MAC address of the client to remove 627 * @addr: the MAC address of the client to remove
628 * @vid: VLAN identifier
553 * @message: message to append to the log on deletion 629 * @message: message to append to the log on deletion
554 * @roaming: true if the deletion is due to a roaming event 630 * @roaming: true if the deletion is due to a roaming event
555 * 631 *
556 * Returns the flags assigned to the local entry before being deleted 632 * Returns the flags assigned to the local entry before being deleted
557 */ 633 */
558uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, 634uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
559 const uint8_t *addr, const char *message, 635 const uint8_t *addr, unsigned short vid,
560 bool roaming) 636 const char *message, bool roaming)
561{ 637{
562 struct batadv_tt_local_entry *tt_local_entry; 638 struct batadv_tt_local_entry *tt_local_entry;
563 uint16_t flags, curr_flags = BATADV_NO_FLAGS; 639 uint16_t flags, curr_flags = BATADV_NO_FLAGS;
564 640
565 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 641 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
566 if (!tt_local_entry) 642 if (!tt_local_entry)
567 goto out; 643 goto out;
568 644
@@ -798,6 +874,7 @@ out:
798 * @bat_priv: the bat priv with all the soft interface information 874 * @bat_priv: the bat priv with all the soft interface information
799 * @orig_node: the originator announcing the client 875 * @orig_node: the originator announcing the client
800 * @tt_addr: the mac address of the non-mesh client 876 * @tt_addr: the mac address of the non-mesh client
877 * @vid: VLAN identifier
801 * @flags: TT flags that have to be set for this non-mesh client 878 * @flags: TT flags that have to be set for this non-mesh client
802 * @ttvn: the tt version number ever announcing this non-mesh client 879 * @ttvn: the tt version number ever announcing this non-mesh client
803 * 880 *
@@ -813,7 +890,8 @@ out:
813 */ 890 */
814static bool batadv_tt_global_add(struct batadv_priv *bat_priv, 891static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
815 struct batadv_orig_node *orig_node, 892 struct batadv_orig_node *orig_node,
816 const unsigned char *tt_addr, uint16_t flags, 893 const unsigned char *tt_addr,
894 unsigned short vid, uint16_t flags,
817 uint8_t ttvn) 895 uint8_t ttvn)
818{ 896{
819 struct batadv_tt_global_entry *tt_global_entry; 897 struct batadv_tt_global_entry *tt_global_entry;
@@ -823,8 +901,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
823 struct batadv_tt_common_entry *common; 901 struct batadv_tt_common_entry *common;
824 uint16_t local_flags; 902 uint16_t local_flags;
825 903
826 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); 904 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr, vid);
827 tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr); 905 tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr, vid);
828 906
829 /* if the node already has a local client for this entry, it has to wait 907 /* if the node already has a local client for this entry, it has to wait
830 * for a roaming advertisement instead of manually messing up the global 908 * for a roaming advertisement instead of manually messing up the global
@@ -841,6 +919,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
841 919
842 common = &tt_global_entry->common; 920 common = &tt_global_entry->common;
843 memcpy(common->addr, tt_addr, ETH_ALEN); 921 memcpy(common->addr, tt_addr, ETH_ALEN);
922 common->vid = vid;
844 923
845 common->flags = flags; 924 common->flags = flags;
846 tt_global_entry->roam_at = 0; 925 tt_global_entry->roam_at = 0;
@@ -858,7 +937,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
858 937
859 hash_added = batadv_hash_add(bat_priv->tt.global_hash, 938 hash_added = batadv_hash_add(bat_priv->tt.global_hash,
860 batadv_compare_tt, 939 batadv_compare_tt,
861 batadv_choose_orig, common, 940 batadv_choose_tt, common,
862 &common->hash_entry); 941 &common->hash_entry);
863 942
864 if (unlikely(hash_added != 0)) { 943 if (unlikely(hash_added != 0)) {
@@ -924,7 +1003,7 @@ add_orig_entry:
924out_remove: 1003out_remove:
925 1004
926 /* remove address from local hash if present */ 1005 /* remove address from local hash if present */
927 local_flags = batadv_tt_local_remove(bat_priv, tt_addr, 1006 local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid,
928 "global tt received", 1007 "global tt received",
929 flags & BATADV_TT_CLIENT_ROAM); 1008 flags & BATADV_TT_CLIENT_ROAM);
930 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; 1009 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
@@ -1147,17 +1226,25 @@ batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
1147 orig_node, message); 1226 orig_node, message);
1148} 1227}
1149 1228
1150 1229/**
1151 1230 * batadv_tt_global_del - remove a client from the global table
1231 * @bat_priv: the bat priv with all the soft interface information
1232 * @orig_node: an originator serving this client
1233 * @addr: the mac address of the client
1234 * @vid: VLAN identifier
1235 * @message: a message explaining the reason for deleting the client to print
1236 * for debugging purpose
1237 * @roaming: true if the deletion has been triggered by a roaming event
1238 */
1152static void batadv_tt_global_del(struct batadv_priv *bat_priv, 1239static void batadv_tt_global_del(struct batadv_priv *bat_priv,
1153 struct batadv_orig_node *orig_node, 1240 struct batadv_orig_node *orig_node,
1154 const unsigned char *addr, 1241 const unsigned char *addr, unsigned short vid,
1155 const char *message, bool roaming) 1242 const char *message, bool roaming)
1156{ 1243{
1157 struct batadv_tt_global_entry *tt_global_entry; 1244 struct batadv_tt_global_entry *tt_global_entry;
1158 struct batadv_tt_local_entry *local_entry = NULL; 1245 struct batadv_tt_local_entry *local_entry = NULL;
1159 1246
1160 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 1247 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
1161 if (!tt_global_entry) 1248 if (!tt_global_entry)
1162 goto out; 1249 goto out;
1163 1250
@@ -1186,7 +1273,8 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
1186 * the global entry, since it is useless now. 1273 * the global entry, since it is useless now.
1187 */ 1274 */
1188 local_entry = batadv_tt_local_hash_find(bat_priv, 1275 local_entry = batadv_tt_local_hash_find(bat_priv,
1189 tt_global_entry->common.addr); 1276 tt_global_entry->common.addr,
1277 vid);
1190 if (local_entry) { 1278 if (local_entry) {
1191 /* local entry exists, case 2: client roamed to us. */ 1279 /* local entry exists, case 2: client roamed to us. */
1192 batadv_tt_global_del_orig_list(tt_global_entry); 1280 batadv_tt_global_del_orig_list(tt_global_entry);
@@ -1354,9 +1442,24 @@ _batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
1354 return ret; 1442 return ret;
1355} 1443}
1356 1444
1445/**
1446 * batadv_transtable_search - get the mesh destination for a given client
1447 * @bat_priv: the bat priv with all the soft interface information
1448 * @src: mac address of the source client
1449 * @addr: mac address of the destination client
1450 * @vid: VLAN identifier
1451 *
1452 * Returns a pointer to the originator that was selected as destination in the
1453 * mesh for contacting the client 'addr', NULL otherwise.
1454 * In case of multiple originators serving the same client, the function returns
1455 * the best one (best in terms of metric towards the destination node).
1456 *
1457 * If the two clients are AP isolated the function returns NULL.
1458 */
1357struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, 1459struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
1358 const uint8_t *src, 1460 const uint8_t *src,
1359 const uint8_t *addr) 1461 const uint8_t *addr,
1462 unsigned short vid)
1360{ 1463{
1361 struct batadv_tt_local_entry *tt_local_entry = NULL; 1464 struct batadv_tt_local_entry *tt_local_entry = NULL;
1362 struct batadv_tt_global_entry *tt_global_entry = NULL; 1465 struct batadv_tt_global_entry *tt_global_entry = NULL;
@@ -1364,13 +1467,13 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
1364 struct batadv_tt_orig_list_entry *best_entry; 1467 struct batadv_tt_orig_list_entry *best_entry;
1365 1468
1366 if (src && atomic_read(&bat_priv->ap_isolation)) { 1469 if (src && atomic_read(&bat_priv->ap_isolation)) {
1367 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src); 1470 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid);
1368 if (!tt_local_entry || 1471 if (!tt_local_entry ||
1369 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)) 1472 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
1370 goto out; 1473 goto out;
1371 } 1474 }
1372 1475
1373 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 1476 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
1374 if (!tt_global_entry) 1477 if (!tt_global_entry)
1375 goto out; 1478 goto out;
1376 1479
@@ -1649,6 +1752,7 @@ batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
1649 memcpy(tt_change->addr, tt_common_entry->addr, 1752 memcpy(tt_change->addr, tt_common_entry->addr,
1650 ETH_ALEN); 1753 ETH_ALEN);
1651 tt_change->flags = tt_common_entry->flags; 1754 tt_change->flags = tt_common_entry->flags;
1755 tt_change->vid = htons(tt_common_entry->vid);
1652 tt_change->reserved = 0; 1756 tt_change->reserved = 0;
1653 1757
1654 tt_num_entries++; 1758 tt_num_entries++;
@@ -1979,11 +2083,13 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
1979 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM; 2083 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
1980 batadv_tt_global_del(bat_priv, orig_node, 2084 batadv_tt_global_del(bat_priv, orig_node,
1981 (tt_change + i)->addr, 2085 (tt_change + i)->addr,
2086 ntohs((tt_change + i)->vid),
1982 "tt removed by changes", 2087 "tt removed by changes",
1983 roams); 2088 roams);
1984 } else { 2089 } else {
1985 if (!batadv_tt_global_add(bat_priv, orig_node, 2090 if (!batadv_tt_global_add(bat_priv, orig_node,
1986 (tt_change + i)->addr, 2091 (tt_change + i)->addr,
2092 ntohs((tt_change + i)->vid),
1987 (tt_change + i)->flags, ttvn)) 2093 (tt_change + i)->flags, ttvn))
1988 /* In case of problem while storing a 2094 /* In case of problem while storing a
1989 * global_entry, we stop the updating 2095 * global_entry, we stop the updating
@@ -2040,12 +2146,21 @@ static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
2040 atomic_set(&orig_node->last_ttvn, ttvn); 2146 atomic_set(&orig_node->last_ttvn, ttvn);
2041} 2147}
2042 2148
2043bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr) 2149/**
2150 * batadv_is_my_client - check if a client is served by the local node
2151 * @bat_priv: the bat priv with all the soft interface information
2152 * @addr: the mac adress of the client to check
2153 * @vid: VLAN identifier
2154 *
2155 * Returns true if the client is served by this node, false otherwise.
2156 */
2157bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
2158 unsigned short vid)
2044{ 2159{
2045 struct batadv_tt_local_entry *tt_local_entry; 2160 struct batadv_tt_local_entry *tt_local_entry;
2046 bool ret = false; 2161 bool ret = false;
2047 2162
2048 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 2163 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
2049 if (!tt_local_entry) 2164 if (!tt_local_entry)
2050 goto out; 2165 goto out;
2051 /* Check if the client has been logically deleted (but is kept for 2166 /* Check if the client has been logically deleted (but is kept for
@@ -2194,7 +2309,20 @@ unlock:
2194 return ret; 2309 return ret;
2195} 2310}
2196 2311
2312/**
2313 * batadv_send_roam_adv - send a roaming advertisement message
2314 * @bat_priv: the bat priv with all the soft interface information
2315 * @client: mac address of the roaming client
2316 * @vid: VLAN identifier
2317 * @orig_node: message destination
2318 *
2319 * Send a ROAMING_ADV message to the node which was previously serving this
2320 * client. This is done to inform the node that from now on all traffic destined
2321 * for this particular roamed client has to be forwarded to the sender of the
2322 * roaming message.
2323 */
2197static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 2324static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
2325 unsigned short vid,
2198 struct batadv_orig_node *orig_node) 2326 struct batadv_orig_node *orig_node)
2199{ 2327{
2200 struct batadv_hard_iface *primary_if; 2328 struct batadv_hard_iface *primary_if;
@@ -2217,7 +2345,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
2217 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX); 2345 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
2218 2346
2219 memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client)); 2347 memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client));
2220 tvlv_roam.reserved = 0; 2348 tvlv_roam.vid = htons(vid);
2221 2349
2222 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, 2350 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
2223 orig_node->orig, BATADV_TVLV_ROAM, 1, 2351 orig_node->orig, BATADV_TVLV_ROAM, 1,
@@ -2383,11 +2511,13 @@ bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
2383 if (!atomic_read(&bat_priv->ap_isolation)) 2511 if (!atomic_read(&bat_priv->ap_isolation))
2384 goto out; 2512 goto out;
2385 2513
2386 tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst); 2514 tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst,
2515 BATADV_NO_FLAGS);
2387 if (!tt_local_entry) 2516 if (!tt_local_entry)
2388 goto out; 2517 goto out;
2389 2518
2390 tt_global_entry = batadv_tt_global_hash_find(bat_priv, src); 2519 tt_global_entry = batadv_tt_global_hash_find(bat_priv, src,
2520 BATADV_NO_FLAGS);
2391 if (!tt_global_entry) 2521 if (!tt_global_entry)
2392 goto out; 2522 goto out;
2393 2523
@@ -2482,17 +2612,23 @@ request_table:
2482 } 2612 }
2483} 2613}
2484 2614
2485/* returns true whether we know that the client has moved from its old 2615/**
2486 * originator to another one. This entry is kept is still kept for consistency 2616 * batadv_tt_global_client_is_roaming - check if a client is marked as roaming
2487 * purposes 2617 * @bat_priv: the bat priv with all the soft interface information
2618 * @addr: the mac address of the client to check
2619 * @vid: VLAN identifier
2620 *
2621 * Returns true if we know that the client has moved from its old originator
2622 * to another one. This entry is still kept for consistency purposes and will be
2623 * deleted later by a DEL or because of timeout
2488 */ 2624 */
2489bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, 2625bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
2490 uint8_t *addr) 2626 uint8_t *addr, unsigned short vid)
2491{ 2627{
2492 struct batadv_tt_global_entry *tt_global_entry; 2628 struct batadv_tt_global_entry *tt_global_entry;
2493 bool ret = false; 2629 bool ret = false;
2494 2630
2495 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 2631 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
2496 if (!tt_global_entry) 2632 if (!tt_global_entry)
2497 goto out; 2633 goto out;
2498 2634
@@ -2505,19 +2641,20 @@ out:
2505/** 2641/**
2506 * batadv_tt_local_client_is_roaming - tells whether the client is roaming 2642 * batadv_tt_local_client_is_roaming - tells whether the client is roaming
2507 * @bat_priv: the bat priv with all the soft interface information 2643 * @bat_priv: the bat priv with all the soft interface information
2508 * @addr: the MAC address of the local client to query 2644 * @addr: the mac address of the local client to query
2645 * @vid: VLAN identifier
2509 * 2646 *
2510 * Returns true if the local client is known to be roaming (it is not served by 2647 * Returns true if the local client is known to be roaming (it is not served by
2511 * this node anymore) or not. If yes, the client is still present in the table 2648 * this node anymore) or not. If yes, the client is still present in the table
2512 * to keep the latter consistent with the node TTVN 2649 * to keep the latter consistent with the node TTVN
2513 */ 2650 */
2514bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, 2651bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
2515 uint8_t *addr) 2652 uint8_t *addr, unsigned short vid)
2516{ 2653{
2517 struct batadv_tt_local_entry *tt_local_entry; 2654 struct batadv_tt_local_entry *tt_local_entry;
2518 bool ret = false; 2655 bool ret = false;
2519 2656
2520 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 2657 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
2521 if (!tt_local_entry) 2658 if (!tt_local_entry)
2522 goto out; 2659 goto out;
2523 2660
@@ -2529,7 +2666,8 @@ out:
2529 2666
2530bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 2667bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
2531 struct batadv_orig_node *orig_node, 2668 struct batadv_orig_node *orig_node,
2532 const unsigned char *addr) 2669 const unsigned char *addr,
2670 unsigned short vlan)
2533{ 2671{
2534 bool ret = false; 2672 bool ret = false;
2535 2673
@@ -2540,7 +2678,7 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
2540 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) 2678 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
2541 goto out; 2679 goto out;
2542 2680
2543 if (!batadv_tt_global_add(bat_priv, orig_node, addr, 2681 if (!batadv_tt_global_add(bat_priv, orig_node, addr, vlan,
2544 BATADV_TT_CLIENT_TEMP, 2682 BATADV_TT_CLIENT_TEMP,
2545 atomic_read(&orig_node->last_ttvn))) 2683 atomic_read(&orig_node->last_ttvn)))
2546 goto out; 2684 goto out;
@@ -2706,7 +2844,7 @@ static int batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
2706 src, roaming_adv->client); 2844 src, roaming_adv->client);
2707 2845
2708 batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client, 2846 batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client,
2709 BATADV_TT_CLIENT_ROAM, 2847 ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM,
2710 atomic_read(&orig_node->last_ttvn) + 1); 2848 atomic_read(&orig_node->last_ttvn) + 1);
2711 2849
2712out: 2850out:
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 015d8b9e63b9..1d9506d85bee 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -22,10 +22,10 @@
22 22
23int batadv_tt_init(struct batadv_priv *bat_priv); 23int batadv_tt_init(struct batadv_priv *bat_priv);
24void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 24void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
25 int ifindex); 25 unsigned short vid, int ifindex);
26uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, 26uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
27 const uint8_t *addr, const char *message, 27 const uint8_t *addr, unsigned short vid,
28 bool roaming); 28 const char *message, bool roaming);
29int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); 29int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset);
30int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset); 30int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
31void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, 31void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
@@ -33,18 +33,21 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
33 const char *message); 33 const char *message);
34struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, 34struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
35 const uint8_t *src, 35 const uint8_t *src,
36 const uint8_t *addr); 36 const uint8_t *addr,
37 unsigned short vid);
37void batadv_tt_free(struct batadv_priv *bat_priv); 38void batadv_tt_free(struct batadv_priv *bat_priv);
38bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr); 39bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
40 unsigned short vid);
39bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, 41bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
40 uint8_t *dst); 42 uint8_t *dst);
41void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv); 43void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv);
42bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, 44bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
43 uint8_t *addr); 45 uint8_t *addr, unsigned short vid);
44bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, 46bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
45 uint8_t *addr); 47 uint8_t *addr, unsigned short vid);
46bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 48bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
47 struct batadv_orig_node *orig_node, 49 struct batadv_orig_node *orig_node,
48 const unsigned char *addr); 50 const unsigned char *addr,
51 unsigned short vid);
49 52
50#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ 53#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 5cbb0d09a9b5..99029c5fadf4 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -715,6 +715,7 @@ struct batadv_bla_claim {
715/** 715/**
716 * struct batadv_tt_common_entry - tt local & tt global common data 716 * struct batadv_tt_common_entry - tt local & tt global common data
717 * @addr: mac address of non-mesh client 717 * @addr: mac address of non-mesh client
718 * @vid: VLAN identifier
718 * @hash_entry: hlist node for batadv_priv_tt::local_hash or for 719 * @hash_entry: hlist node for batadv_priv_tt::local_hash or for
719 * batadv_priv_tt::global_hash 720 * batadv_priv_tt::global_hash
720 * @flags: various state handling flags (see batadv_tt_client_flags) 721 * @flags: various state handling flags (see batadv_tt_client_flags)
@@ -724,6 +725,7 @@ struct batadv_bla_claim {
724 */ 725 */
725struct batadv_tt_common_entry { 726struct batadv_tt_common_entry {
726 uint8_t addr[ETH_ALEN]; 727 uint8_t addr[ETH_ALEN];
728 unsigned short vid;
727 struct hlist_node hash_entry; 729 struct hlist_node hash_entry;
728 uint16_t flags; 730 uint16_t flags;
729 unsigned long added_at; 731 unsigned long added_at;