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