xref: /linux/net/batman-adv/bridge_loop_avoidance.c (revision 68993ced0f618e36cf33388f1e50223e5e6e78cc)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) B.A.T.M.A.N. contributors:
3  *
4  * Simon Wunderlich
5  */
6 
7 #include "bridge_loop_avoidance.h"
8 #include "main.h"
9 
10 #include <linux/atomic.h>
11 #include <linux/byteorder/generic.h>
12 #include <linux/compiler.h>
13 #include <linux/container_of.h>
14 #include <linux/crc16.h>
15 #include <linux/err.h>
16 #include <linux/errno.h>
17 #include <linux/etherdevice.h>
18 #include <linux/gfp.h>
19 #include <linux/if_arp.h>
20 #include <linux/if_ether.h>
21 #include <linux/if_vlan.h>
22 #include <linux/jhash.h>
23 #include <linux/jiffies.h>
24 #include <linux/kref.h>
25 #include <linux/list.h>
26 #include <linux/lockdep.h>
27 #include <linux/netdevice.h>
28 #include <linux/netlink.h>
29 #include <linux/rculist.h>
30 #include <linux/rcupdate.h>
31 #include <linux/skbuff.h>
32 #include <linux/slab.h>
33 #include <linux/spinlock.h>
34 #include <linux/sprintf.h>
35 #include <linux/stddef.h>
36 #include <linux/string.h>
37 #include <linux/string_choices.h>
38 #include <linux/workqueue.h>
39 #include <net/arp.h>
40 #include <net/genetlink.h>
41 #include <net/netlink.h>
42 #include <uapi/linux/batadv_packet.h>
43 #include <uapi/linux/batman_adv.h>
44 
45 #include "hard-interface.h"
46 #include "hash.h"
47 #include "log.h"
48 #include "netlink.h"
49 #include "originator.h"
50 #include "translation-table.h"
51 
52 static const u8 batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05};
53 
54 static void batadv_bla_periodic_work(struct work_struct *work);
55 static void
56 batadv_bla_send_announce(struct batadv_priv *bat_priv,
57 			 struct batadv_bla_backbone_gw *backbone_gw);
58 
59 /**
60  * batadv_choose_claim() - choose the right bucket for a claim.
61  * @data: data to hash
62  * @size: size of the hash table
63  *
64  * Return: the hash index of the claim
65  */
batadv_choose_claim(const void * data,u32 size)66 static inline u32 batadv_choose_claim(const void *data, u32 size)
67 {
68 	const struct batadv_bla_claim *claim = data;
69 	u32 hash = 0;
70 
71 	hash = jhash(&claim->addr, sizeof(claim->addr), hash);
72 	hash = jhash(&claim->vid, sizeof(claim->vid), hash);
73 
74 	return hash % size;
75 }
76 
77 /**
78  * batadv_choose_backbone_gw() - choose the right bucket for a backbone gateway.
79  * @data: data to hash
80  * @size: size of the hash table
81  *
82  * Return: the hash index of the backbone gateway
83  */
batadv_choose_backbone_gw(const void * data,u32 size)84 static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
85 {
86 	const struct batadv_bla_backbone_gw *gw;
87 	u32 hash = 0;
88 
89 	gw = data;
90 	hash = jhash(&gw->orig, sizeof(gw->orig), hash);
91 	hash = jhash(&gw->vid, sizeof(gw->vid), hash);
92 
93 	return hash % size;
94 }
95 
96 /**
97  * batadv_compare_backbone_gw() - compare address and vid of two backbone gws
98  * @node: list node of the first entry to compare
99  * @data2: pointer to the second backbone gateway
100  *
101  * Return: true if the backbones have the same data, false otherwise
102  */
batadv_compare_backbone_gw(const struct hlist_node * node,const void * data2)103 static bool batadv_compare_backbone_gw(const struct hlist_node *node,
104 				       const void *data2)
105 {
106 	const void *data1 = container_of(node, struct batadv_bla_backbone_gw,
107 					 hash_entry);
108 	const struct batadv_bla_backbone_gw *gw1 = data1;
109 	const struct batadv_bla_backbone_gw *gw2 = data2;
110 
111 	if (!batadv_compare_eth(gw1->orig, gw2->orig))
112 		return false;
113 
114 	if (gw1->vid != gw2->vid)
115 		return false;
116 
117 	return true;
118 }
119 
120 /**
121  * batadv_compare_claim() - compare address and vid of two claims
122  * @node: list node of the first entry to compare
123  * @data2: pointer to the second claims
124  *
125  * Return: true if the claim have the same data, 0 otherwise
126  */
batadv_compare_claim(const struct hlist_node * node,const void * data2)127 static bool batadv_compare_claim(const struct hlist_node *node,
128 				 const void *data2)
129 {
130 	const void *data1 = container_of(node, struct batadv_bla_claim,
131 					 hash_entry);
132 	const struct batadv_bla_claim *cl1 = data1;
133 	const struct batadv_bla_claim *cl2 = data2;
134 
135 	if (!batadv_compare_eth(cl1->addr, cl2->addr))
136 		return false;
137 
138 	if (cl1->vid != cl2->vid)
139 		return false;
140 
141 	return true;
142 }
143 
144 /**
145  * batadv_backbone_gw_release() - release backbone gw from lists and queue for
146  *  free after rcu grace period
147  * @ref: kref pointer of the backbone gw
148  */
batadv_backbone_gw_release(struct kref * ref)149 static void batadv_backbone_gw_release(struct kref *ref)
150 {
151 	struct batadv_bla_backbone_gw *backbone_gw;
152 
153 	backbone_gw = container_of(ref, struct batadv_bla_backbone_gw,
154 				   refcount);
155 
156 	kfree_rcu(backbone_gw, rcu);
157 }
158 
159 /**
160  * batadv_backbone_gw_put() - decrement the backbone gw refcounter and possibly
161  *  release it
162  * @backbone_gw: backbone gateway to be free'd
163  */
batadv_backbone_gw_put(struct batadv_bla_backbone_gw * backbone_gw)164 static void batadv_backbone_gw_put(struct batadv_bla_backbone_gw *backbone_gw)
165 {
166 	if (!backbone_gw)
167 		return;
168 
169 	kref_put(&backbone_gw->refcount, batadv_backbone_gw_release);
170 }
171 
172 /**
173  * batadv_claim_release() - release claim from lists and queue for free after
174  *  rcu grace period
175  * @ref: kref pointer of the claim
176  */
batadv_claim_release(struct kref * ref)177 static void batadv_claim_release(struct kref *ref)
178 {
179 	struct batadv_bla_claim *claim;
180 	struct batadv_bla_backbone_gw *old_backbone_gw;
181 
182 	claim = container_of(ref, struct batadv_bla_claim, refcount);
183 
184 	spin_lock_bh(&claim->backbone_lock);
185 	old_backbone_gw = claim->backbone_gw;
186 	claim->backbone_gw = NULL;
187 	spin_unlock_bh(&claim->backbone_lock);
188 
189 	spin_lock_bh(&old_backbone_gw->crc_lock);
190 	old_backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
191 	spin_unlock_bh(&old_backbone_gw->crc_lock);
192 
193 	batadv_backbone_gw_put(old_backbone_gw);
194 
195 	kfree_rcu(claim, rcu);
196 }
197 
198 /**
199  * batadv_claim_put() - decrement the claim refcounter and possibly release it
200  * @claim: claim to be free'd
201  */
batadv_claim_put(struct batadv_bla_claim * claim)202 static void batadv_claim_put(struct batadv_bla_claim *claim)
203 {
204 	if (!claim)
205 		return;
206 
207 	kref_put(&claim->refcount, batadv_claim_release);
208 }
209 
210 /**
211  * batadv_claim_hash_find() - looks for a claim in the claim hash
212  * @bat_priv: the bat priv with all the mesh interface information
213  * @data: search data (may be local/static data)
214  *
215  * Return: claim if found or NULL otherwise.
216  */
217 static struct batadv_bla_claim *
batadv_claim_hash_find(struct batadv_priv * bat_priv,struct batadv_bla_claim * data)218 batadv_claim_hash_find(struct batadv_priv *bat_priv,
219 		       struct batadv_bla_claim *data)
220 {
221 	struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
222 	struct hlist_head *head;
223 	struct batadv_bla_claim *claim;
224 	struct batadv_bla_claim *claim_tmp = NULL;
225 	int index;
226 
227 	if (!hash)
228 		return NULL;
229 
230 	index = batadv_choose_claim(data, hash->size);
231 	head = &hash->table[index];
232 
233 	rcu_read_lock();
234 	hlist_for_each_entry_rcu(claim, head, hash_entry) {
235 		if (!batadv_compare_claim(&claim->hash_entry, data))
236 			continue;
237 
238 		if (!kref_get_unless_zero(&claim->refcount))
239 			continue;
240 
241 		claim_tmp = claim;
242 		break;
243 	}
244 	rcu_read_unlock();
245 
246 	return claim_tmp;
247 }
248 
249 /**
250  * batadv_backbone_hash_find() - looks for a backbone gateway in the hash
251  * @bat_priv: the bat priv with all the mesh interface information
252  * @addr: the address of the originator
253  * @vid: the VLAN ID
254  *
255  * Return: backbone gateway if found or NULL otherwise
256  */
257 static struct batadv_bla_backbone_gw *
batadv_backbone_hash_find(struct batadv_priv * bat_priv,const u8 * addr,unsigned short vid)258 batadv_backbone_hash_find(struct batadv_priv *bat_priv, const u8 *addr,
259 			  unsigned short vid)
260 {
261 	struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
262 	struct hlist_head *head;
263 	struct batadv_bla_backbone_gw search_entry, *backbone_gw;
264 	struct batadv_bla_backbone_gw *backbone_gw_tmp = NULL;
265 	int index;
266 
267 	if (!hash)
268 		return NULL;
269 
270 	ether_addr_copy(search_entry.orig, addr);
271 	search_entry.vid = vid;
272 
273 	index = batadv_choose_backbone_gw(&search_entry, hash->size);
274 	head = &hash->table[index];
275 
276 	rcu_read_lock();
277 	hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
278 		if (!batadv_compare_backbone_gw(&backbone_gw->hash_entry,
279 						&search_entry))
280 			continue;
281 
282 		if (!kref_get_unless_zero(&backbone_gw->refcount))
283 			continue;
284 
285 		backbone_gw_tmp = backbone_gw;
286 		break;
287 	}
288 	rcu_read_unlock();
289 
290 	return backbone_gw_tmp;
291 }
292 
293 /**
294  * batadv_bla_del_backbone_claims() - delete all claims for a backbone
295  * @backbone_gw: backbone gateway where the claims should be removed
296  */
297 static void
batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw * backbone_gw)298 batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
299 {
300 	struct batadv_hashtable *hash;
301 	struct hlist_node *node_tmp;
302 	struct hlist_head *head;
303 	struct batadv_bla_claim *claim;
304 	int i;
305 	spinlock_t *list_lock;	/* protects write access to the hash lists */
306 
307 	hash = backbone_gw->bat_priv->bla.claim_hash;
308 	if (!hash)
309 		return;
310 
311 	for (i = 0; i < hash->size; i++) {
312 		head = &hash->table[i];
313 		list_lock = &hash->list_locks[i];
314 
315 		spin_lock_bh(list_lock);
316 		hlist_for_each_entry_safe(claim, node_tmp,
317 					  head, hash_entry) {
318 			if (claim->backbone_gw != backbone_gw)
319 				continue;
320 
321 			hlist_del_rcu(&claim->hash_entry);
322 			batadv_claim_put(claim);
323 		}
324 		spin_unlock_bh(list_lock);
325 	}
326 
327 	/* all claims gone, initialize CRC */
328 	spin_lock_bh(&backbone_gw->crc_lock);
329 	backbone_gw->crc = BATADV_BLA_CRC_INIT;
330 	spin_unlock_bh(&backbone_gw->crc_lock);
331 }
332 
333 /**
334  * batadv_bla_send_claim() - sends a claim frame according to the provided info
335  * @bat_priv: the bat priv with all the mesh interface information
336  * @mac: the mac address to be announced within the claim
337  * @vid: the VLAN ID
338  * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...)
339  */
batadv_bla_send_claim(struct batadv_priv * bat_priv,const u8 * mac,unsigned short vid,int claimtype)340 static void batadv_bla_send_claim(struct batadv_priv *bat_priv, const u8 *mac,
341 				  unsigned short vid, int claimtype)
342 {
343 	struct sk_buff *skb;
344 	struct ethhdr *ethhdr;
345 	struct batadv_hard_iface *primary_if;
346 	struct net_device *mesh_iface;
347 	u8 *hw_src;
348 	struct batadv_bla_claim_dst local_claim_dest;
349 	__be32 zeroip = 0;
350 
351 	primary_if = batadv_primary_if_get_selected(bat_priv);
352 	if (!primary_if)
353 		return;
354 
355 	memcpy(&local_claim_dest, &bat_priv->bla.claim_dest,
356 	       sizeof(local_claim_dest));
357 	local_claim_dest.type = claimtype;
358 
359 	mesh_iface = READ_ONCE(primary_if->mesh_iface);
360 	if (!mesh_iface)
361 		goto out;
362 
363 	skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
364 			 /* IP DST: 0.0.0.0 */
365 			 zeroip,
366 			 mesh_iface,
367 			 /* IP SRC: 0.0.0.0 */
368 			 zeroip,
369 			 /* Ethernet DST: Broadcast */
370 			 NULL,
371 			 /* Ethernet SRC/HW SRC:  originator mac */
372 			 primary_if->net_dev->dev_addr,
373 			 /* HW DST: FF:43:05:XX:YY:YY
374 			  * with XX   = claim type
375 			  * and YY:YY = group id
376 			  */
377 			 (u8 *)&local_claim_dest);
378 
379 	if (!skb)
380 		goto out;
381 
382 	ethhdr = (struct ethhdr *)skb->data;
383 	hw_src = (u8 *)ethhdr + ETH_HLEN + sizeof(struct arphdr);
384 
385 	/* now we pretend that the client would have sent this ... */
386 	switch (claimtype) {
387 	case BATADV_CLAIM_TYPE_CLAIM:
388 		/* normal claim frame
389 		 * set Ethernet SRC to the clients mac
390 		 */
391 		ether_addr_copy(ethhdr->h_source, mac);
392 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
393 			   "%s(): CLAIM %pM on vid %d\n", __func__, mac,
394 			   batadv_print_vid(vid));
395 		break;
396 	case BATADV_CLAIM_TYPE_UNCLAIM:
397 		/* unclaim frame
398 		 * set HW SRC to the clients mac
399 		 */
400 		ether_addr_copy(hw_src, mac);
401 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
402 			   "%s(): UNCLAIM %pM on vid %d\n", __func__, mac,
403 			   batadv_print_vid(vid));
404 		break;
405 	case BATADV_CLAIM_TYPE_ANNOUNCE:
406 		/* announcement frame
407 		 * set HW SRC to the special mac containing the crc
408 		 */
409 		ether_addr_copy(hw_src, mac);
410 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
411 			   "%s(): ANNOUNCE of %pM on vid %d\n", __func__,
412 			   ethhdr->h_source, batadv_print_vid(vid));
413 		break;
414 	case BATADV_CLAIM_TYPE_REQUEST:
415 		/* request frame
416 		 * set HW SRC and header destination to the receiving backbone
417 		 * gws mac
418 		 */
419 		ether_addr_copy(hw_src, mac);
420 		ether_addr_copy(ethhdr->h_dest, mac);
421 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
422 			   "%s(): REQUEST of %pM to %pM on vid %d\n", __func__,
423 			   ethhdr->h_source, ethhdr->h_dest,
424 			   batadv_print_vid(vid));
425 		break;
426 	case BATADV_CLAIM_TYPE_LOOPDETECT:
427 		ether_addr_copy(ethhdr->h_source, mac);
428 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
429 			   "%s(): LOOPDETECT of %pM to %pM on vid %d\n",
430 			   __func__, ethhdr->h_source, ethhdr->h_dest,
431 			   batadv_print_vid(vid));
432 
433 		break;
434 	}
435 
436 	if (vid & BATADV_VLAN_HAS_TAG) {
437 		skb = vlan_insert_tag(skb, htons(ETH_P_8021Q),
438 				      vid & VLAN_VID_MASK);
439 		if (!skb)
440 			goto out;
441 	}
442 
443 	skb_reset_mac_header(skb);
444 	skb->protocol = eth_type_trans(skb, mesh_iface);
445 	batadv_inc_counter(bat_priv, BATADV_CNT_RX);
446 	batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
447 			   skb->len + ETH_HLEN);
448 
449 	netif_rx(skb);
450 out:
451 	batadv_hardif_put(primary_if);
452 }
453 
454 /**
455  * batadv_bla_loopdetect_report() - worker for reporting the loop
456  * @work: work queue item
457  *
458  * Throws an uevent, as the loopdetect check function can't do that itself
459  * since the kernel may sleep while throwing uevents.
460  */
batadv_bla_loopdetect_report(struct work_struct * work)461 static void batadv_bla_loopdetect_report(struct work_struct *work)
462 {
463 	struct batadv_bla_backbone_gw *backbone_gw;
464 	struct batadv_priv *bat_priv;
465 	char vid_str[6] = { '\0' };
466 
467 	backbone_gw = container_of(work, struct batadv_bla_backbone_gw,
468 				   report_work);
469 	bat_priv = backbone_gw->bat_priv;
470 
471 	batadv_info(bat_priv->mesh_iface,
472 		    "Possible loop on VLAN %d detected which can't be handled by BLA - please check your network setup!\n",
473 		    batadv_print_vid(backbone_gw->vid));
474 	snprintf(vid_str, sizeof(vid_str), "%d",
475 		 batadv_print_vid(backbone_gw->vid));
476 	vid_str[sizeof(vid_str) - 1] = 0;
477 
478 	batadv_throw_uevent(bat_priv, BATADV_UEV_BLA, BATADV_UEV_LOOPDETECT,
479 			    vid_str);
480 
481 	batadv_backbone_gw_put(backbone_gw);
482 }
483 
484 /**
485  * batadv_bla_get_backbone_gw() - finds or creates a backbone gateway
486  * @bat_priv: the bat priv with all the mesh interface information
487  * @orig: the mac address of the originator
488  * @vid: the VLAN ID
489  * @own_backbone: set if the requested backbone is local
490  *
491  * Return: the (possibly created) backbone gateway or NULL on error
492  */
493 static struct batadv_bla_backbone_gw *
batadv_bla_get_backbone_gw(struct batadv_priv * bat_priv,const u8 * orig,unsigned short vid,bool own_backbone)494 batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, const u8 *orig,
495 			   unsigned short vid, bool own_backbone)
496 {
497 	struct batadv_bla_backbone_gw *entry;
498 	struct batadv_orig_node *orig_node;
499 	int hash_added;
500 
501 	entry = batadv_backbone_hash_find(bat_priv, orig, vid);
502 
503 	if (entry)
504 		return entry;
505 
506 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
507 		   "%s(): not found (%pM, %d), creating new entry\n", __func__,
508 		   orig, batadv_print_vid(vid));
509 
510 	entry = kzalloc_obj(*entry, GFP_ATOMIC);
511 	if (!entry)
512 		return NULL;
513 
514 	entry->vid = vid;
515 	entry->lasttime = jiffies;
516 	entry->crc = BATADV_BLA_CRC_INIT;
517 	entry->bat_priv = bat_priv;
518 	spin_lock_init(&entry->crc_lock);
519 	entry->state = BATADV_BLA_BACKBONE_GW_SYNCED;
520 	entry->wait_periods = 0;
521 	ether_addr_copy(entry->orig, orig);
522 	INIT_WORK(&entry->report_work, batadv_bla_loopdetect_report);
523 	kref_init(&entry->refcount);
524 
525 	kref_get(&entry->refcount);
526 	hash_added = batadv_hash_add(bat_priv->bla.backbone_hash,
527 				     batadv_compare_backbone_gw,
528 				     batadv_choose_backbone_gw, entry,
529 				     &entry->hash_entry);
530 
531 	if (unlikely(hash_added != 0)) {
532 		/* hash failed, free the structure */
533 		kfree(entry);
534 		return NULL;
535 	}
536 
537 	/* this is a gateway now, remove any TT entry on this VLAN */
538 	orig_node = batadv_orig_hash_find(bat_priv, orig);
539 	if (orig_node) {
540 		batadv_tt_global_del_orig(bat_priv, orig_node, vid,
541 					  "became a backbone gateway");
542 		batadv_orig_node_put(orig_node);
543 	}
544 
545 	if (own_backbone) {
546 		batadv_bla_send_announce(bat_priv, entry);
547 
548 		/* this will be decreased in the worker thread */
549 		spin_lock_bh(&bat_priv->bla.num_requests_lock);
550 		if (entry->state == BATADV_BLA_BACKBONE_GW_SYNCED) {
551 			entry->state = BATADV_BLA_BACKBONE_GW_UNSYNCED;
552 			entry->wait_periods = BATADV_BLA_WAIT_PERIODS;
553 			atomic_inc(&bat_priv->bla.num_requests);
554 		}
555 		spin_unlock_bh(&bat_priv->bla.num_requests_lock);
556 	}
557 
558 	return entry;
559 }
560 
561 /**
562  * batadv_bla_update_own_backbone_gw() - updates the own backbone gw for a VLAN
563  * @bat_priv: the bat priv with all the mesh interface information
564  * @primary_if: the selected primary interface
565  * @vid: VLAN identifier
566  *
567  * update or add the own backbone gw to make sure we announce
568  * where we receive other backbone gws
569  */
570 static void
batadv_bla_update_own_backbone_gw(struct batadv_priv * bat_priv,struct batadv_hard_iface * primary_if,unsigned short vid)571 batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,
572 				  struct batadv_hard_iface *primary_if,
573 				  unsigned short vid)
574 {
575 	struct batadv_bla_backbone_gw *backbone_gw;
576 
577 	backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
578 						 primary_if->net_dev->dev_addr,
579 						 vid, true);
580 	if (unlikely(!backbone_gw))
581 		return;
582 
583 	backbone_gw->lasttime = jiffies;
584 	batadv_backbone_gw_put(backbone_gw);
585 }
586 
587 /**
588  * batadv_bla_answer_request() - answer a bla request by sending own claims
589  * @bat_priv: the bat priv with all the mesh interface information
590  * @primary_if: interface where the request came on
591  * @vid: the vid where the request came on
592  *
593  * Repeat all of our own claims, and finally send an ANNOUNCE frame
594  * to allow the requester another check if the CRC is correct now.
595  */
batadv_bla_answer_request(struct batadv_priv * bat_priv,struct batadv_hard_iface * primary_if,unsigned short vid)596 static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
597 				      struct batadv_hard_iface *primary_if,
598 				      unsigned short vid)
599 {
600 	struct hlist_head *head;
601 	struct batadv_hashtable *hash;
602 	struct batadv_bla_claim *claim;
603 	struct batadv_bla_backbone_gw *backbone_gw;
604 	int i;
605 
606 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
607 		   "%s(): received a claim request, send all of our own claims again\n",
608 		   __func__);
609 
610 	backbone_gw = batadv_backbone_hash_find(bat_priv,
611 						primary_if->net_dev->dev_addr,
612 						vid);
613 	if (!backbone_gw)
614 		return;
615 
616 	hash = bat_priv->bla.claim_hash;
617 	for (i = 0; i < hash->size; i++) {
618 		head = &hash->table[i];
619 
620 		rcu_read_lock();
621 		hlist_for_each_entry_rcu(claim, head, hash_entry) {
622 			/* only own claims are interesting */
623 			if (claim->backbone_gw != backbone_gw)
624 				continue;
625 
626 			batadv_bla_send_claim(bat_priv, claim->addr, claim->vid,
627 					      BATADV_CLAIM_TYPE_CLAIM);
628 		}
629 		rcu_read_unlock();
630 	}
631 
632 	/* finally, send an announcement frame */
633 	batadv_bla_send_announce(bat_priv, backbone_gw);
634 	batadv_backbone_gw_put(backbone_gw);
635 }
636 
637 /**
638  * batadv_bla_send_request() - send a request to repeat claims
639  * @backbone_gw: the backbone gateway from whom we are out of sync
640  *
641  * When the crc is wrong, ask the backbone gateway for a full table update.
642  * After the request, it will repeat all of his own claims and finally
643  * send an announcement claim with which we can check again.
644  */
batadv_bla_send_request(struct batadv_bla_backbone_gw * backbone_gw)645 static void batadv_bla_send_request(struct batadv_bla_backbone_gw *backbone_gw)
646 {
647 	/* first, remove all old entries */
648 	batadv_bla_del_backbone_claims(backbone_gw);
649 
650 	batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
651 		   "Sending REQUEST to %pM\n", backbone_gw->orig);
652 
653 	/* send request */
654 	batadv_bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig,
655 			      backbone_gw->vid, BATADV_CLAIM_TYPE_REQUEST);
656 
657 	/* no local broadcasts should be sent or received, for now. */
658 	spin_lock_bh(&backbone_gw->bat_priv->bla.num_requests_lock);
659 	if (backbone_gw->state == BATADV_BLA_BACKBONE_GW_SYNCED) {
660 		backbone_gw->state = BATADV_BLA_BACKBONE_GW_UNSYNCED;
661 		atomic_inc(&backbone_gw->bat_priv->bla.num_requests);
662 	}
663 	spin_unlock_bh(&backbone_gw->bat_priv->bla.num_requests_lock);
664 }
665 
666 /**
667  * batadv_bla_send_announce() - Send an announcement frame
668  * @bat_priv: the bat priv with all the mesh interface information
669  * @backbone_gw: our backbone gateway which should be announced
670  */
batadv_bla_send_announce(struct batadv_priv * bat_priv,struct batadv_bla_backbone_gw * backbone_gw)671 static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
672 				     struct batadv_bla_backbone_gw *backbone_gw)
673 {
674 	u8 mac[ETH_ALEN];
675 	__be16 crc;
676 
677 	memcpy(mac, batadv_announce_mac, 4);
678 	spin_lock_bh(&backbone_gw->crc_lock);
679 	crc = htons(backbone_gw->crc);
680 	spin_unlock_bh(&backbone_gw->crc_lock);
681 	memcpy(&mac[4], &crc, 2);
682 
683 	batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
684 			      BATADV_CLAIM_TYPE_ANNOUNCE);
685 }
686 
687 /**
688  * batadv_bla_add_claim() - Adds a claim in the claim hash
689  * @bat_priv: the bat priv with all the mesh interface information
690  * @mac: the mac address of the claim
691  * @vid: the VLAN ID of the frame
692  * @backbone_gw: the backbone gateway which claims it
693  */
batadv_bla_add_claim(struct batadv_priv * bat_priv,const u8 * mac,const unsigned short vid,struct batadv_bla_backbone_gw * backbone_gw)694 static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
695 				 const u8 *mac, const unsigned short vid,
696 				 struct batadv_bla_backbone_gw *backbone_gw)
697 {
698 	struct batadv_bla_backbone_gw *old_backbone_gw;
699 	struct batadv_bla_claim *claim;
700 	struct batadv_bla_claim search_claim;
701 	bool remove_crc = false;
702 	int hash_added;
703 
704 	ether_addr_copy(search_claim.addr, mac);
705 	search_claim.vid = vid;
706 	claim = batadv_claim_hash_find(bat_priv, &search_claim);
707 
708 	/* create a new claim entry if it does not exist yet. */
709 	if (!claim) {
710 		claim = kzalloc_obj(*claim, GFP_ATOMIC);
711 		if (!claim)
712 			return;
713 
714 		ether_addr_copy(claim->addr, mac);
715 		spin_lock_init(&claim->backbone_lock);
716 		claim->vid = vid;
717 		claim->lasttime = jiffies;
718 		kref_get(&backbone_gw->refcount);
719 		claim->backbone_gw = backbone_gw;
720 		kref_init(&claim->refcount);
721 
722 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
723 			   "%s(): adding new entry %pM, vid %d to hash ...\n",
724 			   __func__, mac, batadv_print_vid(vid));
725 
726 		kref_get(&claim->refcount);
727 		hash_added = batadv_hash_add(bat_priv->bla.claim_hash,
728 					     batadv_compare_claim,
729 					     batadv_choose_claim, claim,
730 					     &claim->hash_entry);
731 
732 		if (unlikely(hash_added != 0)) {
733 			/* only local changes happened. */
734 			batadv_backbone_gw_put(backbone_gw);
735 			kfree(claim);
736 			return;
737 		}
738 	} else {
739 		claim->lasttime = jiffies;
740 		if (claim->backbone_gw == backbone_gw)
741 			/* no need to register a new backbone */
742 			goto claim_free_ref;
743 
744 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
745 			   "%s(): changing ownership for %pM, vid %d to gw %pM\n",
746 			   __func__, mac, batadv_print_vid(vid),
747 			   backbone_gw->orig);
748 
749 		remove_crc = true;
750 	}
751 
752 	/* replace backbone_gw atomically and adjust reference counters */
753 	spin_lock_bh(&claim->backbone_lock);
754 	old_backbone_gw = claim->backbone_gw;
755 	kref_get(&backbone_gw->refcount);
756 	claim->backbone_gw = backbone_gw;
757 	spin_unlock_bh(&claim->backbone_lock);
758 
759 	if (remove_crc) {
760 		/* remove claim address from old backbone_gw */
761 		spin_lock_bh(&old_backbone_gw->crc_lock);
762 		old_backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
763 		spin_unlock_bh(&old_backbone_gw->crc_lock);
764 	}
765 
766 	batadv_backbone_gw_put(old_backbone_gw);
767 
768 	/* add claim address to new backbone_gw */
769 	spin_lock_bh(&backbone_gw->crc_lock);
770 	backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
771 	spin_unlock_bh(&backbone_gw->crc_lock);
772 	backbone_gw->lasttime = jiffies;
773 
774 claim_free_ref:
775 	batadv_claim_put(claim);
776 }
777 
778 /**
779  * batadv_bla_claim_get_backbone_gw() - Get valid reference for backbone_gw of
780  *  claim
781  * @claim: claim whose backbone_gw should be returned
782  *
783  * Return: valid reference to claim::backbone_gw
784  */
785 static struct batadv_bla_backbone_gw *
batadv_bla_claim_get_backbone_gw(struct batadv_bla_claim * claim)786 batadv_bla_claim_get_backbone_gw(struct batadv_bla_claim *claim)
787 {
788 	struct batadv_bla_backbone_gw *backbone_gw;
789 
790 	spin_lock_bh(&claim->backbone_lock);
791 	backbone_gw = claim->backbone_gw;
792 	kref_get(&backbone_gw->refcount);
793 	spin_unlock_bh(&claim->backbone_lock);
794 
795 	return backbone_gw;
796 }
797 
798 /**
799  * batadv_bla_del_claim() - delete a claim from the claim hash
800  * @bat_priv: the bat priv with all the mesh interface information
801  * @mac: mac address of the claim to be removed
802  * @vid: VLAN id for the claim to be removed
803  */
batadv_bla_del_claim(struct batadv_priv * bat_priv,const u8 * mac,const unsigned short vid)804 static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
805 				 const u8 *mac, const unsigned short vid)
806 {
807 	struct batadv_bla_claim search_claim, *claim;
808 	struct batadv_bla_claim *claim_removed_entry;
809 	struct hlist_node *claim_removed_node;
810 
811 	ether_addr_copy(search_claim.addr, mac);
812 	search_claim.vid = vid;
813 	claim = batadv_claim_hash_find(bat_priv, &search_claim);
814 	if (!claim)
815 		return;
816 
817 	batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): %pM, vid %d\n", __func__,
818 		   mac, batadv_print_vid(vid));
819 
820 	claim_removed_node = batadv_hash_remove(bat_priv->bla.claim_hash,
821 						batadv_compare_claim,
822 						batadv_choose_claim, claim);
823 	if (!claim_removed_node)
824 		goto free_claim;
825 
826 	/* reference from the hash is gone */
827 	claim_removed_entry = hlist_entry(claim_removed_node,
828 					  struct batadv_bla_claim, hash_entry);
829 	batadv_claim_put(claim_removed_entry);
830 
831 free_claim:
832 	/* don't need the reference from hash_find() anymore */
833 	batadv_claim_put(claim);
834 }
835 
836 /**
837  * batadv_handle_announce() - check for ANNOUNCE frame
838  * @bat_priv: the bat priv with all the mesh interface information
839  * @an_addr: announcement mac address (ARP Sender HW address)
840  * @backbone_addr: originator address of the sender (Ethernet source MAC)
841  * @vid: the VLAN ID of the frame
842  *
843  * Return: true if handled
844  */
batadv_handle_announce(struct batadv_priv * bat_priv,u8 * an_addr,u8 * backbone_addr,unsigned short vid)845 static bool batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr,
846 				   u8 *backbone_addr, unsigned short vid)
847 {
848 	struct batadv_bla_backbone_gw *backbone_gw;
849 	u16 backbone_crc, crc;
850 
851 	if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
852 		return false;
853 
854 	backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
855 						 false);
856 
857 	if (unlikely(!backbone_gw))
858 		return true;
859 
860 	/* handle as ANNOUNCE frame */
861 	backbone_gw->lasttime = jiffies;
862 	crc = ntohs(*((__force __be16 *)(&an_addr[4])));
863 
864 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
865 		   "%s(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n",
866 		   __func__, batadv_print_vid(vid), backbone_gw->orig, crc);
867 
868 	spin_lock_bh(&backbone_gw->crc_lock);
869 	backbone_crc = backbone_gw->crc;
870 	spin_unlock_bh(&backbone_gw->crc_lock);
871 
872 	if (backbone_crc != crc) {
873 		batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
874 			   "%s(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n",
875 			   __func__, backbone_gw->orig,
876 			   batadv_print_vid(backbone_gw->vid),
877 			   backbone_crc, crc);
878 
879 		batadv_bla_send_request(backbone_gw);
880 	} else {
881 		/* if we have sent a request and the crc was OK,
882 		 * we can allow traffic again.
883 		 */
884 		spin_lock_bh(&bat_priv->bla.num_requests_lock);
885 		if (backbone_gw->state == BATADV_BLA_BACKBONE_GW_UNSYNCED) {
886 			backbone_gw->state = BATADV_BLA_BACKBONE_GW_SYNCED;
887 			atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
888 		}
889 		spin_unlock_bh(&bat_priv->bla.num_requests_lock);
890 	}
891 
892 	batadv_backbone_gw_put(backbone_gw);
893 	return true;
894 }
895 
896 /**
897  * batadv_handle_request() - check for REQUEST frame
898  * @bat_priv: the bat priv with all the mesh interface information
899  * @primary_if: the primary hard interface of this batman mesh interface
900  * @backbone_addr: backbone address to be requested (ARP sender HW MAC)
901  * @ethhdr: ethernet header of a packet
902  * @vid: the VLAN ID of the frame
903  *
904  * Return: true if handled
905  */
batadv_handle_request(struct batadv_priv * bat_priv,struct batadv_hard_iface * primary_if,u8 * backbone_addr,struct ethhdr * ethhdr,unsigned short vid)906 static bool batadv_handle_request(struct batadv_priv *bat_priv,
907 				  struct batadv_hard_iface *primary_if,
908 				  u8 *backbone_addr, struct ethhdr *ethhdr,
909 				  unsigned short vid)
910 {
911 	/* check for REQUEST frame */
912 	if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest))
913 		return false;
914 
915 	/* sanity check, this should not happen on a normal switch,
916 	 * we ignore it in this case.
917 	 */
918 	if (!batadv_compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr))
919 		return true;
920 
921 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
922 		   "%s(): REQUEST vid %d (sent by %pM)...\n",
923 		   __func__, batadv_print_vid(vid), ethhdr->h_source);
924 
925 	batadv_bla_answer_request(bat_priv, primary_if, vid);
926 	return true;
927 }
928 
929 /**
930  * batadv_handle_unclaim() - check for UNCLAIM frame
931  * @bat_priv: the bat priv with all the mesh interface information
932  * @primary_if: the primary hard interface of this batman mesh interface
933  * @backbone_addr: originator address of the backbone (Ethernet source)
934  * @claim_addr: Client to be unclaimed (ARP sender HW MAC)
935  * @vid: the VLAN ID of the frame
936  *
937  * Return: true if handled
938  */
batadv_handle_unclaim(struct batadv_priv * bat_priv,struct batadv_hard_iface * primary_if,const u8 * backbone_addr,const u8 * claim_addr,unsigned short vid)939 static bool batadv_handle_unclaim(struct batadv_priv *bat_priv,
940 				  struct batadv_hard_iface *primary_if,
941 				  const u8 *backbone_addr, const u8 *claim_addr,
942 				  unsigned short vid)
943 {
944 	struct batadv_bla_backbone_gw *backbone_gw;
945 
946 	/* unclaim in any case if it is our own */
947 	if (primary_if && batadv_compare_eth(backbone_addr,
948 					     primary_if->net_dev->dev_addr))
949 		batadv_bla_send_claim(bat_priv, claim_addr, vid,
950 				      BATADV_CLAIM_TYPE_UNCLAIM);
951 
952 	backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid);
953 
954 	if (!backbone_gw)
955 		return true;
956 
957 	/* this must be an UNCLAIM frame */
958 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
959 		   "%s(): UNCLAIM %pM on vid %d (sent by %pM)...\n", __func__,
960 		   claim_addr, batadv_print_vid(vid), backbone_gw->orig);
961 
962 	batadv_bla_del_claim(bat_priv, claim_addr, vid);
963 	batadv_backbone_gw_put(backbone_gw);
964 	return true;
965 }
966 
967 /**
968  * batadv_handle_claim() - check for CLAIM frame
969  * @bat_priv: the bat priv with all the mesh interface information
970  * @primary_if: the primary hard interface of this batman mesh interface
971  * @backbone_addr: originator address of the backbone (Ethernet Source)
972  * @claim_addr: client mac address to be claimed (ARP sender HW MAC)
973  * @vid: the VLAN ID of the frame
974  *
975  * Return: true if handled
976  */
batadv_handle_claim(struct batadv_priv * bat_priv,struct batadv_hard_iface * primary_if,const u8 * backbone_addr,const u8 * claim_addr,unsigned short vid)977 static bool batadv_handle_claim(struct batadv_priv *bat_priv,
978 				struct batadv_hard_iface *primary_if,
979 				const u8 *backbone_addr, const u8 *claim_addr,
980 				unsigned short vid)
981 {
982 	struct batadv_bla_backbone_gw *backbone_gw;
983 
984 	/* register the gateway if not yet available, and add the claim. */
985 
986 	backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
987 						 false);
988 
989 	if (unlikely(!backbone_gw))
990 		return true;
991 
992 	/* this must be a CLAIM frame */
993 	batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw);
994 	if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
995 		batadv_bla_send_claim(bat_priv, claim_addr, vid,
996 				      BATADV_CLAIM_TYPE_CLAIM);
997 
998 	/* TODO: we could call something like tt_local_del() here. */
999 
1000 	batadv_backbone_gw_put(backbone_gw);
1001 	return true;
1002 }
1003 
1004 /**
1005  * batadv_check_claim_group() - check for claim group membership
1006  * @bat_priv: the bat priv with all the mesh interface information
1007  * @primary_if: the primary interface of this batman interface
1008  * @hw_src: the Hardware source in the ARP Header
1009  * @hw_dst: the Hardware destination in the ARP Header
1010  * @ethhdr: pointer to the Ethernet header of the claim frame
1011  *
1012  * checks if it is a claim packet and if it's on the same group.
1013  * This function also applies the group ID of the sender
1014  * if it is in the same mesh.
1015  *
1016  * Return:
1017  *	2  - if it is a claim packet and on the same group
1018  *	1  - if is a claim packet from another group
1019  *	0  - if it is not a claim packet
1020  */
batadv_check_claim_group(struct batadv_priv * bat_priv,struct batadv_hard_iface * primary_if,u8 * hw_src,u8 * hw_dst,struct ethhdr * ethhdr)1021 static int batadv_check_claim_group(struct batadv_priv *bat_priv,
1022 				    struct batadv_hard_iface *primary_if,
1023 				    u8 *hw_src, u8 *hw_dst,
1024 				    struct ethhdr *ethhdr)
1025 {
1026 	u8 *backbone_addr;
1027 	struct batadv_orig_node *orig_node;
1028 	struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
1029 
1030 	bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
1031 	bla_dst_own = &bat_priv->bla.claim_dest;
1032 
1033 	/* if announcement packet, use the source,
1034 	 * otherwise assume it is in the hw_src
1035 	 */
1036 	switch (bla_dst->type) {
1037 	case BATADV_CLAIM_TYPE_CLAIM:
1038 		backbone_addr = hw_src;
1039 		break;
1040 	case BATADV_CLAIM_TYPE_REQUEST:
1041 	case BATADV_CLAIM_TYPE_ANNOUNCE:
1042 	case BATADV_CLAIM_TYPE_UNCLAIM:
1043 		backbone_addr = ethhdr->h_source;
1044 		break;
1045 	default:
1046 		return 0;
1047 	}
1048 
1049 	/* don't accept claim frames from ourselves */
1050 	if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
1051 		return 0;
1052 
1053 	/* if its already the same group, it is fine. */
1054 	if (bla_dst->group == bla_dst_own->group)
1055 		return 2;
1056 
1057 	/* lets see if this originator is in our mesh */
1058 	orig_node = batadv_orig_hash_find(bat_priv, backbone_addr);
1059 
1060 	/* don't accept claims from gateways which are not in
1061 	 * the same mesh or group.
1062 	 */
1063 	if (!orig_node)
1064 		return 1;
1065 
1066 	/* if our mesh friends mac is bigger, use it for ourselves. */
1067 	if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) {
1068 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
1069 			   "taking other backbones claim group: %#.4x\n",
1070 			   ntohs(bla_dst->group));
1071 		bla_dst_own->group = bla_dst->group;
1072 	}
1073 
1074 	batadv_orig_node_put(orig_node);
1075 
1076 	return 2;
1077 }
1078 
1079 /**
1080  * batadv_bla_process_claim() - Check if this is a claim frame, and process it
1081  * @bat_priv: the bat priv with all the mesh interface information
1082  * @primary_if: the primary hard interface of this batman mesh interface
1083  * @skb: the frame to be checked
1084  *
1085  * Return: true if it was a claim frame, otherwise return false to
1086  * tell the callee that it can use the frame on its own.
1087  */
batadv_bla_process_claim(struct batadv_priv * bat_priv,struct batadv_hard_iface * primary_if,struct sk_buff * skb)1088 static bool batadv_bla_process_claim(struct batadv_priv *bat_priv,
1089 				     struct batadv_hard_iface *primary_if,
1090 				     struct sk_buff *skb)
1091 {
1092 	struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
1093 	u8 *hw_src, *hw_dst;
1094 	struct vlan_hdr *vhdr, vhdr_buf;
1095 	struct ethhdr *ethhdr;
1096 	struct arphdr *arphdr;
1097 	unsigned short vid;
1098 	int vlan_depth = 0;
1099 	__be16 proto;
1100 	int headlen;
1101 	int ret;
1102 
1103 	vid = batadv_get_vid(skb, 0);
1104 	ethhdr = eth_hdr(skb);
1105 
1106 	proto = ethhdr->h_proto;
1107 	headlen = ETH_HLEN;
1108 	if (vid & BATADV_VLAN_HAS_TAG) {
1109 		/* Traverse the VLAN/Ethertypes.
1110 		 *
1111 		 * At this point it is known that the first protocol is a VLAN
1112 		 * header, so start checking at the encapsulated protocol.
1113 		 *
1114 		 * The depth of the VLAN headers is recorded to drop BLA claim
1115 		 * frames encapsulated into multiple VLAN headers (QinQ).
1116 		 */
1117 		do {
1118 			vhdr = skb_header_pointer(skb, headlen, VLAN_HLEN,
1119 						  &vhdr_buf);
1120 			if (!vhdr)
1121 				return false;
1122 
1123 			proto = vhdr->h_vlan_encapsulated_proto;
1124 			headlen += VLAN_HLEN;
1125 			vlan_depth++;
1126 		} while (proto == htons(ETH_P_8021Q));
1127 	}
1128 
1129 	if (proto != htons(ETH_P_ARP))
1130 		return false; /* not a claim frame */
1131 
1132 	/* this must be a ARP frame. check if it is a claim. */
1133 
1134 	if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev))))
1135 		return false;
1136 
1137 	/* pskb_may_pull() may have modified the pointers, get ethhdr again */
1138 	ethhdr = eth_hdr(skb);
1139 	arphdr = (struct arphdr *)((u8 *)ethhdr + headlen);
1140 
1141 	/* Check whether the ARP frame carries a valid
1142 	 * IP information
1143 	 */
1144 	if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
1145 		return false;
1146 	if (arphdr->ar_pro != htons(ETH_P_IP))
1147 		return false;
1148 	if (arphdr->ar_hln != ETH_ALEN)
1149 		return false;
1150 	if (arphdr->ar_pln != 4)
1151 		return false;
1152 
1153 	hw_src = (u8 *)arphdr + sizeof(struct arphdr);
1154 	hw_dst = hw_src + ETH_ALEN + 4;
1155 	bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
1156 	bla_dst_own = &bat_priv->bla.claim_dest;
1157 
1158 	/* check if it is a claim frame in general */
1159 	if (memcmp(bla_dst->magic, bla_dst_own->magic,
1160 		   sizeof(bla_dst->magic)) != 0)
1161 		return false;
1162 
1163 	/* check if there is a claim frame encapsulated deeper in (QinQ) and
1164 	 * drop that, as this is not supported by BLA but should also not be
1165 	 * sent via the mesh.
1166 	 */
1167 	if (vlan_depth > 1)
1168 		return true;
1169 
1170 	/* Let the loopdetect frames on the mesh in any case. */
1171 	if (bla_dst->type == BATADV_CLAIM_TYPE_LOOPDETECT)
1172 		return false;
1173 
1174 	/* check if it is a claim frame. */
1175 	ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst,
1176 				       ethhdr);
1177 	if (ret == 1)
1178 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
1179 			   "%s(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
1180 			   __func__, ethhdr->h_source, batadv_print_vid(vid),
1181 			   hw_src, hw_dst);
1182 
1183 	if (ret < 2)
1184 		return !!ret;
1185 
1186 	/* become a backbone gw ourselves on this vlan if not happened yet */
1187 	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
1188 
1189 	/* check for the different types of claim frames ... */
1190 	switch (bla_dst->type) {
1191 	case BATADV_CLAIM_TYPE_CLAIM:
1192 		if (batadv_handle_claim(bat_priv, primary_if, hw_src,
1193 					ethhdr->h_source, vid))
1194 			return true;
1195 		break;
1196 	case BATADV_CLAIM_TYPE_UNCLAIM:
1197 		if (batadv_handle_unclaim(bat_priv, primary_if,
1198 					  ethhdr->h_source, hw_src, vid))
1199 			return true;
1200 		break;
1201 
1202 	case BATADV_CLAIM_TYPE_ANNOUNCE:
1203 		if (batadv_handle_announce(bat_priv, hw_src, ethhdr->h_source,
1204 					   vid))
1205 			return true;
1206 		break;
1207 	case BATADV_CLAIM_TYPE_REQUEST:
1208 		if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr,
1209 					  vid))
1210 			return true;
1211 		break;
1212 	}
1213 
1214 	batadv_dbg(BATADV_DBG_BLA, bat_priv,
1215 		   "%s(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
1216 		   __func__, ethhdr->h_source, batadv_print_vid(vid), hw_src,
1217 		   hw_dst);
1218 	return true;
1219 }
1220 
1221 /**
1222  * batadv_bla_purge_backbone_gw() - Remove backbone gateways after a timeout or
1223  *  immediately
1224  * @bat_priv: the bat priv with all the mesh interface information
1225  * @now: whether the whole hash shall be wiped now
1226  *
1227  * Check when we last heard from other nodes, and remove them in case of
1228  * a time out, or clean all backbone gws if now is set.
1229  */
batadv_bla_purge_backbone_gw(struct batadv_priv * bat_priv,int now)1230 static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
1231 {
1232 	struct batadv_bla_backbone_gw *backbone_gw;
1233 	struct hlist_node *node_tmp;
1234 	struct hlist_head *head;
1235 	struct batadv_hashtable *hash;
1236 	spinlock_t *list_lock;	/* protects write access to the hash lists */
1237 	bool purged;
1238 	int i;
1239 
1240 	hash = bat_priv->bla.backbone_hash;
1241 	if (!hash)
1242 		return;
1243 
1244 	for (i = 0; i < hash->size; i++) {
1245 		head = &hash->table[i];
1246 		list_lock = &hash->list_locks[i];
1247 
1248 		do {
1249 			purged = false;
1250 
1251 			spin_lock_bh(list_lock);
1252 			hlist_for_each_entry_safe(backbone_gw, node_tmp,
1253 						  head, hash_entry) {
1254 				if (now)
1255 					goto purge_now;
1256 				if (!batadv_has_timed_out(backbone_gw->lasttime,
1257 							  BATADV_BLA_BACKBONE_TIMEOUT))
1258 					continue;
1259 
1260 				batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
1261 					   "%s(): backbone gw %pM timed out\n",
1262 					   __func__, backbone_gw->orig);
1263 
1264 purge_now:
1265 				purged = true;
1266 
1267 				/* don't wait for the pending request anymore */
1268 				spin_lock_bh(&bat_priv->bla.num_requests_lock);
1269 				if (backbone_gw->state == BATADV_BLA_BACKBONE_GW_UNSYNCED)
1270 					atomic_dec(&bat_priv->bla.num_requests);
1271 
1272 				backbone_gw->state = BATADV_BLA_BACKBONE_GW_STOPPED;
1273 				spin_unlock_bh(&bat_priv->bla.num_requests_lock);
1274 
1275 				batadv_bla_del_backbone_claims(backbone_gw);
1276 
1277 				hlist_del_rcu(&backbone_gw->hash_entry);
1278 				break;
1279 			}
1280 			spin_unlock_bh(list_lock);
1281 
1282 			if (purged) {
1283 				/* reference for pending report_work */
1284 				if (cancel_work_sync(&backbone_gw->report_work))
1285 					batadv_backbone_gw_put(backbone_gw);
1286 
1287 				/* reference for hash_entry */
1288 				batadv_backbone_gw_put(backbone_gw);
1289 			}
1290 		} while (purged);
1291 	}
1292 }
1293 
1294 /**
1295  * batadv_bla_purge_claims() - Remove claims after a timeout or immediately
1296  * @bat_priv: the bat priv with all the mesh interface information
1297  * @primary_if: the selected primary interface, may be NULL if now is set
1298  * @now: whether the whole hash shall be wiped now
1299  *
1300  * Check when we heard last time from our own claims, and remove them in case of
1301  * a time out, or clean all claims if now is set
1302  */
batadv_bla_purge_claims(struct batadv_priv * bat_priv,struct batadv_hard_iface * primary_if,int now)1303 static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
1304 				    struct batadv_hard_iface *primary_if,
1305 				    int now)
1306 {
1307 	struct batadv_bla_backbone_gw *backbone_gw;
1308 	struct batadv_bla_claim *claim;
1309 	struct hlist_head *head;
1310 	struct batadv_hashtable *hash;
1311 	int i;
1312 
1313 	hash = bat_priv->bla.claim_hash;
1314 	if (!hash)
1315 		return;
1316 
1317 	for (i = 0; i < hash->size; i++) {
1318 		head = &hash->table[i];
1319 
1320 		rcu_read_lock();
1321 		hlist_for_each_entry_rcu(claim, head, hash_entry) {
1322 			/* only purge claims not currently in the process of being released.
1323 			 * Such claims could otherwise have a NULL-ptr backbone_gw set because
1324 			 * they already went through batadv_claim_release()
1325 			 */
1326 			if (!kref_get_unless_zero(&claim->refcount))
1327 				continue;
1328 
1329 			backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
1330 			if (now)
1331 				goto purge_now;
1332 
1333 			if (!batadv_compare_eth(backbone_gw->orig,
1334 						primary_if->net_dev->dev_addr))
1335 				goto skip;
1336 
1337 			if (!batadv_has_timed_out(claim->lasttime,
1338 						  BATADV_BLA_CLAIM_TIMEOUT))
1339 				goto skip;
1340 
1341 			batadv_dbg(BATADV_DBG_BLA, bat_priv,
1342 				   "%s(): timed out.\n", __func__);
1343 
1344 purge_now:
1345 			batadv_dbg(BATADV_DBG_BLA, bat_priv,
1346 				   "%s(): %pM, vid %d\n", __func__,
1347 				   claim->addr, claim->vid);
1348 
1349 			batadv_handle_unclaim(bat_priv, primary_if,
1350 					      backbone_gw->orig,
1351 					      claim->addr, claim->vid);
1352 skip:
1353 			batadv_backbone_gw_put(backbone_gw);
1354 			batadv_claim_put(claim);
1355 		}
1356 		rcu_read_unlock();
1357 	}
1358 }
1359 
1360 /**
1361  * batadv_bla_update_orig_address() - Update the backbone gateways when the own
1362  *  originator address changes
1363  * @bat_priv: the bat priv with all the mesh interface information
1364  * @primary_if: the new selected primary_if
1365  * @oldif: the old primary interface, may be NULL
1366  */
batadv_bla_update_orig_address(struct batadv_priv * bat_priv,struct batadv_hard_iface * primary_if,struct batadv_hard_iface * oldif)1367 void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
1368 				    struct batadv_hard_iface *primary_if,
1369 				    struct batadv_hard_iface *oldif)
1370 {
1371 	struct batadv_bla_backbone_gw *backbone_gw;
1372 	struct hlist_head *head;
1373 	struct batadv_hashtable *hash;
1374 	__be16 group;
1375 	int i;
1376 
1377 	/* reset bridge loop avoidance group id */
1378 	group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN));
1379 	bat_priv->bla.claim_dest.group = group;
1380 
1381 	/* purge everything when bridge loop avoidance is turned off */
1382 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1383 		oldif = NULL;
1384 
1385 	if (!oldif) {
1386 		batadv_bla_purge_claims(bat_priv, NULL, 1);
1387 		batadv_bla_purge_backbone_gw(bat_priv, 1);
1388 		return;
1389 	}
1390 
1391 	hash = bat_priv->bla.backbone_hash;
1392 	if (!hash)
1393 		return;
1394 
1395 	for (i = 0; i < hash->size; i++) {
1396 		head = &hash->table[i];
1397 
1398 		rcu_read_lock();
1399 		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
1400 			/* own orig still holds the old value. */
1401 			if (!batadv_compare_eth(backbone_gw->orig,
1402 						oldif->net_dev->dev_addr))
1403 				continue;
1404 
1405 			ether_addr_copy(backbone_gw->orig,
1406 					primary_if->net_dev->dev_addr);
1407 			/* send an announce frame so others will ask for our
1408 			 * claims and update their tables.
1409 			 */
1410 			batadv_bla_send_announce(bat_priv, backbone_gw);
1411 		}
1412 		rcu_read_unlock();
1413 	}
1414 }
1415 
1416 /**
1417  * batadv_bla_send_loopdetect() - send a loopdetect frame
1418  * @bat_priv: the bat priv with all the mesh interface information
1419  * @backbone_gw: the backbone gateway for which a loop should be detected
1420  *
1421  * To detect loops that the bridge loop avoidance can't handle, send a loop
1422  * detection packet on the backbone. Unlike other BLA frames, this frame will
1423  * be allowed on the mesh by other nodes. If it is received on the mesh, this
1424  * indicates that there is a loop.
1425  */
1426 static void
batadv_bla_send_loopdetect(struct batadv_priv * bat_priv,struct batadv_bla_backbone_gw * backbone_gw)1427 batadv_bla_send_loopdetect(struct batadv_priv *bat_priv,
1428 			   struct batadv_bla_backbone_gw *backbone_gw)
1429 {
1430 	batadv_dbg(BATADV_DBG_BLA, bat_priv, "Send loopdetect frame for vid %d\n",
1431 		   backbone_gw->vid);
1432 	batadv_bla_send_claim(bat_priv, bat_priv->bla.loopdetect_addr,
1433 			      backbone_gw->vid, BATADV_CLAIM_TYPE_LOOPDETECT);
1434 }
1435 
1436 /**
1437  * batadv_bla_status_update() - purge bla interfaces if necessary
1438  * @net_dev: the mesh interface net device
1439  */
batadv_bla_status_update(struct net_device * net_dev)1440 void batadv_bla_status_update(struct net_device *net_dev)
1441 {
1442 	struct batadv_priv *bat_priv = netdev_priv(net_dev);
1443 	struct batadv_hard_iface *primary_if;
1444 
1445 	primary_if = batadv_primary_if_get_selected(bat_priv);
1446 	if (!primary_if)
1447 		return;
1448 
1449 	/* this function already purges everything when bla is disabled,
1450 	 * so just call that one.
1451 	 */
1452 	batadv_bla_update_orig_address(bat_priv, primary_if, primary_if);
1453 	batadv_hardif_put(primary_if);
1454 }
1455 
1456 /**
1457  * batadv_bla_periodic_work() - performs periodic bla work
1458  * @work: kernel work struct
1459  *
1460  * periodic work to do:
1461  *  * purge structures when they are too old
1462  *  * send announcements
1463  */
batadv_bla_periodic_work(struct work_struct * work)1464 static void batadv_bla_periodic_work(struct work_struct *work)
1465 {
1466 	struct delayed_work *delayed_work;
1467 	struct batadv_priv *bat_priv;
1468 	struct batadv_priv_bla *priv_bla;
1469 	struct hlist_head *head;
1470 	struct batadv_bla_backbone_gw *backbone_gw;
1471 	struct batadv_hashtable *hash;
1472 	struct batadv_hard_iface *primary_if;
1473 	bool send_loopdetect = false;
1474 	int i;
1475 
1476 	delayed_work = to_delayed_work(work);
1477 	priv_bla = container_of(delayed_work, struct batadv_priv_bla, work);
1478 	bat_priv = container_of(priv_bla, struct batadv_priv, bla);
1479 	primary_if = batadv_primary_if_get_selected(bat_priv);
1480 	if (!primary_if)
1481 		goto out;
1482 
1483 	batadv_bla_purge_claims(bat_priv, primary_if, 0);
1484 	batadv_bla_purge_backbone_gw(bat_priv, 0);
1485 
1486 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1487 		goto out;
1488 
1489 	if (atomic_dec_and_test(&bat_priv->bla.loopdetect_next)) {
1490 		/* set a new random mac address for the next bridge loop
1491 		 * detection frames. Set the locally administered bit to avoid
1492 		 * collisions with users mac addresses.
1493 		 */
1494 		eth_random_addr(bat_priv->bla.loopdetect_addr);
1495 		bat_priv->bla.loopdetect_addr[0] = 0xba;
1496 		bat_priv->bla.loopdetect_addr[1] = 0xbe;
1497 		bat_priv->bla.loopdetect_lasttime = jiffies;
1498 		atomic_set(&bat_priv->bla.loopdetect_next,
1499 			   BATADV_BLA_LOOPDETECT_PERIODS);
1500 
1501 		/* mark for sending loop detect on all VLANs */
1502 		send_loopdetect = true;
1503 	}
1504 
1505 	hash = bat_priv->bla.backbone_hash;
1506 	if (!hash)
1507 		goto out;
1508 
1509 	for (i = 0; i < hash->size; i++) {
1510 		head = &hash->table[i];
1511 
1512 		rcu_read_lock();
1513 		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
1514 			if (!batadv_compare_eth(backbone_gw->orig,
1515 						primary_if->net_dev->dev_addr))
1516 				continue;
1517 
1518 			backbone_gw->lasttime = jiffies;
1519 
1520 			batadv_bla_send_announce(bat_priv, backbone_gw);
1521 			if (send_loopdetect)
1522 				batadv_bla_send_loopdetect(bat_priv,
1523 							   backbone_gw);
1524 
1525 			/* state is only set to unsynced after creation to avoid
1526 			 * problems when we are not yet known as backbone gw
1527 			 * in the backbone.
1528 			 *
1529 			 * We can reset this now after we waited some periods
1530 			 * to give bridge forward delays and bla group forming
1531 			 * some grace time.
1532 			 */
1533 
1534 			spin_lock_bh(&bat_priv->bla.num_requests_lock);
1535 			if (backbone_gw->state != BATADV_BLA_BACKBONE_GW_UNSYNCED)
1536 				goto unlock_next;
1537 
1538 			if (backbone_gw->wait_periods > 0)
1539 				backbone_gw->wait_periods--;
1540 
1541 			if (backbone_gw->wait_periods > 0)
1542 				goto unlock_next;
1543 
1544 			backbone_gw->state = BATADV_BLA_BACKBONE_GW_SYNCED;
1545 			atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
1546 
1547 unlock_next:
1548 			spin_unlock_bh(&bat_priv->bla.num_requests_lock);
1549 		}
1550 		rcu_read_unlock();
1551 	}
1552 out:
1553 	batadv_hardif_put(primary_if);
1554 
1555 	queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work,
1556 			   msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH));
1557 }
1558 
1559 /* The hash for claim and backbone hash receive the same key because they
1560  * are getting initialized by hash_new with the same key. Reinitializing
1561  * them with to different keys to allow nested locking without generating
1562  * lockdep warnings
1563  */
1564 static struct lock_class_key batadv_claim_hash_lock_class_key;
1565 static struct lock_class_key batadv_backbone_hash_lock_class_key;
1566 
1567 /**
1568  * batadv_bla_init() - initialize all bla structures
1569  * @bat_priv: the bat priv with all the mesh interface information
1570  *
1571  * Return: 0 on success, < 0 on error.
1572  */
batadv_bla_init(struct batadv_priv * bat_priv)1573 int batadv_bla_init(struct batadv_priv *bat_priv)
1574 {
1575 	int i;
1576 	u8 claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
1577 	struct batadv_hard_iface *primary_if;
1578 	u16 crc;
1579 	unsigned long entrytime;
1580 
1581 	spin_lock_init(&bat_priv->bla.bcast_duplist_lock);
1582 
1583 	batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n");
1584 
1585 	/* setting claim destination address */
1586 	memcpy(&bat_priv->bla.claim_dest.magic, claim_dest, 3);
1587 	bat_priv->bla.claim_dest.type = 0;
1588 	primary_if = batadv_primary_if_get_selected(bat_priv);
1589 	if (primary_if) {
1590 		crc = crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN);
1591 		bat_priv->bla.claim_dest.group = htons(crc);
1592 		batadv_hardif_put(primary_if);
1593 	} else {
1594 		bat_priv->bla.claim_dest.group = 0; /* will be set later */
1595 	}
1596 
1597 	/* initialize the duplicate list */
1598 	entrytime = jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT);
1599 	for (i = 0; i < BATADV_DUPLIST_SIZE; i++)
1600 		bat_priv->bla.bcast_duplist[i].entrytime = entrytime;
1601 	bat_priv->bla.bcast_duplist_curr = 0;
1602 
1603 	atomic_set(&bat_priv->bla.loopdetect_next,
1604 		   BATADV_BLA_LOOPDETECT_PERIODS);
1605 
1606 	if (bat_priv->bla.claim_hash)
1607 		return 0;
1608 
1609 	bat_priv->bla.claim_hash = batadv_hash_new(128);
1610 	if (!bat_priv->bla.claim_hash)
1611 		return -ENOMEM;
1612 
1613 	bat_priv->bla.backbone_hash = batadv_hash_new(32);
1614 	if (!bat_priv->bla.backbone_hash) {
1615 		batadv_hash_destroy(bat_priv->bla.claim_hash);
1616 		return -ENOMEM;
1617 	}
1618 
1619 	batadv_hash_set_lock_class(bat_priv->bla.claim_hash,
1620 				   &batadv_claim_hash_lock_class_key);
1621 	batadv_hash_set_lock_class(bat_priv->bla.backbone_hash,
1622 				   &batadv_backbone_hash_lock_class_key);
1623 
1624 	batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hashes initialized\n");
1625 
1626 	INIT_DELAYED_WORK(&bat_priv->bla.work, batadv_bla_periodic_work);
1627 
1628 	queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work,
1629 			   msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH));
1630 	return 0;
1631 }
1632 
1633 /**
1634  * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup.
1635  * @bat_priv: the bat priv with all the mesh interface information
1636  * @skb: contains the multicast packet to be checked
1637  * @payload_offset: offset in the skb, marking the start of the data to be CRC'ed
1638  * @orig: originator mac address, NULL if unknown
1639  *
1640  * Check if it is on our broadcast list. Another gateway might have sent the
1641  * same packet because it is connected to the same backbone, so we have to
1642  * remove this duplicate.
1643  *
1644  * This is performed by checking the CRC, which will tell us
1645  * with a good chance that it is the same packet. If it is furthermore
1646  * sent by another host, drop it. We allow equal packets from
1647  * the same host however as this might be intended.
1648  *
1649  * Return: true if a packet is in the duplicate list, false otherwise.
1650  */
batadv_bla_check_duplist(struct batadv_priv * bat_priv,struct sk_buff * skb,int payload_offset,const u8 * orig)1651 static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
1652 				     struct sk_buff *skb, int payload_offset,
1653 				     const u8 *orig)
1654 {
1655 	struct batadv_bcast_duplist_entry *entry;
1656 	bool ret = false;
1657 	int payload_len;
1658 	int i, curr;
1659 	u32 crc;
1660 
1661 	/* calculate the crc ... */
1662 	payload_len = skb->len - payload_offset;
1663 	crc = skb_crc32c(skb, payload_offset, payload_len, 0);
1664 
1665 	spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
1666 
1667 	for (i = 0; i < BATADV_DUPLIST_SIZE; i++) {
1668 		curr = (bat_priv->bla.bcast_duplist_curr + i);
1669 		curr %= BATADV_DUPLIST_SIZE;
1670 		entry = &bat_priv->bla.bcast_duplist[curr];
1671 
1672 		/* we can stop searching if the entry is too old ;
1673 		 * later entries will be even older
1674 		 */
1675 		if (batadv_has_timed_out(entry->entrytime,
1676 					 BATADV_DUPLIST_TIMEOUT))
1677 			break;
1678 
1679 		if (entry->crc != crc)
1680 			continue;
1681 
1682 		/* are the originators both known and not anonymous? */
1683 		if (orig && !is_zero_ether_addr(orig) &&
1684 		    !is_zero_ether_addr(entry->orig)) {
1685 			/* If known, check if the new frame came from
1686 			 * the same originator:
1687 			 * We are safe to take identical frames from the
1688 			 * same orig, if known, as multiplications in
1689 			 * the mesh are detected via the (orig, seqno) pair.
1690 			 * So we can be a bit more liberal here and allow
1691 			 * identical frames from the same orig which the source
1692 			 * host might have sent multiple times on purpose.
1693 			 */
1694 			if (batadv_compare_eth(entry->orig, orig))
1695 				continue;
1696 		}
1697 
1698 		/* this entry seems to match: same crc, not too old,
1699 		 * and from another gw. therefore return true to forbid it.
1700 		 */
1701 		ret = true;
1702 		goto out;
1703 	}
1704 	/* not found, add a new entry (overwrite the oldest entry)
1705 	 * and allow it, its the first occurrence.
1706 	 */
1707 	curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1);
1708 	curr %= BATADV_DUPLIST_SIZE;
1709 	entry = &bat_priv->bla.bcast_duplist[curr];
1710 	entry->crc = crc;
1711 	entry->entrytime = jiffies;
1712 
1713 	/* known originator */
1714 	if (orig)
1715 		ether_addr_copy(entry->orig, orig);
1716 	/* anonymous originator */
1717 	else
1718 		eth_zero_addr(entry->orig);
1719 
1720 	bat_priv->bla.bcast_duplist_curr = curr;
1721 
1722 out:
1723 	spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock);
1724 
1725 	return ret;
1726 }
1727 
1728 /**
1729  * batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
1730  * @bat_priv: the bat priv with all the mesh interface information
1731  * @skb: contains the multicast packet to be checked, decapsulated from a
1732  *  unicast_packet
1733  *
1734  * Check if it is on our broadcast list. Another gateway might have sent the
1735  * same packet because it is connected to the same backbone, so we have to
1736  * remove this duplicate.
1737  *
1738  * Return: true if a packet is in the duplicate list, false otherwise.
1739  */
batadv_bla_check_ucast_duplist(struct batadv_priv * bat_priv,struct sk_buff * skb)1740 static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
1741 					   struct sk_buff *skb)
1742 {
1743 	return batadv_bla_check_duplist(bat_priv, skb, 0, NULL);
1744 }
1745 
1746 /**
1747  * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
1748  * @bat_priv: the bat priv with all the mesh interface information
1749  * @skb: contains the bcast_packet to be checked
1750  *
1751  * Check if it is on our broadcast list. Another gateway might have sent the
1752  * same packet because it is connected to the same backbone, so we have to
1753  * remove this duplicate.
1754  *
1755  * Return: true if a packet is in the duplicate list, false otherwise.
1756  */
batadv_bla_check_bcast_duplist(struct batadv_priv * bat_priv,struct sk_buff * skb)1757 bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
1758 				    struct sk_buff *skb)
1759 {
1760 	struct batadv_bcast_packet *bcast_packet;
1761 
1762 	bcast_packet = (struct batadv_bcast_packet *)skb->data;
1763 
1764 	return batadv_bla_check_duplist(bat_priv, skb, sizeof(*bcast_packet),
1765 					bcast_packet->orig);
1766 }
1767 
1768 /**
1769  * batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
1770  *  the VLAN identified by vid.
1771  * @bat_priv: the bat priv with all the mesh interface information
1772  * @orig: originator mac address
1773  * @vid: VLAN identifier
1774  *
1775  * Return: true if orig is a backbone for this vid, false otherwise.
1776  */
batadv_bla_is_backbone_gw_orig(struct batadv_priv * bat_priv,u8 * orig,unsigned short vid)1777 bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig,
1778 				    unsigned short vid)
1779 {
1780 	struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
1781 	struct hlist_head *head;
1782 	struct batadv_bla_backbone_gw *backbone_gw;
1783 	int i;
1784 
1785 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1786 		return false;
1787 
1788 	if (!hash)
1789 		return false;
1790 
1791 	for (i = 0; i < hash->size; i++) {
1792 		head = &hash->table[i];
1793 
1794 		rcu_read_lock();
1795 		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
1796 			if (batadv_compare_eth(backbone_gw->orig, orig) &&
1797 			    backbone_gw->vid == vid) {
1798 				rcu_read_unlock();
1799 				return true;
1800 			}
1801 		}
1802 		rcu_read_unlock();
1803 	}
1804 
1805 	return false;
1806 }
1807 
1808 /**
1809  * batadv_bla_is_backbone_gw() - check if originator is a backbone gw for a VLAN
1810  * @skb: the frame to be checked
1811  * @orig_node: the orig_node of the frame
1812  * @hdr_size: maximum length of the frame
1813  *
1814  * Return: true if the orig_node is also a gateway on the mesh interface,
1815  * otherwise it returns false.
1816  */
batadv_bla_is_backbone_gw(struct sk_buff * skb,struct batadv_orig_node * orig_node,int hdr_size)1817 bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
1818 			       struct batadv_orig_node *orig_node, int hdr_size)
1819 {
1820 	struct batadv_bla_backbone_gw *backbone_gw;
1821 	unsigned short vid;
1822 
1823 	if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
1824 		return false;
1825 
1826 	/* first, find out the vid. */
1827 	if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
1828 		return false;
1829 
1830 	vid = batadv_get_vid(skb, hdr_size);
1831 
1832 	/* see if this originator is a backbone gw for this VLAN */
1833 	backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,
1834 						orig_node->orig, vid);
1835 	if (!backbone_gw)
1836 		return false;
1837 
1838 	batadv_backbone_gw_put(backbone_gw);
1839 	return true;
1840 }
1841 
1842 /**
1843  * batadv_bla_free() - free all bla structures
1844  * @bat_priv: the bat priv with all the mesh interface information
1845  *
1846  * for meshinterface free or module unload
1847  */
batadv_bla_free(struct batadv_priv * bat_priv)1848 void batadv_bla_free(struct batadv_priv *bat_priv)
1849 {
1850 	struct batadv_hard_iface *primary_if;
1851 
1852 	cancel_delayed_work_sync(&bat_priv->bla.work);
1853 	primary_if = batadv_primary_if_get_selected(bat_priv);
1854 
1855 	if (bat_priv->bla.claim_hash) {
1856 		batadv_bla_purge_claims(bat_priv, primary_if, 1);
1857 		batadv_hash_destroy(bat_priv->bla.claim_hash);
1858 		bat_priv->bla.claim_hash = NULL;
1859 	}
1860 	if (bat_priv->bla.backbone_hash) {
1861 		batadv_bla_purge_backbone_gw(bat_priv, 1);
1862 		batadv_hash_destroy(bat_priv->bla.backbone_hash);
1863 		bat_priv->bla.backbone_hash = NULL;
1864 	}
1865 	batadv_hardif_put(primary_if);
1866 }
1867 
1868 /**
1869  * batadv_bla_loopdetect_check() - check and handle a detected loop
1870  * @bat_priv: the bat priv with all the mesh interface information
1871  * @skb: the packet to check
1872  * @primary_if: interface where the request came on
1873  * @vid: the VLAN ID of the frame
1874  *
1875  * Checks if this packet is a loop detect frame which has been sent by us,
1876  * throws an uevent and logs the event if that is the case.
1877  *
1878  * Return: true if it is a loop detect frame which is to be dropped, false
1879  * otherwise.
1880  */
1881 static bool
batadv_bla_loopdetect_check(struct batadv_priv * bat_priv,struct sk_buff * skb,struct batadv_hard_iface * primary_if,unsigned short vid)1882 batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
1883 			    struct batadv_hard_iface *primary_if,
1884 			    unsigned short vid)
1885 {
1886 	struct batadv_bla_backbone_gw *backbone_gw;
1887 	struct ethhdr *ethhdr;
1888 	bool ret;
1889 
1890 	ethhdr = eth_hdr(skb);
1891 
1892 	/* Only check for the MAC address and skip more checks here for
1893 	 * performance reasons - this function is on the hotpath, after all.
1894 	 */
1895 	if (!batadv_compare_eth(ethhdr->h_source,
1896 				bat_priv->bla.loopdetect_addr))
1897 		return false;
1898 
1899 	/* If the packet came too late, don't forward it on the mesh
1900 	 * but don't consider that as loop. It might be a coincidence.
1901 	 */
1902 	if (batadv_has_timed_out(bat_priv->bla.loopdetect_lasttime,
1903 				 BATADV_BLA_LOOPDETECT_TIMEOUT))
1904 		return true;
1905 
1906 	backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
1907 						 primary_if->net_dev->dev_addr,
1908 						 vid, true);
1909 	if (unlikely(!backbone_gw))
1910 		return true;
1911 
1912 	ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work);
1913 
1914 	/* backbone_gw is unreferenced in the report work function
1915 	 * if queue_work() call was successful
1916 	 */
1917 	if (!ret)
1918 		batadv_backbone_gw_put(backbone_gw);
1919 
1920 	return true;
1921 }
1922 
1923 /**
1924  * batadv_bla_rx() - check packets coming from the mesh.
1925  * @bat_priv: the bat priv with all the mesh interface information
1926  * @skb: the frame to be checked
1927  * @vid: the VLAN ID of the frame
1928  * @packet_type: the batman packet type this frame came in
1929  *
1930  * batadv_bla_rx avoidance checks if:
1931  *  * we have to race for a claim
1932  *  * if the frame is allowed on the LAN
1933  *
1934  * In these cases, the skb is further handled by this function
1935  *
1936  * Return: true if handled, otherwise it returns false and the caller shall
1937  * further process the skb.
1938  */
batadv_bla_rx(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid,int packet_type)1939 bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
1940 		   unsigned short vid, int packet_type)
1941 {
1942 	struct batadv_bla_backbone_gw *backbone_gw;
1943 	struct ethhdr *ethhdr;
1944 	struct batadv_bla_claim search_claim, *claim = NULL;
1945 	struct batadv_hard_iface *primary_if;
1946 	bool own_claim;
1947 	bool ret;
1948 
1949 	ethhdr = eth_hdr(skb);
1950 
1951 	primary_if = batadv_primary_if_get_selected(bat_priv);
1952 	if (!primary_if)
1953 		goto handled;
1954 
1955 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1956 		goto allow;
1957 
1958 	if (batadv_bla_loopdetect_check(bat_priv, skb, primary_if, vid))
1959 		goto handled;
1960 
1961 	if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
1962 		/* don't allow multicast packets while requests are in flight */
1963 		if (is_multicast_ether_addr(ethhdr->h_dest))
1964 			/* Both broadcast flooding or multicast-via-unicasts
1965 			 * delivery might send to multiple backbone gateways
1966 			 * sharing the same LAN and therefore need to coordinate
1967 			 * which backbone gateway forwards into the LAN,
1968 			 * by claiming the payload source address.
1969 			 *
1970 			 * Broadcast flooding and multicast-via-unicasts
1971 			 * delivery use the following two batman packet types.
1972 			 * Note: explicitly exclude BATADV_UNICAST_4ADDR,
1973 			 * as the DHCP gateway feature will send explicitly
1974 			 * to only one BLA gateway, so the claiming process
1975 			 * should be avoided there.
1976 			 */
1977 			if (packet_type == BATADV_BCAST ||
1978 			    packet_type == BATADV_UNICAST)
1979 				goto handled;
1980 
1981 	/* potential duplicates from foreign BLA backbone gateways via
1982 	 * multicast-in-unicast packets
1983 	 */
1984 	if (is_multicast_ether_addr(ethhdr->h_dest) &&
1985 	    packet_type == BATADV_UNICAST &&
1986 	    batadv_bla_check_ucast_duplist(bat_priv, skb))
1987 		goto handled;
1988 
1989 	ether_addr_copy(search_claim.addr, ethhdr->h_source);
1990 	search_claim.vid = vid;
1991 	claim = batadv_claim_hash_find(bat_priv, &search_claim);
1992 
1993 	if (!claim) {
1994 		bool local = batadv_is_my_client(bat_priv, ethhdr->h_source, vid);
1995 
1996 		/* possible optimization: race for a claim */
1997 		/* No claim exists yet, claim it for us!
1998 		 */
1999 
2000 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
2001 			   "%s(): Unclaimed MAC %pM found. Claim it. Local: %s\n",
2002 			   __func__, ethhdr->h_source, str_yes_no(local));
2003 		batadv_handle_claim(bat_priv, primary_if,
2004 				    primary_if->net_dev->dev_addr,
2005 				    ethhdr->h_source, vid);
2006 		goto allow;
2007 	}
2008 
2009 	/* if it is our own claim ... */
2010 	backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
2011 	own_claim = batadv_compare_eth(backbone_gw->orig,
2012 				       primary_if->net_dev->dev_addr);
2013 	batadv_backbone_gw_put(backbone_gw);
2014 
2015 	if (own_claim) {
2016 		/* ... allow it in any case */
2017 		claim->lasttime = jiffies;
2018 		goto allow;
2019 	}
2020 
2021 	/* if it is a multicast ... */
2022 	if (is_multicast_ether_addr(ethhdr->h_dest) &&
2023 	    (packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
2024 		/* ... drop it. the responsible gateway is in charge.
2025 		 *
2026 		 * We need to check packet type because with the gateway
2027 		 * feature, broadcasts (like DHCP requests) may be sent
2028 		 * using a unicast 4 address packet type. See comment above.
2029 		 */
2030 		goto handled;
2031 	} else {
2032 		/* seems the client considers us as its best gateway.
2033 		 * send a claim and update the claim table
2034 		 * immediately.
2035 		 */
2036 		batadv_handle_claim(bat_priv, primary_if,
2037 				    primary_if->net_dev->dev_addr,
2038 				    ethhdr->h_source, vid);
2039 		goto allow;
2040 	}
2041 allow:
2042 	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
2043 	ret = false;
2044 	goto out;
2045 
2046 handled:
2047 	kfree_skb(skb);
2048 	ret = true;
2049 
2050 out:
2051 	batadv_hardif_put(primary_if);
2052 	batadv_claim_put(claim);
2053 	return ret;
2054 }
2055 
2056 /**
2057  * batadv_bla_tx() - check packets going into the mesh
2058  * @bat_priv: the bat priv with all the mesh interface information
2059  * @skb: the frame to be checked
2060  * @vid: the VLAN ID of the frame
2061  *
2062  * batadv_bla_tx checks if:
2063  *  * a claim was received which has to be processed
2064  *  * the frame is allowed on the mesh
2065  *
2066  * in these cases, the skb is further handled by this function.
2067  *
2068  * This call might reallocate skb data.
2069  *
2070  * Return: true if handled, otherwise it returns false and the caller shall
2071  * further process the skb.
2072  */
batadv_bla_tx(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid)2073 bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
2074 		   unsigned short vid)
2075 {
2076 	struct ethhdr *ethhdr;
2077 	struct batadv_bla_claim search_claim, *claim = NULL;
2078 	struct batadv_bla_backbone_gw *backbone_gw;
2079 	struct batadv_hard_iface *primary_if;
2080 	bool client_roamed;
2081 	bool ret = false;
2082 
2083 	primary_if = batadv_primary_if_get_selected(bat_priv);
2084 	if (!primary_if)
2085 		goto out;
2086 
2087 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
2088 		goto allow;
2089 
2090 	if (batadv_bla_process_claim(bat_priv, primary_if, skb))
2091 		goto handled;
2092 
2093 	ethhdr = eth_hdr(skb);
2094 
2095 	if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
2096 		/* don't allow broadcasts while requests are in flight */
2097 		if (is_multicast_ether_addr(ethhdr->h_dest))
2098 			goto handled;
2099 
2100 	ether_addr_copy(search_claim.addr, ethhdr->h_source);
2101 	search_claim.vid = vid;
2102 
2103 	claim = batadv_claim_hash_find(bat_priv, &search_claim);
2104 
2105 	/* if no claim exists, allow it. */
2106 	if (!claim)
2107 		goto allow;
2108 
2109 	/* check if we are responsible. */
2110 	backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
2111 	client_roamed = batadv_compare_eth(backbone_gw->orig,
2112 					   primary_if->net_dev->dev_addr);
2113 	batadv_backbone_gw_put(backbone_gw);
2114 
2115 	if (client_roamed) {
2116 		/* if yes, the client has roamed and we have
2117 		 * to unclaim it.
2118 		 */
2119 		if (batadv_has_timed_out(claim->lasttime, 100)) {
2120 			/* only unclaim if the last claim entry is
2121 			 * older than 100 ms to make sure we really
2122 			 * have a roaming client here.
2123 			 */
2124 			batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): Roaming client %pM detected. Unclaim it.\n",
2125 				   __func__, ethhdr->h_source);
2126 			batadv_handle_unclaim(bat_priv, primary_if,
2127 					      primary_if->net_dev->dev_addr,
2128 					      ethhdr->h_source, vid);
2129 			goto allow;
2130 		} else {
2131 			batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): Race for claim %pM detected. Drop packet.\n",
2132 				   __func__, ethhdr->h_source);
2133 			goto handled;
2134 		}
2135 	}
2136 
2137 	/* check if it is a multicast/broadcast frame */
2138 	if (is_multicast_ether_addr(ethhdr->h_dest)) {
2139 		/* drop it. the responsible gateway has forwarded it into
2140 		 * the backbone network.
2141 		 */
2142 		goto handled;
2143 	} else {
2144 		/* we must allow it. at least if we are
2145 		 * responsible for the DESTINATION.
2146 		 */
2147 		goto allow;
2148 	}
2149 allow:
2150 	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
2151 	ret = false;
2152 	goto out;
2153 handled:
2154 	ret = true;
2155 out:
2156 	batadv_hardif_put(primary_if);
2157 	batadv_claim_put(claim);
2158 	return ret;
2159 }
2160 
2161 /**
2162  * batadv_bla_claim_dump_entry() - dump one entry of the claim table
2163  * to a netlink socket
2164  * @msg: buffer for the message
2165  * @portid: netlink port
2166  * @cb: Control block containing additional options
2167  * @primary_if: primary interface
2168  * @claim: entry to dump
2169  *
2170  * Return: 0 or error code.
2171  */
2172 static int
batadv_bla_claim_dump_entry(struct sk_buff * msg,u32 portid,struct netlink_callback * cb,struct batadv_hard_iface * primary_if,struct batadv_bla_claim * claim)2173 batadv_bla_claim_dump_entry(struct sk_buff *msg, u32 portid,
2174 			    struct netlink_callback *cb,
2175 			    struct batadv_hard_iface *primary_if,
2176 			    struct batadv_bla_claim *claim)
2177 {
2178 	const u8 *primary_addr = primary_if->net_dev->dev_addr;
2179 	struct batadv_bla_backbone_gw *backbone_gw;
2180 	u16 backbone_crc;
2181 	bool is_own;
2182 	void *hdr;
2183 	int ret = -EINVAL;
2184 
2185 	hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
2186 			  &batadv_netlink_family, NLM_F_MULTI,
2187 			  BATADV_CMD_GET_BLA_CLAIM);
2188 	if (!hdr) {
2189 		ret = -ENOBUFS;
2190 		goto out;
2191 	}
2192 
2193 	genl_dump_check_consistent(cb, hdr);
2194 
2195 	backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
2196 
2197 	is_own = batadv_compare_eth(backbone_gw->orig, primary_addr);
2198 
2199 	spin_lock_bh(&backbone_gw->crc_lock);
2200 	backbone_crc = backbone_gw->crc;
2201 	spin_unlock_bh(&backbone_gw->crc_lock);
2202 
2203 	if (is_own)
2204 		if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) {
2205 			genlmsg_cancel(msg, hdr);
2206 			goto put_backbone_gw;
2207 		}
2208 
2209 	if (nla_put(msg, BATADV_ATTR_BLA_ADDRESS, ETH_ALEN, claim->addr) ||
2210 	    nla_put_u16(msg, BATADV_ATTR_BLA_VID, claim->vid) ||
2211 	    nla_put(msg, BATADV_ATTR_BLA_BACKBONE, ETH_ALEN,
2212 		    backbone_gw->orig) ||
2213 	    nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
2214 			backbone_crc)) {
2215 		genlmsg_cancel(msg, hdr);
2216 		goto put_backbone_gw;
2217 	}
2218 
2219 	genlmsg_end(msg, hdr);
2220 	ret = 0;
2221 
2222 put_backbone_gw:
2223 	batadv_backbone_gw_put(backbone_gw);
2224 out:
2225 	return ret;
2226 }
2227 
2228 /**
2229  * batadv_bla_claim_dump_bucket() - dump one bucket of the claim table
2230  * to a netlink socket
2231  * @msg: buffer for the message
2232  * @portid: netlink port
2233  * @cb: Control block containing additional options
2234  * @primary_if: primary interface
2235  * @hash: hash to dump
2236  * @bucket: bucket index to dump
2237  * @idx_skip: How many entries to skip
2238  *
2239  * Return: always 0.
2240  */
2241 static int
batadv_bla_claim_dump_bucket(struct sk_buff * msg,u32 portid,struct netlink_callback * cb,struct batadv_hard_iface * primary_if,struct batadv_hashtable * hash,unsigned int bucket,int * idx_skip)2242 batadv_bla_claim_dump_bucket(struct sk_buff *msg, u32 portid,
2243 			     struct netlink_callback *cb,
2244 			     struct batadv_hard_iface *primary_if,
2245 			     struct batadv_hashtable *hash, unsigned int bucket,
2246 			     int *idx_skip)
2247 {
2248 	struct batadv_bla_claim *claim;
2249 	int idx = 0;
2250 	int ret = 0;
2251 
2252 	spin_lock_bh(&hash->list_locks[bucket]);
2253 	cb->seq = atomic_read(&hash->generation) << 1 | 1;
2254 
2255 	hlist_for_each_entry(claim, &hash->table[bucket], hash_entry) {
2256 		if (idx++ < *idx_skip)
2257 			continue;
2258 
2259 		ret = batadv_bla_claim_dump_entry(msg, portid, cb,
2260 						  primary_if, claim);
2261 		if (ret) {
2262 			*idx_skip = idx - 1;
2263 			goto unlock;
2264 		}
2265 	}
2266 
2267 	*idx_skip = 0;
2268 unlock:
2269 	spin_unlock_bh(&hash->list_locks[bucket]);
2270 	return ret;
2271 }
2272 
2273 /**
2274  * batadv_bla_claim_dump() - dump claim table to a netlink socket
2275  * @msg: buffer for the message
2276  * @cb: callback structure containing arguments
2277  *
2278  * Return: message length.
2279  */
batadv_bla_claim_dump(struct sk_buff * msg,struct netlink_callback * cb)2280 int batadv_bla_claim_dump(struct sk_buff *msg, struct netlink_callback *cb)
2281 {
2282 	struct batadv_hard_iface *primary_if = NULL;
2283 	int portid = NETLINK_CB(cb->skb).portid;
2284 	struct net_device *mesh_iface;
2285 	struct batadv_hashtable *hash;
2286 	struct batadv_priv *bat_priv;
2287 	int bucket = cb->args[0];
2288 	int idx = cb->args[1];
2289 	int ret = 0;
2290 
2291 	mesh_iface = batadv_netlink_get_meshif(cb);
2292 	if (IS_ERR(mesh_iface))
2293 		return PTR_ERR(mesh_iface);
2294 
2295 	bat_priv = netdev_priv(mesh_iface);
2296 	hash = bat_priv->bla.claim_hash;
2297 
2298 	primary_if = batadv_primary_if_get_selected(bat_priv);
2299 	if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
2300 		ret = -ENOENT;
2301 		goto out;
2302 	}
2303 
2304 	while (bucket < hash->size) {
2305 		if (batadv_bla_claim_dump_bucket(msg, portid, cb, primary_if,
2306 						 hash, bucket, &idx))
2307 			break;
2308 		bucket++;
2309 	}
2310 
2311 	cb->args[0] = bucket;
2312 	cb->args[1] = idx;
2313 
2314 	ret = msg->len;
2315 
2316 out:
2317 	batadv_hardif_put(primary_if);
2318 
2319 	dev_put(mesh_iface);
2320 
2321 	return ret;
2322 }
2323 
2324 /**
2325  * batadv_bla_backbone_dump_entry() - dump one entry of the backbone table to a
2326  *  netlink socket
2327  * @msg: buffer for the message
2328  * @portid: netlink port
2329  * @cb: Control block containing additional options
2330  * @primary_if: primary interface
2331  * @backbone_gw: entry to dump
2332  *
2333  * Return: 0 or error code.
2334  */
2335 static int
batadv_bla_backbone_dump_entry(struct sk_buff * msg,u32 portid,struct netlink_callback * cb,struct batadv_hard_iface * primary_if,struct batadv_bla_backbone_gw * backbone_gw)2336 batadv_bla_backbone_dump_entry(struct sk_buff *msg, u32 portid,
2337 			       struct netlink_callback *cb,
2338 			       struct batadv_hard_iface *primary_if,
2339 			       struct batadv_bla_backbone_gw *backbone_gw)
2340 {
2341 	const u8 *primary_addr = primary_if->net_dev->dev_addr;
2342 	u16 backbone_crc;
2343 	bool is_own;
2344 	int msecs;
2345 	void *hdr;
2346 	int ret = -EINVAL;
2347 
2348 	hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
2349 			  &batadv_netlink_family, NLM_F_MULTI,
2350 			  BATADV_CMD_GET_BLA_BACKBONE);
2351 	if (!hdr) {
2352 		ret = -ENOBUFS;
2353 		goto out;
2354 	}
2355 
2356 	genl_dump_check_consistent(cb, hdr);
2357 
2358 	is_own = batadv_compare_eth(backbone_gw->orig, primary_addr);
2359 
2360 	spin_lock_bh(&backbone_gw->crc_lock);
2361 	backbone_crc = backbone_gw->crc;
2362 	spin_unlock_bh(&backbone_gw->crc_lock);
2363 
2364 	msecs = jiffies_to_msecs(jiffies - backbone_gw->lasttime);
2365 
2366 	if (is_own)
2367 		if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) {
2368 			genlmsg_cancel(msg, hdr);
2369 			goto out;
2370 		}
2371 
2372 	if (nla_put(msg, BATADV_ATTR_BLA_BACKBONE, ETH_ALEN,
2373 		    backbone_gw->orig) ||
2374 	    nla_put_u16(msg, BATADV_ATTR_BLA_VID, backbone_gw->vid) ||
2375 	    nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
2376 			backbone_crc) ||
2377 	    nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) {
2378 		genlmsg_cancel(msg, hdr);
2379 		goto out;
2380 	}
2381 
2382 	genlmsg_end(msg, hdr);
2383 	ret = 0;
2384 
2385 out:
2386 	return ret;
2387 }
2388 
2389 /**
2390  * batadv_bla_backbone_dump_bucket() - dump one bucket of the backbone table to
2391  *  a netlink socket
2392  * @msg: buffer for the message
2393  * @portid: netlink port
2394  * @cb: Control block containing additional options
2395  * @primary_if: primary interface
2396  * @hash: hash to dump
2397  * @bucket: bucket index to dump
2398  * @idx_skip: How many entries to skip
2399  *
2400  * Return: always 0.
2401  */
2402 static int
batadv_bla_backbone_dump_bucket(struct sk_buff * msg,u32 portid,struct netlink_callback * cb,struct batadv_hard_iface * primary_if,struct batadv_hashtable * hash,unsigned int bucket,int * idx_skip)2403 batadv_bla_backbone_dump_bucket(struct sk_buff *msg, u32 portid,
2404 				struct netlink_callback *cb,
2405 				struct batadv_hard_iface *primary_if,
2406 				struct batadv_hashtable *hash,
2407 				unsigned int bucket, int *idx_skip)
2408 {
2409 	struct batadv_bla_backbone_gw *backbone_gw;
2410 	int idx = 0;
2411 	int ret = 0;
2412 
2413 	spin_lock_bh(&hash->list_locks[bucket]);
2414 	cb->seq = atomic_read(&hash->generation) << 1 | 1;
2415 
2416 	hlist_for_each_entry(backbone_gw, &hash->table[bucket], hash_entry) {
2417 		if (idx++ < *idx_skip)
2418 			continue;
2419 
2420 		ret = batadv_bla_backbone_dump_entry(msg, portid, cb,
2421 						     primary_if, backbone_gw);
2422 		if (ret) {
2423 			*idx_skip = idx - 1;
2424 			goto unlock;
2425 		}
2426 	}
2427 
2428 	*idx_skip = 0;
2429 unlock:
2430 	spin_unlock_bh(&hash->list_locks[bucket]);
2431 	return ret;
2432 }
2433 
2434 /**
2435  * batadv_bla_backbone_dump() - dump backbone table to a netlink socket
2436  * @msg: buffer for the message
2437  * @cb: callback structure containing arguments
2438  *
2439  * Return: message length.
2440  */
batadv_bla_backbone_dump(struct sk_buff * msg,struct netlink_callback * cb)2441 int batadv_bla_backbone_dump(struct sk_buff *msg, struct netlink_callback *cb)
2442 {
2443 	struct batadv_hard_iface *primary_if = NULL;
2444 	int portid = NETLINK_CB(cb->skb).portid;
2445 	struct net_device *mesh_iface;
2446 	struct batadv_hashtable *hash;
2447 	struct batadv_priv *bat_priv;
2448 	int bucket = cb->args[0];
2449 	int idx = cb->args[1];
2450 	int ret = 0;
2451 
2452 	mesh_iface = batadv_netlink_get_meshif(cb);
2453 	if (IS_ERR(mesh_iface))
2454 		return PTR_ERR(mesh_iface);
2455 
2456 	bat_priv = netdev_priv(mesh_iface);
2457 	hash = bat_priv->bla.backbone_hash;
2458 
2459 	primary_if = batadv_primary_if_get_selected(bat_priv);
2460 	if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
2461 		ret = -ENOENT;
2462 		goto out;
2463 	}
2464 
2465 	while (bucket < hash->size) {
2466 		if (batadv_bla_backbone_dump_bucket(msg, portid, cb, primary_if,
2467 						    hash, bucket, &idx))
2468 			break;
2469 		bucket++;
2470 	}
2471 
2472 	cb->args[0] = bucket;
2473 	cb->args[1] = idx;
2474 
2475 	ret = msg->len;
2476 
2477 out:
2478 	batadv_hardif_put(primary_if);
2479 
2480 	dev_put(mesh_iface);
2481 
2482 	return ret;
2483 }
2484 
2485 #ifdef CONFIG_BATMAN_ADV_DAT
2486 /**
2487  * batadv_bla_check_claim() - check if address is claimed
2488  *
2489  * @bat_priv: the bat priv with all the mesh interface information
2490  * @addr: mac address of which the claim status is checked
2491  * @vid: the VLAN ID
2492  *
2493  * addr is checked if this address is claimed by the local device itself.
2494  *
2495  * Return: true if bla is disabled or the mac is claimed by the device,
2496  * false if the device addr is already claimed by another gateway
2497  */
batadv_bla_check_claim(struct batadv_priv * bat_priv,u8 * addr,unsigned short vid)2498 bool batadv_bla_check_claim(struct batadv_priv *bat_priv,
2499 			    u8 *addr, unsigned short vid)
2500 {
2501 	struct batadv_bla_backbone_gw *backbone_gw;
2502 	struct batadv_bla_claim search_claim;
2503 	struct batadv_bla_claim *claim = NULL;
2504 	struct batadv_hard_iface *primary_if = NULL;
2505 	bool ret = true;
2506 
2507 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
2508 		return ret;
2509 
2510 	primary_if = batadv_primary_if_get_selected(bat_priv);
2511 	if (!primary_if)
2512 		return ret;
2513 
2514 	/* First look if the mac address is claimed */
2515 	ether_addr_copy(search_claim.addr, addr);
2516 	search_claim.vid = vid;
2517 
2518 	claim = batadv_claim_hash_find(bat_priv, &search_claim);
2519 
2520 	/* If there is a claim and we are not owner of the claim,
2521 	 * return false.
2522 	 */
2523 	if (claim) {
2524 		backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
2525 
2526 		if (!batadv_compare_eth(backbone_gw->orig,
2527 					primary_if->net_dev->dev_addr))
2528 			ret = false;
2529 
2530 		batadv_backbone_gw_put(backbone_gw);
2531 		batadv_claim_put(claim);
2532 	}
2533 
2534 	batadv_hardif_put(primary_if);
2535 	return ret;
2536 }
2537 #endif
2538