diff options
author | Antonio Quartulli <antonio@open-mesh.com> | 2013-06-04 06:11:39 -0400 |
---|---|---|
committer | Antonio Quartulli <antonio@meshcoding.com> | 2013-10-19 09:11:21 -0400 |
commit | c018ad3de61a1dc4194879a53e5559e094aa7b1a (patch) | |
tree | 4edb9c156b618dae46d38249a5c817e0d1f1e2b0 /net | |
parent | bc58eeef744df93e141678ef44452f0869cd563d (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.c | 35 | ||||
-rw-r--r-- | net/batman-adv/distributed-arp-table.c | 11 | ||||
-rw-r--r-- | net/batman-adv/gateway_client.c | 3 | ||||
-rw-r--r-- | net/batman-adv/main.c | 29 | ||||
-rw-r--r-- | net/batman-adv/main.h | 9 | ||||
-rw-r--r-- | net/batman-adv/packet.h | 14 | ||||
-rw-r--r-- | net/batman-adv/routing.c | 26 | ||||
-rw-r--r-- | net/batman-adv/send.c | 8 | ||||
-rw-r--r-- | net/batman-adv/send.h | 16 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.c | 35 | ||||
-rw-r--r-- | net/batman-adv/translation-table.c | 240 | ||||
-rw-r--r-- | net/batman-adv/translation-table.h | 19 | ||||
-rw-r--r-- | net/batman-adv/types.h | 2 |
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) | |||
1365 | int batadv_bla_is_backbone_gw(struct sk_buff *skb, | 1363 | int 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); |
1084 | out: | 1087 | out: |
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 | */ | ||
1155 | unsigned 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 | |||
1147 | static int batadv_param_set_ra(const char *val, const struct kernel_param *kp) | 1174 | static 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 | */ | ||
176 | enum 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, | |||
368 | void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src, | 360 | void 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); |
363 | unsigned 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 | */ | ||
129 | enum 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 */ |
126 | enum batadv_bla_claimframe { | 134 | enum 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 | */ |
403 | struct batadv_tvlv_tt_change { | 412 | struct 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 | */ |
414 | struct batadv_tvlv_roam_adv { | 424 | struct 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 | |||
33 | static int batadv_route_unicast_packet(struct sk_buff *skb, | 35 | static 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: | |||
734 | static bool | 737 | static bool |
735 | batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, | 738 | batadv_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 | ||
776 | static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | 780 | static 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 | */ |
246 | int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv, | 247 | int 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); |
41 | int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv, | 41 | int 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 | */ |
53 | static inline int batadv_send_skb_unicast(struct batadv_priv *bat_priv, | 54 | static 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 | */ |
69 | static inline int batadv_send_skb_unicast_4addr(struct batadv_priv *bat_priv, | 72 | static 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) | |||
152 | static int batadv_interface_tx(struct sk_buff *skb, | 153 | static 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; | |||
34 | static struct lock_class_key batadv_tt_global_hash_lock_class_key; | 34 | static struct lock_class_key batadv_tt_global_hash_lock_class_key; |
35 | 35 | ||
36 | static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, | 36 | static 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); |
38 | static void batadv_tt_purge(struct work_struct *work); | 39 | static void batadv_tt_purge(struct work_struct *work); |
39 | static void | 40 | static void |
@@ -41,7 +42,8 @@ batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry); | |||
41 | static void batadv_tt_global_del(struct batadv_priv *bat_priv, | 42 | static 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 */ |
47 | static int batadv_compare_tt(const struct hlist_node *node, const void *data2) | 49 | static 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 | */ | ||
65 | static 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 | */ | ||
55 | static struct batadv_tt_common_entry * | 90 | static struct batadv_tt_common_entry * |
56 | batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data) | 91 | batadv_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 | */ | ||
85 | static struct batadv_tt_local_entry * | 135 | static struct batadv_tt_local_entry * |
86 | batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data) | 136 | batadv_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 | */ | ||
99 | static struct batadv_tt_global_entry * | 160 | static struct batadv_tt_global_entry * |
100 | batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data) | 161 | batadv_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 | */ | ||
275 | void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, | 348 | void 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 | */ |
558 | uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, | 634 | uint16_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 | */ |
814 | static bool batadv_tt_global_add(struct batadv_priv *bat_priv, | 891 | static 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: | |||
924 | out_remove: | 1003 | out_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 | */ | ||
1152 | static void batadv_tt_global_del(struct batadv_priv *bat_priv, | 1239 | static 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 | */ | ||
1357 | struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, | 1459 | struct 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 | ||
2043 | bool 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 | */ | ||
2157 | bool 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 | */ | ||
2197 | static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, | 2324 | static 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 | */ |
2489 | bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, | 2625 | bool 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 | */ |
2514 | bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, | 2651 | bool 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 | ||
2530 | bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, | 2667 | bool 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 | ||
2712 | out: | 2850 | out: |
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 | ||
23 | int batadv_tt_init(struct batadv_priv *bat_priv); | 23 | int batadv_tt_init(struct batadv_priv *bat_priv); |
24 | void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, | 24 | void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, |
25 | int ifindex); | 25 | unsigned short vid, int ifindex); |
26 | uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, | 26 | uint16_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); |
29 | int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); | 29 | int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); |
30 | int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset); | 30 | int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset); |
31 | void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, | 31 | void 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); |
34 | struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, | 34 | struct 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); | ||
37 | void batadv_tt_free(struct batadv_priv *bat_priv); | 38 | void batadv_tt_free(struct batadv_priv *bat_priv); |
38 | bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr); | 39 | bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr, |
40 | unsigned short vid); | ||
39 | bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, | 41 | bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, |
40 | uint8_t *dst); | 42 | uint8_t *dst); |
41 | void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv); | 43 | void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv); |
42 | bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, | 44 | bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, |
43 | uint8_t *addr); | 45 | uint8_t *addr, unsigned short vid); |
44 | bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, | 46 | bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, |
45 | uint8_t *addr); | 47 | uint8_t *addr, unsigned short vid); |
46 | bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, | 48 | bool 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 | */ |
725 | struct batadv_tt_common_entry { | 726 | struct 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; |