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