xref: /linux/net/batman-adv/bridge_loop_avoidance.c (revision 4413e16d9d21673bb5048a2e542f1aaa00015c2e)
1 /* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors:
2  *
3  * Simon Wunderlich
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 2 of the GNU General Public
7  * License as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA
18  */
19 
20 #include "main.h"
21 #include "hash.h"
22 #include "hard-interface.h"
23 #include "originator.h"
24 #include "bridge_loop_avoidance.h"
25 #include "translation-table.h"
26 #include "send.h"
27 
28 #include <linux/etherdevice.h>
29 #include <linux/crc16.h>
30 #include <linux/if_arp.h>
31 #include <net/arp.h>
32 #include <linux/if_vlan.h>
33 
34 static const uint8_t batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05};
35 
36 static void batadv_bla_periodic_work(struct work_struct *work);
37 static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
38 				     struct batadv_backbone_gw *backbone_gw);
39 
40 /* return the index of the claim */
41 static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
42 {
43 	const unsigned char *key = data;
44 	uint32_t hash = 0;
45 	size_t i;
46 
47 	for (i = 0; i < ETH_ALEN + sizeof(short); i++) {
48 		hash += key[i];
49 		hash += (hash << 10);
50 		hash ^= (hash >> 6);
51 	}
52 
53 	hash += (hash << 3);
54 	hash ^= (hash >> 11);
55 	hash += (hash << 15);
56 
57 	return hash % size;
58 }
59 
60 /* return the index of the backbone gateway */
61 static inline uint32_t batadv_choose_backbone_gw(const void *data,
62 						 uint32_t size)
63 {
64 	const unsigned char *key = data;
65 	uint32_t hash = 0;
66 	size_t i;
67 
68 	for (i = 0; i < ETH_ALEN + sizeof(short); i++) {
69 		hash += key[i];
70 		hash += (hash << 10);
71 		hash ^= (hash >> 6);
72 	}
73 
74 	hash += (hash << 3);
75 	hash ^= (hash >> 11);
76 	hash += (hash << 15);
77 
78 	return hash % size;
79 }
80 
81 
82 /* compares address and vid of two backbone gws */
83 static int batadv_compare_backbone_gw(const struct hlist_node *node,
84 				      const void *data2)
85 {
86 	const void *data1 = container_of(node, struct batadv_backbone_gw,
87 					 hash_entry);
88 
89 	return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0);
90 }
91 
92 /* compares address and vid of two claims */
93 static int batadv_compare_claim(const struct hlist_node *node,
94 				const void *data2)
95 {
96 	const void *data1 = container_of(node, struct batadv_claim,
97 					 hash_entry);
98 
99 	return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0);
100 }
101 
102 /* free a backbone gw */
103 static void batadv_backbone_gw_free_ref(struct batadv_backbone_gw *backbone_gw)
104 {
105 	if (atomic_dec_and_test(&backbone_gw->refcount))
106 		kfree_rcu(backbone_gw, rcu);
107 }
108 
109 /* finally deinitialize the claim */
110 static void batadv_claim_free_rcu(struct rcu_head *rcu)
111 {
112 	struct batadv_claim *claim;
113 
114 	claim = container_of(rcu, struct batadv_claim, rcu);
115 
116 	batadv_backbone_gw_free_ref(claim->backbone_gw);
117 	kfree(claim);
118 }
119 
120 /* free a claim, call claim_free_rcu if its the last reference */
121 static void batadv_claim_free_ref(struct batadv_claim *claim)
122 {
123 	if (atomic_dec_and_test(&claim->refcount))
124 		call_rcu(&claim->rcu, batadv_claim_free_rcu);
125 }
126 
127 /* @bat_priv: the bat priv with all the soft interface information
128  * @data: search data (may be local/static data)
129  *
130  * looks for a claim in the hash, and returns it if found
131  * or NULL otherwise.
132  */
133 static struct batadv_claim *batadv_claim_hash_find(struct batadv_priv *bat_priv,
134 						   struct batadv_claim *data)
135 {
136 	struct batadv_hashtable *hash = bat_priv->claim_hash;
137 	struct hlist_head *head;
138 	struct hlist_node *node;
139 	struct batadv_claim *claim;
140 	struct batadv_claim *claim_tmp = NULL;
141 	int index;
142 
143 	if (!hash)
144 		return NULL;
145 
146 	index = batadv_choose_claim(data, hash->size);
147 	head = &hash->table[index];
148 
149 	rcu_read_lock();
150 	hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
151 		if (!batadv_compare_claim(&claim->hash_entry, data))
152 			continue;
153 
154 		if (!atomic_inc_not_zero(&claim->refcount))
155 			continue;
156 
157 		claim_tmp = claim;
158 		break;
159 	}
160 	rcu_read_unlock();
161 
162 	return claim_tmp;
163 }
164 
165 /**
166  * batadv_backbone_hash_find - looks for a claim in the hash
167  * @bat_priv: the bat priv with all the soft interface information
168  * @addr: the address of the originator
169  * @vid: the VLAN ID
170  *
171  * Returns claim if found or NULL otherwise.
172  */
173 static struct batadv_backbone_gw *
174 batadv_backbone_hash_find(struct batadv_priv *bat_priv,
175 			  uint8_t *addr, short vid)
176 {
177 	struct batadv_hashtable *hash = bat_priv->backbone_hash;
178 	struct hlist_head *head;
179 	struct hlist_node *node;
180 	struct batadv_backbone_gw search_entry, *backbone_gw;
181 	struct batadv_backbone_gw *backbone_gw_tmp = NULL;
182 	int index;
183 
184 	if (!hash)
185 		return NULL;
186 
187 	memcpy(search_entry.orig, addr, ETH_ALEN);
188 	search_entry.vid = vid;
189 
190 	index = batadv_choose_backbone_gw(&search_entry, hash->size);
191 	head = &hash->table[index];
192 
193 	rcu_read_lock();
194 	hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
195 		if (!batadv_compare_backbone_gw(&backbone_gw->hash_entry,
196 						&search_entry))
197 			continue;
198 
199 		if (!atomic_inc_not_zero(&backbone_gw->refcount))
200 			continue;
201 
202 		backbone_gw_tmp = backbone_gw;
203 		break;
204 	}
205 	rcu_read_unlock();
206 
207 	return backbone_gw_tmp;
208 }
209 
210 /* delete all claims for a backbone */
211 static void
212 batadv_bla_del_backbone_claims(struct batadv_backbone_gw *backbone_gw)
213 {
214 	struct batadv_hashtable *hash;
215 	struct hlist_node *node, *node_tmp;
216 	struct hlist_head *head;
217 	struct batadv_claim *claim;
218 	int i;
219 	spinlock_t *list_lock;	/* protects write access to the hash lists */
220 
221 	hash = backbone_gw->bat_priv->claim_hash;
222 	if (!hash)
223 		return;
224 
225 	for (i = 0; i < hash->size; i++) {
226 		head = &hash->table[i];
227 		list_lock = &hash->list_locks[i];
228 
229 		spin_lock_bh(list_lock);
230 		hlist_for_each_entry_safe(claim, node, node_tmp,
231 					  head, hash_entry) {
232 
233 			if (claim->backbone_gw != backbone_gw)
234 				continue;
235 
236 			batadv_claim_free_ref(claim);
237 			hlist_del_rcu(node);
238 		}
239 		spin_unlock_bh(list_lock);
240 	}
241 
242 	/* all claims gone, intialize CRC */
243 	backbone_gw->crc = BATADV_BLA_CRC_INIT;
244 }
245 
246 /**
247  * batadv_bla_send_claim - sends a claim frame according to the provided info
248  * @bat_priv: the bat priv with all the soft interface information
249  * @orig: the mac address to be announced within the claim
250  * @vid: the VLAN ID
251  * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...)
252  */
253 static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
254 				  short vid, int claimtype)
255 {
256 	struct sk_buff *skb;
257 	struct ethhdr *ethhdr;
258 	struct batadv_hard_iface *primary_if;
259 	struct net_device *soft_iface;
260 	uint8_t *hw_src;
261 	struct batadv_bla_claim_dst local_claim_dest;
262 	__be32 zeroip = 0;
263 
264 	primary_if = batadv_primary_if_get_selected(bat_priv);
265 	if (!primary_if)
266 		return;
267 
268 	memcpy(&local_claim_dest, &bat_priv->claim_dest,
269 	       sizeof(local_claim_dest));
270 	local_claim_dest.type = claimtype;
271 
272 	soft_iface = primary_if->soft_iface;
273 
274 	skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
275 			 /* IP DST: 0.0.0.0 */
276 			 zeroip,
277 			 primary_if->soft_iface,
278 			 /* IP SRC: 0.0.0.0 */
279 			 zeroip,
280 			 /* Ethernet DST: Broadcast */
281 			 NULL,
282 			 /* Ethernet SRC/HW SRC:  originator mac */
283 			 primary_if->net_dev->dev_addr,
284 			 /* HW DST: FF:43:05:XX:00:00
285 			  * with XX   = claim type
286 			  * and YY:YY = group id
287 			  */
288 			 (uint8_t *)&local_claim_dest);
289 
290 	if (!skb)
291 		goto out;
292 
293 	ethhdr = (struct ethhdr *)skb->data;
294 	hw_src = (uint8_t *)ethhdr + ETH_HLEN + sizeof(struct arphdr);
295 
296 	/* now we pretend that the client would have sent this ... */
297 	switch (claimtype) {
298 	case BATADV_CLAIM_TYPE_ADD:
299 		/* normal claim frame
300 		 * set Ethernet SRC to the clients mac
301 		 */
302 		memcpy(ethhdr->h_source, mac, ETH_ALEN);
303 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
304 			   "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid);
305 		break;
306 	case BATADV_CLAIM_TYPE_DEL:
307 		/* unclaim frame
308 		 * set HW SRC to the clients mac
309 		 */
310 		memcpy(hw_src, mac, ETH_ALEN);
311 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
312 			   "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac,
313 			   vid);
314 		break;
315 	case BATADV_CLAIM_TYPE_ANNOUNCE:
316 		/* announcement frame
317 		 * set HW SRC to the special mac containg the crc
318 		 */
319 		memcpy(hw_src, mac, ETH_ALEN);
320 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
321 			   "bla_send_claim(): ANNOUNCE of %pM on vid %d\n",
322 			   ethhdr->h_source, vid);
323 		break;
324 	case BATADV_CLAIM_TYPE_REQUEST:
325 		/* request frame
326 		 * set HW SRC to the special mac containg the crc
327 		 */
328 		memcpy(hw_src, mac, ETH_ALEN);
329 		memcpy(ethhdr->h_dest, mac, ETH_ALEN);
330 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
331 			   "bla_send_claim(): REQUEST of %pM to %pMon vid %d\n",
332 			   ethhdr->h_source, ethhdr->h_dest, vid);
333 		break;
334 
335 	}
336 
337 	if (vid != -1)
338 		skb = vlan_insert_tag(skb, vid);
339 
340 	skb_reset_mac_header(skb);
341 	skb->protocol = eth_type_trans(skb, soft_iface);
342 	bat_priv->stats.rx_packets++;
343 	bat_priv->stats.rx_bytes += skb->len + ETH_HLEN;
344 	soft_iface->last_rx = jiffies;
345 
346 	netif_rx(skb);
347 out:
348 	if (primary_if)
349 		batadv_hardif_free_ref(primary_if);
350 }
351 
352 /**
353  * batadv_bla_get_backbone_gw
354  * @bat_priv: the bat priv with all the soft interface information
355  * @orig: the mac address of the originator
356  * @vid: the VLAN ID
357  *
358  * searches for the backbone gw or creates a new one if it could not
359  * be found.
360  */
361 static struct batadv_backbone_gw *
362 batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
363 			   short vid)
364 {
365 	struct batadv_backbone_gw *entry;
366 	struct batadv_orig_node *orig_node;
367 	int hash_added;
368 
369 	entry = batadv_backbone_hash_find(bat_priv, orig, vid);
370 
371 	if (entry)
372 		return entry;
373 
374 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
375 		   "bla_get_backbone_gw(): not found (%pM, %d), creating new entry\n",
376 		   orig, vid);
377 
378 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
379 	if (!entry)
380 		return NULL;
381 
382 	entry->vid = vid;
383 	entry->lasttime = jiffies;
384 	entry->crc = BATADV_BLA_CRC_INIT;
385 	entry->bat_priv = bat_priv;
386 	atomic_set(&entry->request_sent, 0);
387 	memcpy(entry->orig, orig, ETH_ALEN);
388 
389 	/* one for the hash, one for returning */
390 	atomic_set(&entry->refcount, 2);
391 
392 	hash_added = batadv_hash_add(bat_priv->backbone_hash,
393 				     batadv_compare_backbone_gw,
394 				     batadv_choose_backbone_gw, entry,
395 				     &entry->hash_entry);
396 
397 	if (unlikely(hash_added != 0)) {
398 		/* hash failed, free the structure */
399 		kfree(entry);
400 		return NULL;
401 	}
402 
403 	/* this is a gateway now, remove any tt entries */
404 	orig_node = batadv_orig_hash_find(bat_priv, orig);
405 	if (orig_node) {
406 		batadv_tt_global_del_orig(bat_priv, orig_node,
407 					  "became a backbone gateway");
408 		batadv_orig_node_free_ref(orig_node);
409 	}
410 	return entry;
411 }
412 
413 /* update or add the own backbone gw to make sure we announce
414  * where we receive other backbone gws
415  */
416 static void
417 batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,
418 				  struct batadv_hard_iface *primary_if,
419 				  short vid)
420 {
421 	struct batadv_backbone_gw *backbone_gw;
422 
423 	backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
424 						 primary_if->net_dev->dev_addr,
425 						 vid);
426 	if (unlikely(!backbone_gw))
427 		return;
428 
429 	backbone_gw->lasttime = jiffies;
430 	batadv_backbone_gw_free_ref(backbone_gw);
431 }
432 
433 /* @bat_priv: the bat priv with all the soft interface information
434  * @vid: the vid where the request came on
435  *
436  * Repeat all of our own claims, and finally send an ANNOUNCE frame
437  * to allow the requester another check if the CRC is correct now.
438  */
439 static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
440 				      struct batadv_hard_iface *primary_if,
441 				      short vid)
442 {
443 	struct hlist_node *node;
444 	struct hlist_head *head;
445 	struct batadv_hashtable *hash;
446 	struct batadv_claim *claim;
447 	struct batadv_backbone_gw *backbone_gw;
448 	int i;
449 
450 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
451 		   "bla_answer_request(): received a claim request, send all of our own claims again\n");
452 
453 	backbone_gw = batadv_backbone_hash_find(bat_priv,
454 						primary_if->net_dev->dev_addr,
455 						vid);
456 	if (!backbone_gw)
457 		return;
458 
459 	hash = bat_priv->claim_hash;
460 	for (i = 0; i < hash->size; i++) {
461 		head = &hash->table[i];
462 
463 		rcu_read_lock();
464 		hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
465 			/* only own claims are interesting */
466 			if (claim->backbone_gw != backbone_gw)
467 				continue;
468 
469 			batadv_bla_send_claim(bat_priv, claim->addr, claim->vid,
470 					      BATADV_CLAIM_TYPE_ADD);
471 		}
472 		rcu_read_unlock();
473 	}
474 
475 	/* finally, send an announcement frame */
476 	batadv_bla_send_announce(bat_priv, backbone_gw);
477 	batadv_backbone_gw_free_ref(backbone_gw);
478 }
479 
480 /* @backbone_gw: the backbone gateway from whom we are out of sync
481  *
482  * When the crc is wrong, ask the backbone gateway for a full table update.
483  * After the request, it will repeat all of his own claims and finally
484  * send an announcement claim with which we can check again.
485  */
486 static void batadv_bla_send_request(struct batadv_backbone_gw *backbone_gw)
487 {
488 	/* first, remove all old entries */
489 	batadv_bla_del_backbone_claims(backbone_gw);
490 
491 	batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
492 		   "Sending REQUEST to %pM\n", backbone_gw->orig);
493 
494 	/* send request */
495 	batadv_bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig,
496 			      backbone_gw->vid, BATADV_CLAIM_TYPE_REQUEST);
497 
498 	/* no local broadcasts should be sent or received, for now. */
499 	if (!atomic_read(&backbone_gw->request_sent)) {
500 		atomic_inc(&backbone_gw->bat_priv->bla_num_requests);
501 		atomic_set(&backbone_gw->request_sent, 1);
502 	}
503 }
504 
505 /* @bat_priv: the bat priv with all the soft interface information
506  * @backbone_gw: our backbone gateway which should be announced
507  *
508  * This function sends an announcement. It is called from multiple
509  * places.
510  */
511 static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
512 				     struct batadv_backbone_gw *backbone_gw)
513 {
514 	uint8_t mac[ETH_ALEN];
515 	__be16 crc;
516 
517 	memcpy(mac, batadv_announce_mac, 4);
518 	crc = htons(backbone_gw->crc);
519 	memcpy(&mac[4], &crc, 2);
520 
521 	batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
522 			      BATADV_CLAIM_TYPE_ANNOUNCE);
523 
524 }
525 
526 /**
527  * batadv_bla_add_claim - Adds a claim in the claim hash
528  * @bat_priv: the bat priv with all the soft interface information
529  * @mac: the mac address of the claim
530  * @vid: the VLAN ID of the frame
531  * @backbone_gw: the backbone gateway which claims it
532  */
533 static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
534 				 const uint8_t *mac, const short vid,
535 				 struct batadv_backbone_gw *backbone_gw)
536 {
537 	struct batadv_claim *claim;
538 	struct batadv_claim search_claim;
539 	int hash_added;
540 
541 	memcpy(search_claim.addr, mac, ETH_ALEN);
542 	search_claim.vid = vid;
543 	claim = batadv_claim_hash_find(bat_priv, &search_claim);
544 
545 	/* create a new claim entry if it does not exist yet. */
546 	if (!claim) {
547 		claim = kzalloc(sizeof(*claim), GFP_ATOMIC);
548 		if (!claim)
549 			return;
550 
551 		memcpy(claim->addr, mac, ETH_ALEN);
552 		claim->vid = vid;
553 		claim->lasttime = jiffies;
554 		claim->backbone_gw = backbone_gw;
555 
556 		atomic_set(&claim->refcount, 2);
557 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
558 			   "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n",
559 			   mac, vid);
560 		hash_added = batadv_hash_add(bat_priv->claim_hash,
561 					     batadv_compare_claim,
562 					     batadv_choose_claim, claim,
563 					     &claim->hash_entry);
564 
565 		if (unlikely(hash_added != 0)) {
566 			/* only local changes happened. */
567 			kfree(claim);
568 			return;
569 		}
570 	} else {
571 		claim->lasttime = jiffies;
572 		if (claim->backbone_gw == backbone_gw)
573 			/* no need to register a new backbone */
574 			goto claim_free_ref;
575 
576 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
577 			   "bla_add_claim(): changing ownership for %pM, vid %d\n",
578 			   mac, vid);
579 
580 		claim->backbone_gw->crc ^=
581 			crc16(0, claim->addr, ETH_ALEN);
582 		batadv_backbone_gw_free_ref(claim->backbone_gw);
583 
584 	}
585 	/* set (new) backbone gw */
586 	atomic_inc(&backbone_gw->refcount);
587 	claim->backbone_gw = backbone_gw;
588 
589 	backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
590 	backbone_gw->lasttime = jiffies;
591 
592 claim_free_ref:
593 	batadv_claim_free_ref(claim);
594 }
595 
596 /* Delete a claim from the claim hash which has the
597  * given mac address and vid.
598  */
599 static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
600 				 const uint8_t *mac, const short vid)
601 {
602 	struct batadv_claim search_claim, *claim;
603 
604 	memcpy(search_claim.addr, mac, ETH_ALEN);
605 	search_claim.vid = vid;
606 	claim = batadv_claim_hash_find(bat_priv, &search_claim);
607 	if (!claim)
608 		return;
609 
610 	batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n",
611 		   mac, vid);
612 
613 	batadv_hash_remove(bat_priv->claim_hash, batadv_compare_claim,
614 			   batadv_choose_claim, claim);
615 	batadv_claim_free_ref(claim); /* reference from the hash is gone */
616 
617 	claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
618 
619 	/* don't need the reference from hash_find() anymore */
620 	batadv_claim_free_ref(claim);
621 }
622 
623 /* check for ANNOUNCE frame, return 1 if handled */
624 static int batadv_handle_announce(struct batadv_priv *bat_priv,
625 				  uint8_t *an_addr, uint8_t *backbone_addr,
626 				  short vid)
627 {
628 	struct batadv_backbone_gw *backbone_gw;
629 	uint16_t crc;
630 
631 	if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
632 		return 0;
633 
634 	backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid);
635 
636 	if (unlikely(!backbone_gw))
637 		return 1;
638 
639 
640 	/* handle as ANNOUNCE frame */
641 	backbone_gw->lasttime = jiffies;
642 	crc = ntohs(*((__be16 *)(&an_addr[4])));
643 
644 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
645 		   "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %04x\n",
646 		   vid, backbone_gw->orig, crc);
647 
648 	if (backbone_gw->crc != crc) {
649 		batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
650 			   "handle_announce(): CRC FAILED for %pM/%d (my = %04x, sent = %04x)\n",
651 			   backbone_gw->orig, backbone_gw->vid,
652 			   backbone_gw->crc, crc);
653 
654 		batadv_bla_send_request(backbone_gw);
655 	} else {
656 		/* if we have sent a request and the crc was OK,
657 		 * we can allow traffic again.
658 		 */
659 		if (atomic_read(&backbone_gw->request_sent)) {
660 			atomic_dec(&backbone_gw->bat_priv->bla_num_requests);
661 			atomic_set(&backbone_gw->request_sent, 0);
662 		}
663 	}
664 
665 	batadv_backbone_gw_free_ref(backbone_gw);
666 	return 1;
667 }
668 
669 /* check for REQUEST frame, return 1 if handled */
670 static int batadv_handle_request(struct batadv_priv *bat_priv,
671 				 struct batadv_hard_iface *primary_if,
672 				 uint8_t *backbone_addr,
673 				 struct ethhdr *ethhdr, short vid)
674 {
675 	/* check for REQUEST frame */
676 	if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest))
677 		return 0;
678 
679 	/* sanity check, this should not happen on a normal switch,
680 	 * we ignore it in this case.
681 	 */
682 	if (!batadv_compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr))
683 		return 1;
684 
685 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
686 		   "handle_request(): REQUEST vid %d (sent by %pM)...\n",
687 		   vid, ethhdr->h_source);
688 
689 	batadv_bla_answer_request(bat_priv, primary_if, vid);
690 	return 1;
691 }
692 
693 /* check for UNCLAIM frame, return 1 if handled */
694 static int batadv_handle_unclaim(struct batadv_priv *bat_priv,
695 				 struct batadv_hard_iface *primary_if,
696 				 uint8_t *backbone_addr,
697 				 uint8_t *claim_addr, short vid)
698 {
699 	struct batadv_backbone_gw *backbone_gw;
700 
701 	/* unclaim in any case if it is our own */
702 	if (primary_if && batadv_compare_eth(backbone_addr,
703 					     primary_if->net_dev->dev_addr))
704 		batadv_bla_send_claim(bat_priv, claim_addr, vid,
705 				      BATADV_CLAIM_TYPE_DEL);
706 
707 	backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid);
708 
709 	if (!backbone_gw)
710 		return 1;
711 
712 	/* this must be an UNCLAIM frame */
713 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
714 		   "handle_unclaim(): UNCLAIM %pM on vid %d (sent by %pM)...\n",
715 		   claim_addr, vid, backbone_gw->orig);
716 
717 	batadv_bla_del_claim(bat_priv, claim_addr, vid);
718 	batadv_backbone_gw_free_ref(backbone_gw);
719 	return 1;
720 }
721 
722 /* check for CLAIM frame, return 1 if handled */
723 static int batadv_handle_claim(struct batadv_priv *bat_priv,
724 			       struct batadv_hard_iface *primary_if,
725 			       uint8_t *backbone_addr, uint8_t *claim_addr,
726 			       short vid)
727 {
728 	struct batadv_backbone_gw *backbone_gw;
729 
730 	/* register the gateway if not yet available, and add the claim. */
731 
732 	backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid);
733 
734 	if (unlikely(!backbone_gw))
735 		return 1;
736 
737 	/* this must be a CLAIM frame */
738 	batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw);
739 	if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
740 		batadv_bla_send_claim(bat_priv, claim_addr, vid,
741 				      BATADV_CLAIM_TYPE_ADD);
742 
743 	/* TODO: we could call something like tt_local_del() here. */
744 
745 	batadv_backbone_gw_free_ref(backbone_gw);
746 	return 1;
747 }
748 
749 /**
750  * batadv_check_claim_group
751  * @bat_priv: the bat priv with all the soft interface information
752  * @hw_src: the Hardware source in the ARP Header
753  * @hw_dst: the Hardware destination in the ARP Header
754  * @ethhdr: pointer to the Ethernet header of the claim frame
755  *
756  * checks if it is a claim packet and if its on the same group.
757  * This function also applies the group ID of the sender
758  * if it is in the same mesh.
759  *
760  * returns:
761  *	2  - if it is a claim packet and on the same group
762  *	1  - if is a claim packet from another group
763  *	0  - if it is not a claim packet
764  */
765 static int batadv_check_claim_group(struct batadv_priv *bat_priv,
766 				    struct batadv_hard_iface *primary_if,
767 				    uint8_t *hw_src, uint8_t *hw_dst,
768 				    struct ethhdr *ethhdr)
769 {
770 	uint8_t *backbone_addr;
771 	struct batadv_orig_node *orig_node;
772 	struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
773 
774 	bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
775 	bla_dst_own = &bat_priv->claim_dest;
776 
777 	/* check if it is a claim packet in general */
778 	if (memcmp(bla_dst->magic, bla_dst_own->magic,
779 		   sizeof(bla_dst->magic)) != 0)
780 		return 0;
781 
782 	/* if announcement packet, use the source,
783 	 * otherwise assume it is in the hw_src
784 	 */
785 	switch (bla_dst->type) {
786 	case BATADV_CLAIM_TYPE_ADD:
787 		backbone_addr = hw_src;
788 		break;
789 	case BATADV_CLAIM_TYPE_REQUEST:
790 	case BATADV_CLAIM_TYPE_ANNOUNCE:
791 	case BATADV_CLAIM_TYPE_DEL:
792 		backbone_addr = ethhdr->h_source;
793 		break;
794 	default:
795 		return 0;
796 	}
797 
798 	/* don't accept claim frames from ourselves */
799 	if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
800 		return 0;
801 
802 	/* if its already the same group, it is fine. */
803 	if (bla_dst->group == bla_dst_own->group)
804 		return 2;
805 
806 	/* lets see if this originator is in our mesh */
807 	orig_node = batadv_orig_hash_find(bat_priv, backbone_addr);
808 
809 	/* dont accept claims from gateways which are not in
810 	 * the same mesh or group.
811 	 */
812 	if (!orig_node)
813 		return 1;
814 
815 	/* if our mesh friends mac is bigger, use it for ourselves. */
816 	if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) {
817 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
818 			   "taking other backbones claim group: %04x\n",
819 			   ntohs(bla_dst->group));
820 		bla_dst_own->group = bla_dst->group;
821 	}
822 
823 	batadv_orig_node_free_ref(orig_node);
824 
825 	return 2;
826 }
827 
828 
829 /* @bat_priv: the bat priv with all the soft interface information
830  * @skb: the frame to be checked
831  *
832  * Check if this is a claim frame, and process it accordingly.
833  *
834  * returns 1 if it was a claim frame, otherwise return 0 to
835  * tell the callee that it can use the frame on its own.
836  */
837 static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
838 				    struct batadv_hard_iface *primary_if,
839 				    struct sk_buff *skb)
840 {
841 	struct ethhdr *ethhdr;
842 	struct vlan_ethhdr *vhdr;
843 	struct arphdr *arphdr;
844 	uint8_t *hw_src, *hw_dst;
845 	struct batadv_bla_claim_dst *bla_dst;
846 	uint16_t proto;
847 	int headlen;
848 	short vid = -1;
849 	int ret;
850 
851 	ethhdr = (struct ethhdr *)skb_mac_header(skb);
852 
853 	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
854 		vhdr = (struct vlan_ethhdr *)ethhdr;
855 		vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
856 		proto = ntohs(vhdr->h_vlan_encapsulated_proto);
857 		headlen = sizeof(*vhdr);
858 	} else {
859 		proto = ntohs(ethhdr->h_proto);
860 		headlen = ETH_HLEN;
861 	}
862 
863 	if (proto != ETH_P_ARP)
864 		return 0; /* not a claim frame */
865 
866 	/* this must be a ARP frame. check if it is a claim. */
867 
868 	if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev))))
869 		return 0;
870 
871 	/* pskb_may_pull() may have modified the pointers, get ethhdr again */
872 	ethhdr = (struct ethhdr *)skb_mac_header(skb);
873 	arphdr = (struct arphdr *)((uint8_t *)ethhdr + headlen);
874 
875 	/* Check whether the ARP frame carries a valid
876 	 * IP information
877 	 */
878 	if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
879 		return 0;
880 	if (arphdr->ar_pro != htons(ETH_P_IP))
881 		return 0;
882 	if (arphdr->ar_hln != ETH_ALEN)
883 		return 0;
884 	if (arphdr->ar_pln != 4)
885 		return 0;
886 
887 	hw_src = (uint8_t *)arphdr + sizeof(struct arphdr);
888 	hw_dst = hw_src + ETH_ALEN + 4;
889 	bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
890 
891 	/* check if it is a claim frame. */
892 	ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst,
893 				       ethhdr);
894 	if (ret == 1)
895 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
896 			   "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
897 			   ethhdr->h_source, vid, hw_src, hw_dst);
898 
899 	if (ret < 2)
900 		return ret;
901 
902 	/* become a backbone gw ourselves on this vlan if not happened yet */
903 	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
904 
905 	/* check for the different types of claim frames ... */
906 	switch (bla_dst->type) {
907 	case BATADV_CLAIM_TYPE_ADD:
908 		if (batadv_handle_claim(bat_priv, primary_if, hw_src,
909 					ethhdr->h_source, vid))
910 			return 1;
911 		break;
912 	case BATADV_CLAIM_TYPE_DEL:
913 		if (batadv_handle_unclaim(bat_priv, primary_if,
914 					  ethhdr->h_source, hw_src, vid))
915 			return 1;
916 		break;
917 
918 	case BATADV_CLAIM_TYPE_ANNOUNCE:
919 		if (batadv_handle_announce(bat_priv, hw_src, ethhdr->h_source,
920 					   vid))
921 			return 1;
922 		break;
923 	case BATADV_CLAIM_TYPE_REQUEST:
924 		if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr,
925 					  vid))
926 			return 1;
927 		break;
928 	}
929 
930 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
931 		   "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
932 		   ethhdr->h_source, vid, hw_src, hw_dst);
933 	return 1;
934 }
935 
936 /* Check when we last heard from other nodes, and remove them in case of
937  * a time out, or clean all backbone gws if now is set.
938  */
939 static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
940 {
941 	struct batadv_backbone_gw *backbone_gw;
942 	struct hlist_node *node, *node_tmp;
943 	struct hlist_head *head;
944 	struct batadv_hashtable *hash;
945 	spinlock_t *list_lock;	/* protects write access to the hash lists */
946 	int i;
947 
948 	hash = bat_priv->backbone_hash;
949 	if (!hash)
950 		return;
951 
952 	for (i = 0; i < hash->size; i++) {
953 		head = &hash->table[i];
954 		list_lock = &hash->list_locks[i];
955 
956 		spin_lock_bh(list_lock);
957 		hlist_for_each_entry_safe(backbone_gw, node, node_tmp,
958 					  head, hash_entry) {
959 			if (now)
960 				goto purge_now;
961 			if (!batadv_has_timed_out(backbone_gw->lasttime,
962 						  BATADV_BLA_BACKBONE_TIMEOUT))
963 				continue;
964 
965 			batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
966 				   "bla_purge_backbone_gw(): backbone gw %pM timed out\n",
967 				   backbone_gw->orig);
968 
969 purge_now:
970 			/* don't wait for the pending request anymore */
971 			if (atomic_read(&backbone_gw->request_sent))
972 				atomic_dec(&bat_priv->bla_num_requests);
973 
974 			batadv_bla_del_backbone_claims(backbone_gw);
975 
976 			hlist_del_rcu(node);
977 			batadv_backbone_gw_free_ref(backbone_gw);
978 		}
979 		spin_unlock_bh(list_lock);
980 	}
981 }
982 
983 /**
984  * batadv_bla_purge_claims
985  * @bat_priv: the bat priv with all the soft interface information
986  * @primary_if: the selected primary interface, may be NULL if now is set
987  * @now: whether the whole hash shall be wiped now
988  *
989  * Check when we heard last time from our own claims, and remove them in case of
990  * a time out, or clean all claims if now is set
991  */
992 static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
993 				    struct batadv_hard_iface *primary_if,
994 				    int now)
995 {
996 	struct batadv_claim *claim;
997 	struct hlist_node *node;
998 	struct hlist_head *head;
999 	struct batadv_hashtable *hash;
1000 	int i;
1001 
1002 	hash = bat_priv->claim_hash;
1003 	if (!hash)
1004 		return;
1005 
1006 	for (i = 0; i < hash->size; i++) {
1007 		head = &hash->table[i];
1008 
1009 		rcu_read_lock();
1010 		hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
1011 			if (now)
1012 				goto purge_now;
1013 			if (!batadv_compare_eth(claim->backbone_gw->orig,
1014 						primary_if->net_dev->dev_addr))
1015 				continue;
1016 			if (!batadv_has_timed_out(claim->lasttime,
1017 						  BATADV_BLA_CLAIM_TIMEOUT))
1018 				continue;
1019 
1020 			batadv_dbg(BATADV_DBG_BLA, bat_priv,
1021 				   "bla_purge_claims(): %pM, vid %d, time out\n",
1022 				   claim->addr, claim->vid);
1023 
1024 purge_now:
1025 			batadv_handle_unclaim(bat_priv, primary_if,
1026 					      claim->backbone_gw->orig,
1027 					      claim->addr, claim->vid);
1028 		}
1029 		rcu_read_unlock();
1030 	}
1031 }
1032 
1033 /**
1034  * batadv_bla_update_orig_address
1035  * @bat_priv: the bat priv with all the soft interface information
1036  * @primary_if: the new selected primary_if
1037  * @oldif: the old primary interface, may be NULL
1038  *
1039  * Update the backbone gateways when the own orig address changes.
1040  */
1041 void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
1042 				    struct batadv_hard_iface *primary_if,
1043 				    struct batadv_hard_iface *oldif)
1044 {
1045 	struct batadv_backbone_gw *backbone_gw;
1046 	struct hlist_node *node;
1047 	struct hlist_head *head;
1048 	struct batadv_hashtable *hash;
1049 	int i;
1050 
1051 	/* reset bridge loop avoidance group id */
1052 	bat_priv->claim_dest.group =
1053 		htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN));
1054 
1055 	if (!oldif) {
1056 		batadv_bla_purge_claims(bat_priv, NULL, 1);
1057 		batadv_bla_purge_backbone_gw(bat_priv, 1);
1058 		return;
1059 	}
1060 
1061 	hash = bat_priv->backbone_hash;
1062 	if (!hash)
1063 		return;
1064 
1065 	for (i = 0; i < hash->size; i++) {
1066 		head = &hash->table[i];
1067 
1068 		rcu_read_lock();
1069 		hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
1070 			/* own orig still holds the old value. */
1071 			if (!batadv_compare_eth(backbone_gw->orig,
1072 						oldif->net_dev->dev_addr))
1073 				continue;
1074 
1075 			memcpy(backbone_gw->orig,
1076 			       primary_if->net_dev->dev_addr, ETH_ALEN);
1077 			/* send an announce frame so others will ask for our
1078 			 * claims and update their tables.
1079 			 */
1080 			batadv_bla_send_announce(bat_priv, backbone_gw);
1081 		}
1082 		rcu_read_unlock();
1083 	}
1084 }
1085 
1086 
1087 
1088 /* (re)start the timer */
1089 static void batadv_bla_start_timer(struct batadv_priv *bat_priv)
1090 {
1091 	INIT_DELAYED_WORK(&bat_priv->bla_work, batadv_bla_periodic_work);
1092 	queue_delayed_work(batadv_event_workqueue, &bat_priv->bla_work,
1093 			   msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH));
1094 }
1095 
1096 /* periodic work to do:
1097  *  * purge structures when they are too old
1098  *  * send announcements
1099  */
1100 static void batadv_bla_periodic_work(struct work_struct *work)
1101 {
1102 	struct delayed_work *delayed_work =
1103 		container_of(work, struct delayed_work, work);
1104 	struct batadv_priv *bat_priv;
1105 	struct hlist_node *node;
1106 	struct hlist_head *head;
1107 	struct batadv_backbone_gw *backbone_gw;
1108 	struct batadv_hashtable *hash;
1109 	struct batadv_hard_iface *primary_if;
1110 	int i;
1111 
1112 	bat_priv = container_of(delayed_work, struct batadv_priv, bla_work);
1113 	primary_if = batadv_primary_if_get_selected(bat_priv);
1114 	if (!primary_if)
1115 		goto out;
1116 
1117 	batadv_bla_purge_claims(bat_priv, primary_if, 0);
1118 	batadv_bla_purge_backbone_gw(bat_priv, 0);
1119 
1120 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1121 		goto out;
1122 
1123 	hash = bat_priv->backbone_hash;
1124 	if (!hash)
1125 		goto out;
1126 
1127 	for (i = 0; i < hash->size; i++) {
1128 		head = &hash->table[i];
1129 
1130 		rcu_read_lock();
1131 		hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
1132 			if (!batadv_compare_eth(backbone_gw->orig,
1133 						primary_if->net_dev->dev_addr))
1134 				continue;
1135 
1136 			backbone_gw->lasttime = jiffies;
1137 
1138 			batadv_bla_send_announce(bat_priv, backbone_gw);
1139 		}
1140 		rcu_read_unlock();
1141 	}
1142 out:
1143 	if (primary_if)
1144 		batadv_hardif_free_ref(primary_if);
1145 
1146 	batadv_bla_start_timer(bat_priv);
1147 }
1148 
1149 /* The hash for claim and backbone hash receive the same key because they
1150  * are getting initialized by hash_new with the same key. Reinitializing
1151  * them with to different keys to allow nested locking without generating
1152  * lockdep warnings
1153  */
1154 static struct lock_class_key batadv_claim_hash_lock_class_key;
1155 static struct lock_class_key batadv_backbone_hash_lock_class_key;
1156 
1157 /* initialize all bla structures */
1158 int batadv_bla_init(struct batadv_priv *bat_priv)
1159 {
1160 	int i;
1161 	uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
1162 	struct batadv_hard_iface *primary_if;
1163 
1164 	batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n");
1165 
1166 	/* setting claim destination address */
1167 	memcpy(&bat_priv->claim_dest.magic, claim_dest, 3);
1168 	bat_priv->claim_dest.type = 0;
1169 	primary_if = batadv_primary_if_get_selected(bat_priv);
1170 	if (primary_if) {
1171 		bat_priv->claim_dest.group =
1172 			htons(crc16(0, primary_if->net_dev->dev_addr,
1173 				    ETH_ALEN));
1174 		batadv_hardif_free_ref(primary_if);
1175 	} else {
1176 		bat_priv->claim_dest.group = 0; /* will be set later */
1177 	}
1178 
1179 	/* initialize the duplicate list */
1180 	for (i = 0; i < BATADV_DUPLIST_SIZE; i++)
1181 		bat_priv->bcast_duplist[i].entrytime =
1182 			jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT);
1183 	bat_priv->bcast_duplist_curr = 0;
1184 
1185 	if (bat_priv->claim_hash)
1186 		return 0;
1187 
1188 	bat_priv->claim_hash = batadv_hash_new(128);
1189 	bat_priv->backbone_hash = batadv_hash_new(32);
1190 
1191 	if (!bat_priv->claim_hash || !bat_priv->backbone_hash)
1192 		return -ENOMEM;
1193 
1194 	batadv_hash_set_lock_class(bat_priv->claim_hash,
1195 				   &batadv_claim_hash_lock_class_key);
1196 	batadv_hash_set_lock_class(bat_priv->backbone_hash,
1197 				   &batadv_backbone_hash_lock_class_key);
1198 
1199 	batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hashes initialized\n");
1200 
1201 	batadv_bla_start_timer(bat_priv);
1202 	return 0;
1203 }
1204 
1205 /**
1206  * batadv_bla_check_bcast_duplist
1207  * @bat_priv: the bat priv with all the soft interface information
1208  * @bcast_packet: originator mac address
1209  * @hdr_size: maximum length of the frame
1210  *
1211  * check if it is on our broadcast list. Another gateway might
1212  * have sent the same packet because it is connected to the same backbone,
1213  * so we have to remove this duplicate.
1214  *
1215  * This is performed by checking the CRC, which will tell us
1216  * with a good chance that it is the same packet. If it is furthermore
1217  * sent by another host, drop it. We allow equal packets from
1218  * the same host however as this might be intended.
1219  */
1220 int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
1221 				   struct batadv_bcast_packet *bcast_packet,
1222 				   int hdr_size)
1223 {
1224 	int i, length, curr;
1225 	uint8_t *content;
1226 	uint16_t crc;
1227 	struct batadv_bcast_duplist_entry *entry;
1228 
1229 	length = hdr_size - sizeof(*bcast_packet);
1230 	content = (uint8_t *)bcast_packet;
1231 	content += sizeof(*bcast_packet);
1232 
1233 	/* calculate the crc ... */
1234 	crc = crc16(0, content, length);
1235 
1236 	for (i = 0; i < BATADV_DUPLIST_SIZE; i++) {
1237 		curr = (bat_priv->bcast_duplist_curr + i) % BATADV_DUPLIST_SIZE;
1238 		entry = &bat_priv->bcast_duplist[curr];
1239 
1240 		/* we can stop searching if the entry is too old ;
1241 		 * later entries will be even older
1242 		 */
1243 		if (batadv_has_timed_out(entry->entrytime,
1244 					 BATADV_DUPLIST_TIMEOUT))
1245 			break;
1246 
1247 		if (entry->crc != crc)
1248 			continue;
1249 
1250 		if (batadv_compare_eth(entry->orig, bcast_packet->orig))
1251 			continue;
1252 
1253 		/* this entry seems to match: same crc, not too old,
1254 		 * and from another gw. therefore return 1 to forbid it.
1255 		 */
1256 		return 1;
1257 	}
1258 	/* not found, add a new entry (overwrite the oldest entry) */
1259 	curr = (bat_priv->bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1);
1260 	curr %= BATADV_DUPLIST_SIZE;
1261 	entry = &bat_priv->bcast_duplist[curr];
1262 	entry->crc = crc;
1263 	entry->entrytime = jiffies;
1264 	memcpy(entry->orig, bcast_packet->orig, ETH_ALEN);
1265 	bat_priv->bcast_duplist_curr = curr;
1266 
1267 	/* allow it, its the first occurence. */
1268 	return 0;
1269 }
1270 
1271 
1272 
1273 /* @bat_priv: the bat priv with all the soft interface information
1274  * @orig: originator mac address
1275  *
1276  * check if the originator is a gateway for any VLAN ID.
1277  *
1278  * returns 1 if it is found, 0 otherwise
1279  */
1280 int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
1281 {
1282 	struct batadv_hashtable *hash = bat_priv->backbone_hash;
1283 	struct hlist_head *head;
1284 	struct hlist_node *node;
1285 	struct batadv_backbone_gw *backbone_gw;
1286 	int i;
1287 
1288 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1289 		return 0;
1290 
1291 	if (!hash)
1292 		return 0;
1293 
1294 	for (i = 0; i < hash->size; i++) {
1295 		head = &hash->table[i];
1296 
1297 		rcu_read_lock();
1298 		hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
1299 			if (batadv_compare_eth(backbone_gw->orig, orig)) {
1300 				rcu_read_unlock();
1301 				return 1;
1302 			}
1303 		}
1304 		rcu_read_unlock();
1305 	}
1306 
1307 	return 0;
1308 }
1309 
1310 
1311 /**
1312  * batadv_bla_is_backbone_gw
1313  * @skb: the frame to be checked
1314  * @orig_node: the orig_node of the frame
1315  * @hdr_size: maximum length of the frame
1316  *
1317  * bla_is_backbone_gw inspects the skb for the VLAN ID and returns 1
1318  * if the orig_node is also a gateway on the soft interface, otherwise it
1319  * returns 0.
1320  */
1321 int batadv_bla_is_backbone_gw(struct sk_buff *skb,
1322 			      struct batadv_orig_node *orig_node, int hdr_size)
1323 {
1324 	struct ethhdr *ethhdr;
1325 	struct vlan_ethhdr *vhdr;
1326 	struct batadv_backbone_gw *backbone_gw;
1327 	short vid = -1;
1328 
1329 	if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
1330 		return 0;
1331 
1332 	/* first, find out the vid. */
1333 	if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
1334 		return 0;
1335 
1336 	ethhdr = (struct ethhdr *)(((uint8_t *)skb->data) + hdr_size);
1337 
1338 	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
1339 		if (!pskb_may_pull(skb, hdr_size + sizeof(struct vlan_ethhdr)))
1340 			return 0;
1341 
1342 		vhdr = (struct vlan_ethhdr *)(((uint8_t *)skb->data) +
1343 					      hdr_size);
1344 		vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
1345 	}
1346 
1347 	/* see if this originator is a backbone gw for this VLAN */
1348 	backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,
1349 						orig_node->orig, vid);
1350 	if (!backbone_gw)
1351 		return 0;
1352 
1353 	batadv_backbone_gw_free_ref(backbone_gw);
1354 	return 1;
1355 }
1356 
1357 /* free all bla structures (for softinterface free or module unload) */
1358 void batadv_bla_free(struct batadv_priv *bat_priv)
1359 {
1360 	struct batadv_hard_iface *primary_if;
1361 
1362 	cancel_delayed_work_sync(&bat_priv->bla_work);
1363 	primary_if = batadv_primary_if_get_selected(bat_priv);
1364 
1365 	if (bat_priv->claim_hash) {
1366 		batadv_bla_purge_claims(bat_priv, primary_if, 1);
1367 		batadv_hash_destroy(bat_priv->claim_hash);
1368 		bat_priv->claim_hash = NULL;
1369 	}
1370 	if (bat_priv->backbone_hash) {
1371 		batadv_bla_purge_backbone_gw(bat_priv, 1);
1372 		batadv_hash_destroy(bat_priv->backbone_hash);
1373 		bat_priv->backbone_hash = NULL;
1374 	}
1375 	if (primary_if)
1376 		batadv_hardif_free_ref(primary_if);
1377 }
1378 
1379 /**
1380  * batadv_bla_rx
1381  * @bat_priv: the bat priv with all the soft interface information
1382  * @skb: the frame to be checked
1383  * @vid: the VLAN ID of the frame
1384  * @is_bcast: the packet came in a broadcast packet type.
1385  *
1386  * bla_rx avoidance checks if:
1387  *  * we have to race for a claim
1388  *  * if the frame is allowed on the LAN
1389  *
1390  * in these cases, the skb is further handled by this function and
1391  * returns 1, otherwise it returns 0 and the caller shall further
1392  * process the skb.
1393  */
1394 int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid,
1395 		  bool is_bcast)
1396 {
1397 	struct ethhdr *ethhdr;
1398 	struct batadv_claim search_claim, *claim = NULL;
1399 	struct batadv_hard_iface *primary_if;
1400 	int ret;
1401 
1402 	ethhdr = (struct ethhdr *)skb_mac_header(skb);
1403 
1404 	primary_if = batadv_primary_if_get_selected(bat_priv);
1405 	if (!primary_if)
1406 		goto handled;
1407 
1408 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1409 		goto allow;
1410 
1411 
1412 	if (unlikely(atomic_read(&bat_priv->bla_num_requests)))
1413 		/* don't allow broadcasts while requests are in flight */
1414 		if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
1415 			goto handled;
1416 
1417 	memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN);
1418 	search_claim.vid = vid;
1419 	claim = batadv_claim_hash_find(bat_priv, &search_claim);
1420 
1421 	if (!claim) {
1422 		/* possible optimization: race for a claim */
1423 		/* No claim exists yet, claim it for us!
1424 		 */
1425 		batadv_handle_claim(bat_priv, primary_if,
1426 				    primary_if->net_dev->dev_addr,
1427 				    ethhdr->h_source, vid);
1428 		goto allow;
1429 	}
1430 
1431 	/* if it is our own claim ... */
1432 	if (batadv_compare_eth(claim->backbone_gw->orig,
1433 			       primary_if->net_dev->dev_addr)) {
1434 		/* ... allow it in any case */
1435 		claim->lasttime = jiffies;
1436 		goto allow;
1437 	}
1438 
1439 	/* if it is a broadcast ... */
1440 	if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
1441 		/* ... drop it. the responsible gateway is in charge.
1442 		 *
1443 		 * We need to check is_bcast because with the gateway
1444 		 * feature, broadcasts (like DHCP requests) may be sent
1445 		 * using a unicast packet type.
1446 		 */
1447 		goto handled;
1448 	} else {
1449 		/* seems the client considers us as its best gateway.
1450 		 * send a claim and update the claim table
1451 		 * immediately.
1452 		 */
1453 		batadv_handle_claim(bat_priv, primary_if,
1454 				    primary_if->net_dev->dev_addr,
1455 				    ethhdr->h_source, vid);
1456 		goto allow;
1457 	}
1458 allow:
1459 	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
1460 	ret = 0;
1461 	goto out;
1462 
1463 handled:
1464 	kfree_skb(skb);
1465 	ret = 1;
1466 
1467 out:
1468 	if (primary_if)
1469 		batadv_hardif_free_ref(primary_if);
1470 	if (claim)
1471 		batadv_claim_free_ref(claim);
1472 	return ret;
1473 }
1474 
1475 /**
1476  * batadv_bla_tx
1477  * @bat_priv: the bat priv with all the soft interface information
1478  * @skb: the frame to be checked
1479  * @vid: the VLAN ID of the frame
1480  *
1481  * bla_tx checks if:
1482  *  * a claim was received which has to be processed
1483  *  * the frame is allowed on the mesh
1484  *
1485  * in these cases, the skb is further handled by this function and
1486  * returns 1, otherwise it returns 0 and the caller shall further
1487  * process the skb.
1488  */
1489 int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid)
1490 {
1491 	struct ethhdr *ethhdr;
1492 	struct batadv_claim search_claim, *claim = NULL;
1493 	struct batadv_hard_iface *primary_if;
1494 	int ret = 0;
1495 
1496 	primary_if = batadv_primary_if_get_selected(bat_priv);
1497 	if (!primary_if)
1498 		goto out;
1499 
1500 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1501 		goto allow;
1502 
1503 	/* in VLAN case, the mac header might not be set. */
1504 	skb_reset_mac_header(skb);
1505 
1506 	if (batadv_bla_process_claim(bat_priv, primary_if, skb))
1507 		goto handled;
1508 
1509 	ethhdr = (struct ethhdr *)skb_mac_header(skb);
1510 
1511 	if (unlikely(atomic_read(&bat_priv->bla_num_requests)))
1512 		/* don't allow broadcasts while requests are in flight */
1513 		if (is_multicast_ether_addr(ethhdr->h_dest))
1514 			goto handled;
1515 
1516 	memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN);
1517 	search_claim.vid = vid;
1518 
1519 	claim = batadv_claim_hash_find(bat_priv, &search_claim);
1520 
1521 	/* if no claim exists, allow it. */
1522 	if (!claim)
1523 		goto allow;
1524 
1525 	/* check if we are responsible. */
1526 	if (batadv_compare_eth(claim->backbone_gw->orig,
1527 			       primary_if->net_dev->dev_addr)) {
1528 		/* if yes, the client has roamed and we have
1529 		 * to unclaim it.
1530 		 */
1531 		batadv_handle_unclaim(bat_priv, primary_if,
1532 				      primary_if->net_dev->dev_addr,
1533 				      ethhdr->h_source, vid);
1534 		goto allow;
1535 	}
1536 
1537 	/* check if it is a multicast/broadcast frame */
1538 	if (is_multicast_ether_addr(ethhdr->h_dest)) {
1539 		/* drop it. the responsible gateway has forwarded it into
1540 		 * the backbone network.
1541 		 */
1542 		goto handled;
1543 	} else {
1544 		/* we must allow it. at least if we are
1545 		 * responsible for the DESTINATION.
1546 		 */
1547 		goto allow;
1548 	}
1549 allow:
1550 	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
1551 	ret = 0;
1552 	goto out;
1553 handled:
1554 	ret = 1;
1555 out:
1556 	if (primary_if)
1557 		batadv_hardif_free_ref(primary_if);
1558 	if (claim)
1559 		batadv_claim_free_ref(claim);
1560 	return ret;
1561 }
1562 
1563 int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
1564 {
1565 	struct net_device *net_dev = (struct net_device *)seq->private;
1566 	struct batadv_priv *bat_priv = netdev_priv(net_dev);
1567 	struct batadv_hashtable *hash = bat_priv->claim_hash;
1568 	struct batadv_claim *claim;
1569 	struct batadv_hard_iface *primary_if;
1570 	struct hlist_node *node;
1571 	struct hlist_head *head;
1572 	uint32_t i;
1573 	bool is_own;
1574 	int ret = 0;
1575 	uint8_t *primary_addr;
1576 
1577 	primary_if = batadv_primary_if_get_selected(bat_priv);
1578 	if (!primary_if) {
1579 		ret = seq_printf(seq,
1580 				 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
1581 				 net_dev->name);
1582 		goto out;
1583 	}
1584 
1585 	if (primary_if->if_status != BATADV_IF_ACTIVE) {
1586 		ret = seq_printf(seq,
1587 				 "BATMAN mesh %s disabled - primary interface not active\n",
1588 				 net_dev->name);
1589 		goto out;
1590 	}
1591 
1592 	primary_addr = primary_if->net_dev->dev_addr;
1593 	seq_printf(seq,
1594 		   "Claims announced for the mesh %s (orig %pM, group id %04x)\n",
1595 		   net_dev->name, primary_addr,
1596 		   ntohs(bat_priv->claim_dest.group));
1597 	seq_printf(seq, "   %-17s    %-5s    %-17s [o] (%-4s)\n",
1598 		   "Client", "VID", "Originator", "CRC");
1599 	for (i = 0; i < hash->size; i++) {
1600 		head = &hash->table[i];
1601 
1602 		rcu_read_lock();
1603 		hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
1604 			is_own = batadv_compare_eth(claim->backbone_gw->orig,
1605 						    primary_addr);
1606 			seq_printf(seq,	" * %pM on % 5d by %pM [%c] (%04x)\n",
1607 				   claim->addr, claim->vid,
1608 				   claim->backbone_gw->orig,
1609 				   (is_own ? 'x' : ' '),
1610 				   claim->backbone_gw->crc);
1611 		}
1612 		rcu_read_unlock();
1613 	}
1614 out:
1615 	if (primary_if)
1616 		batadv_hardif_free_ref(primary_if);
1617 	return ret;
1618 }
1619