aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonio Quartulli <antonio@open-mesh.com>2013-06-04 06:11:43 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-19 11:28:07 -0400
commitbe1db4f6615b5e6156c807ea8985171c215c2d57 (patch)
tree7e93ce347b58e6449725354d9b5ccd31da58b567
parentbbb877ed777236669ed14b5957ae72117f3b3129 (diff)
batman-adv: make the Distributed ARP Table vlan aware
The same IP subnet can be used on different VLANs, therefore DAT has to differentiate whether the IP to resolve belongs to one or the other virtual LAN. To accomplish this task DAT has to deal with the VLAN tag and store it together with each ARP entry. Signed-off-by: Antonio Quartulli <antonio@open-mesh.com> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
-rw-r--r--net/batman-adv/distributed-arp-table.c153
-rw-r--r--net/batman-adv/types.h2
2 files changed, 107 insertions, 48 deletions
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 1b590f01f824..47dbe9a53e91 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/if_ether.h> 20#include <linux/if_ether.h>
21#include <linux/if_arp.h> 21#include <linux/if_arp.h>
22#include <linux/if_vlan.h>
22#include <net/arp.h> 23#include <net/arp.h>
23 24
24#include "main.h" 25#include "main.h"
@@ -205,15 +206,11 @@ static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size)
205 */ 206 */
206static uint32_t batadv_hash_dat(const void *data, uint32_t size) 207static uint32_t batadv_hash_dat(const void *data, uint32_t size)
207{ 208{
208 const unsigned char *key = data;
209 uint32_t hash = 0; 209 uint32_t hash = 0;
210 size_t i; 210 const struct batadv_dat_entry *dat = data;
211 211
212 for (i = 0; i < 4; i++) { 212 hash = batadv_hash_bytes(hash, &dat->ip, sizeof(dat->ip));
213 hash += key[i]; 213 hash = batadv_hash_bytes(hash, &dat->vid, sizeof(dat->vid));
214 hash += (hash << 10);
215 hash ^= (hash >> 6);
216 }
217 214
218 hash += (hash << 3); 215 hash += (hash << 3);
219 hash ^= (hash >> 11); 216 hash ^= (hash >> 11);
@@ -227,21 +224,26 @@ static uint32_t batadv_hash_dat(const void *data, uint32_t size)
227 * table 224 * table
228 * @bat_priv: the bat priv with all the soft interface information 225 * @bat_priv: the bat priv with all the soft interface information
229 * @ip: search key 226 * @ip: search key
227 * @vid: VLAN identifier
230 * 228 *
231 * Returns the dat_entry if found, NULL otherwise. 229 * Returns the dat_entry if found, NULL otherwise.
232 */ 230 */
233static struct batadv_dat_entry * 231static struct batadv_dat_entry *
234batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip) 232batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip,
233 unsigned short vid)
235{ 234{
236 struct hlist_head *head; 235 struct hlist_head *head;
237 struct batadv_dat_entry *dat_entry, *dat_entry_tmp = NULL; 236 struct batadv_dat_entry to_find, *dat_entry, *dat_entry_tmp = NULL;
238 struct batadv_hashtable *hash = bat_priv->dat.hash; 237 struct batadv_hashtable *hash = bat_priv->dat.hash;
239 uint32_t index; 238 uint32_t index;
240 239
241 if (!hash) 240 if (!hash)
242 return NULL; 241 return NULL;
243 242
244 index = batadv_hash_dat(&ip, hash->size); 243 to_find.ip = ip;
244 to_find.vid = vid;
245
246 index = batadv_hash_dat(&to_find, hash->size);
245 head = &hash->table[index]; 247 head = &hash->table[index];
246 248
247 rcu_read_lock(); 249 rcu_read_lock();
@@ -265,22 +267,24 @@ batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip)
265 * @bat_priv: the bat priv with all the soft interface information 267 * @bat_priv: the bat priv with all the soft interface information
266 * @ip: ipv4 to add/edit 268 * @ip: ipv4 to add/edit
267 * @mac_addr: mac address to assign to the given ipv4 269 * @mac_addr: mac address to assign to the given ipv4
270 * @vid: VLAN identifier
268 */ 271 */
269static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, 272static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
270 uint8_t *mac_addr) 273 uint8_t *mac_addr, unsigned short vid)
271{ 274{
272 struct batadv_dat_entry *dat_entry; 275 struct batadv_dat_entry *dat_entry;
273 int hash_added; 276 int hash_added;
274 277
275 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip); 278 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip, vid);
276 /* if this entry is already known, just update it */ 279 /* if this entry is already known, just update it */
277 if (dat_entry) { 280 if (dat_entry) {
278 if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr)) 281 if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr))
279 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN); 282 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
280 dat_entry->last_update = jiffies; 283 dat_entry->last_update = jiffies;
281 batadv_dbg(BATADV_DBG_DAT, bat_priv, 284 batadv_dbg(BATADV_DBG_DAT, bat_priv,
282 "Entry updated: %pI4 %pM\n", &dat_entry->ip, 285 "Entry updated: %pI4 %pM (vid: %d)\n",
283 dat_entry->mac_addr); 286 &dat_entry->ip, dat_entry->mac_addr,
287 BATADV_PRINT_VID(vid));
284 goto out; 288 goto out;
285 } 289 }
286 290
@@ -289,12 +293,13 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
289 goto out; 293 goto out;
290 294
291 dat_entry->ip = ip; 295 dat_entry->ip = ip;
296 dat_entry->vid = vid;
292 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN); 297 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
293 dat_entry->last_update = jiffies; 298 dat_entry->last_update = jiffies;
294 atomic_set(&dat_entry->refcount, 2); 299 atomic_set(&dat_entry->refcount, 2);
295 300
296 hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat, 301 hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat,
297 batadv_hash_dat, &dat_entry->ip, 302 batadv_hash_dat, dat_entry,
298 &dat_entry->hash_entry); 303 &dat_entry->hash_entry);
299 304
300 if (unlikely(hash_added != 0)) { 305 if (unlikely(hash_added != 0)) {
@@ -303,8 +308,8 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
303 goto out; 308 goto out;
304 } 309 }
305 310
306 batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM\n", 311 batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM (vid: %d)\n",
307 &dat_entry->ip, dat_entry->mac_addr); 312 &dat_entry->ip, dat_entry->mac_addr, BATADV_PRINT_VID(vid));
308 313
309out: 314out:
310 if (dat_entry) 315 if (dat_entry)
@@ -756,8 +761,8 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
756 goto out; 761 goto out;
757 762
758 seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name); 763 seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name);
759 seq_printf(seq, " %-7s %-13s %5s\n", "IPv4", "MAC", 764 seq_printf(seq, " %-7s %-9s %4s %11s\n", "IPv4",
760 "last-seen"); 765 "MAC", "VID", "last-seen");
761 766
762 for (i = 0; i < hash->size; i++) { 767 for (i = 0; i < hash->size; i++) {
763 head = &hash->table[i]; 768 head = &hash->table[i];
@@ -770,8 +775,9 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
770 last_seen_msecs = last_seen_msecs % 60000; 775 last_seen_msecs = last_seen_msecs % 60000;
771 last_seen_secs = last_seen_msecs / 1000; 776 last_seen_secs = last_seen_msecs / 1000;
772 777
773 seq_printf(seq, " * %15pI4 %14pM %6i:%02i\n", 778 seq_printf(seq, " * %15pI4 %14pM %4i %6i:%02i\n",
774 &dat_entry->ip, dat_entry->mac_addr, 779 &dat_entry->ip, dat_entry->mac_addr,
780 BATADV_PRINT_VID(dat_entry->vid),
775 last_seen_mins, last_seen_secs); 781 last_seen_mins, last_seen_secs);
776 } 782 }
777 rcu_read_unlock(); 783 rcu_read_unlock();
@@ -858,6 +864,31 @@ out:
858} 864}
859 865
860/** 866/**
867 * batadv_dat_get_vid - extract the VLAN identifier from skb if any
868 * @skb: the buffer containing the packet to extract the VID from
869 * @hdr_size: the size of the batman-adv header encapsulating the packet
870 *
871 * If the packet embedded in the skb is vlan tagged this function returns the
872 * VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS is returned.
873 */
874static unsigned short batadv_dat_get_vid(struct sk_buff *skb, int *hdr_size)
875{
876 unsigned short vid;
877
878 vid = batadv_get_vid(skb, *hdr_size);
879
880 /* ARP parsing functions jump forward of hdr_size + ETH_HLEN.
881 * If the header contained in the packet is a VLAN one (which is longer)
882 * hdr_size is updated so that the functions will still skip the
883 * correct amount of bytes.
884 */
885 if (vid & BATADV_VLAN_HAS_TAG)
886 *hdr_size += VLAN_HLEN;
887
888 return vid;
889}
890
891/**
861 * batadv_dat_snoop_outgoing_arp_request - snoop the ARP request and try to 892 * batadv_dat_snoop_outgoing_arp_request - snoop the ARP request and try to
862 * answer using DAT 893 * answer using DAT
863 * @bat_priv: the bat priv with all the soft interface information 894 * @bat_priv: the bat priv with all the soft interface information
@@ -876,26 +907,31 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
876 bool ret = false; 907 bool ret = false;
877 struct batadv_dat_entry *dat_entry = NULL; 908 struct batadv_dat_entry *dat_entry = NULL;
878 struct sk_buff *skb_new; 909 struct sk_buff *skb_new;
910 int hdr_size = 0;
911 unsigned short vid;
879 912
880 if (!atomic_read(&bat_priv->distributed_arp_table)) 913 if (!atomic_read(&bat_priv->distributed_arp_table))
881 goto out; 914 goto out;
882 915
883 type = batadv_arp_get_type(bat_priv, skb, 0); 916 vid = batadv_dat_get_vid(skb, &hdr_size);
917
918 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
884 /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast 919 /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast
885 * message to the selected DHT candidates 920 * message to the selected DHT candidates
886 */ 921 */
887 if (type != ARPOP_REQUEST) 922 if (type != ARPOP_REQUEST)
888 goto out; 923 goto out;
889 924
890 batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REQUEST"); 925 batadv_dbg_arp(bat_priv, skb, type, hdr_size,
926 "Parsing outgoing ARP REQUEST");
891 927
892 ip_src = batadv_arp_ip_src(skb, 0); 928 ip_src = batadv_arp_ip_src(skb, hdr_size);
893 hw_src = batadv_arp_hw_src(skb, 0); 929 hw_src = batadv_arp_hw_src(skb, hdr_size);
894 ip_dst = batadv_arp_ip_dst(skb, 0); 930 ip_dst = batadv_arp_ip_dst(skb, hdr_size);
895 931
896 batadv_dat_entry_add(bat_priv, ip_src, hw_src); 932 batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
897 933
898 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); 934 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
899 if (dat_entry) { 935 if (dat_entry) {
900 /* If the ARP request is destined for a local client the local 936 /* If the ARP request is destined for a local client the local
901 * client will answer itself. DAT would only generate a 937 * client will answer itself. DAT would only generate a
@@ -917,11 +953,15 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
917 if (!skb_new) 953 if (!skb_new)
918 goto out; 954 goto out;
919 955
956 if (vid & BATADV_VLAN_HAS_TAG)
957 skb_new = vlan_insert_tag(skb_new, htons(ETH_P_8021Q),
958 vid & VLAN_VID_MASK);
959
920 skb_reset_mac_header(skb_new); 960 skb_reset_mac_header(skb_new);
921 skb_new->protocol = eth_type_trans(skb_new, 961 skb_new->protocol = eth_type_trans(skb_new,
922 bat_priv->soft_iface); 962 bat_priv->soft_iface);
923 bat_priv->stats.rx_packets++; 963 bat_priv->stats.rx_packets++;
924 bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; 964 bat_priv->stats.rx_bytes += skb->len + ETH_HLEN + hdr_size;
925 bat_priv->soft_iface->last_rx = jiffies; 965 bat_priv->soft_iface->last_rx = jiffies;
926 966
927 netif_rx(skb_new); 967 netif_rx(skb_new);
@@ -956,11 +996,14 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
956 struct sk_buff *skb_new; 996 struct sk_buff *skb_new;
957 struct batadv_dat_entry *dat_entry = NULL; 997 struct batadv_dat_entry *dat_entry = NULL;
958 bool ret = false; 998 bool ret = false;
999 unsigned short vid;
959 int err; 1000 int err;
960 1001
961 if (!atomic_read(&bat_priv->distributed_arp_table)) 1002 if (!atomic_read(&bat_priv->distributed_arp_table))
962 goto out; 1003 goto out;
963 1004
1005 vid = batadv_dat_get_vid(skb, &hdr_size);
1006
964 type = batadv_arp_get_type(bat_priv, skb, hdr_size); 1007 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
965 if (type != ARPOP_REQUEST) 1008 if (type != ARPOP_REQUEST)
966 goto out; 1009 goto out;
@@ -972,9 +1015,9 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
972 batadv_dbg_arp(bat_priv, skb, type, hdr_size, 1015 batadv_dbg_arp(bat_priv, skb, type, hdr_size,
973 "Parsing incoming ARP REQUEST"); 1016 "Parsing incoming ARP REQUEST");
974 1017
975 batadv_dat_entry_add(bat_priv, ip_src, hw_src); 1018 batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
976 1019
977 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); 1020 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
978 if (!dat_entry) 1021 if (!dat_entry)
979 goto out; 1022 goto out;
980 1023
@@ -985,6 +1028,10 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
985 if (!skb_new) 1028 if (!skb_new)
986 goto out; 1029 goto out;
987 1030
1031 if (vid & BATADV_VLAN_HAS_TAG)
1032 skb_new = vlan_insert_tag(skb_new, htons(ETH_P_8021Q),
1033 vid & VLAN_VID_MASK);
1034
988 /* To preserve backwards compatibility, the node has choose the outgoing 1035 /* To preserve backwards compatibility, the node has choose the outgoing
989 * format based on the incoming request packet type. The assumption is 1036 * format based on the incoming request packet type. The assumption is
990 * that a node not using the 4addr packet format doesn't support it. 1037 * that a node not using the 4addr packet format doesn't support it.
@@ -992,10 +1039,9 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
992 if (hdr_size == sizeof(struct batadv_unicast_4addr_packet)) 1039 if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
993 err = batadv_send_skb_unicast_4addr(bat_priv, skb_new, 1040 err = batadv_send_skb_unicast_4addr(bat_priv, skb_new,
994 BATADV_P_DAT_CACHE_REPLY, 1041 BATADV_P_DAT_CACHE_REPLY,
995 BATADV_NO_FLAGS); 1042 vid);
996 else 1043 else
997 err = batadv_send_skb_unicast(bat_priv, skb_new, 1044 err = batadv_send_skb_unicast(bat_priv, skb_new, vid);
998 BATADV_NO_FLAGS);
999 1045
1000 if (!err) { 1046 if (!err) {
1001 batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX); 1047 batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX);
@@ -1020,23 +1066,28 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
1020 uint16_t type; 1066 uint16_t type;
1021 __be32 ip_src, ip_dst; 1067 __be32 ip_src, ip_dst;
1022 uint8_t *hw_src, *hw_dst; 1068 uint8_t *hw_src, *hw_dst;
1069 int hdr_size = 0;
1070 unsigned short vid;
1023 1071
1024 if (!atomic_read(&bat_priv->distributed_arp_table)) 1072 if (!atomic_read(&bat_priv->distributed_arp_table))
1025 return; 1073 return;
1026 1074
1027 type = batadv_arp_get_type(bat_priv, skb, 0); 1075 vid = batadv_dat_get_vid(skb, &hdr_size);
1076
1077 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
1028 if (type != ARPOP_REPLY) 1078 if (type != ARPOP_REPLY)
1029 return; 1079 return;
1030 1080
1031 batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REPLY"); 1081 batadv_dbg_arp(bat_priv, skb, type, hdr_size,
1082 "Parsing outgoing ARP REPLY");
1032 1083
1033 hw_src = batadv_arp_hw_src(skb, 0); 1084 hw_src = batadv_arp_hw_src(skb, hdr_size);
1034 ip_src = batadv_arp_ip_src(skb, 0); 1085 ip_src = batadv_arp_ip_src(skb, hdr_size);
1035 hw_dst = batadv_arp_hw_dst(skb, 0); 1086 hw_dst = batadv_arp_hw_dst(skb, hdr_size);
1036 ip_dst = batadv_arp_ip_dst(skb, 0); 1087 ip_dst = batadv_arp_ip_dst(skb, hdr_size);
1037 1088
1038 batadv_dat_entry_add(bat_priv, ip_src, hw_src); 1089 batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
1039 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst); 1090 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
1040 1091
1041 /* Send the ARP reply to the candidates for both the IP addresses that 1092 /* Send the ARP reply to the candidates for both the IP addresses that
1042 * the node obtained from the ARP reply 1093 * the node obtained from the ARP reply
@@ -1058,10 +1109,13 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
1058 __be32 ip_src, ip_dst; 1109 __be32 ip_src, ip_dst;
1059 uint8_t *hw_src, *hw_dst; 1110 uint8_t *hw_src, *hw_dst;
1060 bool ret = false; 1111 bool ret = false;
1112 unsigned short vid;
1061 1113
1062 if (!atomic_read(&bat_priv->distributed_arp_table)) 1114 if (!atomic_read(&bat_priv->distributed_arp_table))
1063 goto out; 1115 goto out;
1064 1116
1117 vid = batadv_dat_get_vid(skb, &hdr_size);
1118
1065 type = batadv_arp_get_type(bat_priv, skb, hdr_size); 1119 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
1066 if (type != ARPOP_REPLY) 1120 if (type != ARPOP_REPLY)
1067 goto out; 1121 goto out;
@@ -1077,13 +1131,13 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
1077 /* Update our internal cache with both the IP addresses the node got 1131 /* Update our internal cache with both the IP addresses the node got
1078 * within the ARP reply 1132 * within the ARP reply
1079 */ 1133 */
1080 batadv_dat_entry_add(bat_priv, ip_src, hw_src); 1134 batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
1081 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst); 1135 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
1082 1136
1083 /* if this REPLY is directed to a client of mine, let's deliver the 1137 /* if this REPLY is directed to a client of mine, let's deliver the
1084 * packet to the interface 1138 * packet to the interface
1085 */ 1139 */
1086 ret = !batadv_is_my_client(bat_priv, hw_dst, BATADV_NO_FLAGS); 1140 ret = !batadv_is_my_client(bat_priv, hw_dst, vid);
1087out: 1141out:
1088 if (ret) 1142 if (ret)
1089 kfree_skb(skb); 1143 kfree_skb(skb);
@@ -1106,7 +1160,8 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
1106 __be32 ip_dst; 1160 __be32 ip_dst;
1107 struct batadv_dat_entry *dat_entry = NULL; 1161 struct batadv_dat_entry *dat_entry = NULL;
1108 bool ret = false; 1162 bool ret = false;
1109 const size_t bcast_len = sizeof(struct batadv_bcast_packet); 1163 int hdr_size = sizeof(struct batadv_bcast_packet);
1164 unsigned short vid;
1110 1165
1111 if (!atomic_read(&bat_priv->distributed_arp_table)) 1166 if (!atomic_read(&bat_priv->distributed_arp_table))
1112 goto out; 1167 goto out;
@@ -1117,12 +1172,14 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
1117 if (forw_packet->num_packets) 1172 if (forw_packet->num_packets)
1118 goto out; 1173 goto out;
1119 1174
1120 type = batadv_arp_get_type(bat_priv, forw_packet->skb, bcast_len); 1175 vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size);
1176
1177 type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size);
1121 if (type != ARPOP_REQUEST) 1178 if (type != ARPOP_REQUEST)
1122 goto out; 1179 goto out;
1123 1180
1124 ip_dst = batadv_arp_ip_dst(forw_packet->skb, bcast_len); 1181 ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size);
1125 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); 1182 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
1126 /* check if the node already got this entry */ 1183 /* check if the node already got this entry */
1127 if (!dat_entry) { 1184 if (!dat_entry) {
1128 batadv_dbg(BATADV_DBG_DAT, bat_priv, 1185 batadv_dbg(BATADV_DBG_DAT, bat_priv,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 99029c5fadf4..6954a5d5a9e9 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -933,6 +933,7 @@ struct batadv_algo_ops {
933 * is used to stored ARP entries needed for the global DAT cache 933 * is used to stored ARP entries needed for the global DAT cache
934 * @ip: the IPv4 corresponding to this DAT/ARP entry 934 * @ip: the IPv4 corresponding to this DAT/ARP entry
935 * @mac_addr: the MAC address associated to the stored IPv4 935 * @mac_addr: the MAC address associated to the stored IPv4
936 * @vid: the vlan ID associated to this entry
936 * @last_update: time in jiffies when this entry was refreshed last time 937 * @last_update: time in jiffies when this entry was refreshed last time
937 * @hash_entry: hlist node for batadv_priv_dat::hash 938 * @hash_entry: hlist node for batadv_priv_dat::hash
938 * @refcount: number of contexts the object is used 939 * @refcount: number of contexts the object is used
@@ -941,6 +942,7 @@ struct batadv_algo_ops {
941struct batadv_dat_entry { 942struct batadv_dat_entry {
942 __be32 ip; 943 __be32 ip;
943 uint8_t mac_addr[ETH_ALEN]; 944 uint8_t mac_addr[ETH_ALEN];
945 unsigned short vid;
944 unsigned long last_update; 946 unsigned long last_update;
945 struct hlist_node hash_entry; 947 struct hlist_node hash_entry;
946 atomic_t refcount; 948 atomic_t refcount;