Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/batman-adv/bridge_loop_avoidance.c
26285 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_ptr: pointer to position inside the head buffer of the skb
1592
* marking the start of the data to be CRC'ed
1593
* @orig: originator mac address, NULL if unknown
1594
*
1595
* Check if it is on our broadcast list. Another gateway might have sent the
1596
* same packet because it is connected to the same backbone, so we have to
1597
* remove this duplicate.
1598
*
1599
* This is performed by checking the CRC, which will tell us
1600
* with a good chance that it is the same packet. If it is furthermore
1601
* sent by another host, drop it. We allow equal packets from
1602
* the same host however as this might be intended.
1603
*
1604
* Return: true if a packet is in the duplicate list, false otherwise.
1605
*/
1606
static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
1607
struct sk_buff *skb, u8 *payload_ptr,
1608
const u8 *orig)
1609
{
1610
struct batadv_bcast_duplist_entry *entry;
1611
bool ret = false;
1612
int i, curr;
1613
__be32 crc;
1614
1615
/* calculate the crc ... */
1616
crc = batadv_skb_crc32(skb, payload_ptr);
1617
1618
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
1619
1620
for (i = 0; i < BATADV_DUPLIST_SIZE; i++) {
1621
curr = (bat_priv->bla.bcast_duplist_curr + i);
1622
curr %= BATADV_DUPLIST_SIZE;
1623
entry = &bat_priv->bla.bcast_duplist[curr];
1624
1625
/* we can stop searching if the entry is too old ;
1626
* later entries will be even older
1627
*/
1628
if (batadv_has_timed_out(entry->entrytime,
1629
BATADV_DUPLIST_TIMEOUT))
1630
break;
1631
1632
if (entry->crc != crc)
1633
continue;
1634
1635
/* are the originators both known and not anonymous? */
1636
if (orig && !is_zero_ether_addr(orig) &&
1637
!is_zero_ether_addr(entry->orig)) {
1638
/* If known, check if the new frame came from
1639
* the same originator:
1640
* We are safe to take identical frames from the
1641
* same orig, if known, as multiplications in
1642
* the mesh are detected via the (orig, seqno) pair.
1643
* So we can be a bit more liberal here and allow
1644
* identical frames from the same orig which the source
1645
* host might have sent multiple times on purpose.
1646
*/
1647
if (batadv_compare_eth(entry->orig, orig))
1648
continue;
1649
}
1650
1651
/* this entry seems to match: same crc, not too old,
1652
* and from another gw. therefore return true to forbid it.
1653
*/
1654
ret = true;
1655
goto out;
1656
}
1657
/* not found, add a new entry (overwrite the oldest entry)
1658
* and allow it, its the first occurrence.
1659
*/
1660
curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1);
1661
curr %= BATADV_DUPLIST_SIZE;
1662
entry = &bat_priv->bla.bcast_duplist[curr];
1663
entry->crc = crc;
1664
entry->entrytime = jiffies;
1665
1666
/* known originator */
1667
if (orig)
1668
ether_addr_copy(entry->orig, orig);
1669
/* anonymous originator */
1670
else
1671
eth_zero_addr(entry->orig);
1672
1673
bat_priv->bla.bcast_duplist_curr = curr;
1674
1675
out:
1676
spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock);
1677
1678
return ret;
1679
}
1680
1681
/**
1682
* batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
1683
* @bat_priv: the bat priv with all the mesh interface information
1684
* @skb: contains the multicast packet to be checked, decapsulated from a
1685
* unicast_packet
1686
*
1687
* Check if it is on our broadcast list. Another gateway might have sent the
1688
* same packet because it is connected to the same backbone, so we have to
1689
* remove this duplicate.
1690
*
1691
* Return: true if a packet is in the duplicate list, false otherwise.
1692
*/
1693
static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
1694
struct sk_buff *skb)
1695
{
1696
return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL);
1697
}
1698
1699
/**
1700
* batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
1701
* @bat_priv: the bat priv with all the mesh interface information
1702
* @skb: contains the bcast_packet to be checked
1703
*
1704
* Check if it is on our broadcast list. Another gateway might have sent the
1705
* same packet because it is connected to the same backbone, so we have to
1706
* remove this duplicate.
1707
*
1708
* Return: true if a packet is in the duplicate list, false otherwise.
1709
*/
1710
bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
1711
struct sk_buff *skb)
1712
{
1713
struct batadv_bcast_packet *bcast_packet;
1714
u8 *payload_ptr;
1715
1716
bcast_packet = (struct batadv_bcast_packet *)skb->data;
1717
payload_ptr = (u8 *)(bcast_packet + 1);
1718
1719
return batadv_bla_check_duplist(bat_priv, skb, payload_ptr,
1720
bcast_packet->orig);
1721
}
1722
1723
/**
1724
* batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
1725
* the VLAN identified by vid.
1726
* @bat_priv: the bat priv with all the mesh interface information
1727
* @orig: originator mac address
1728
* @vid: VLAN identifier
1729
*
1730
* Return: true if orig is a backbone for this vid, false otherwise.
1731
*/
1732
bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig,
1733
unsigned short vid)
1734
{
1735
struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
1736
struct hlist_head *head;
1737
struct batadv_bla_backbone_gw *backbone_gw;
1738
int i;
1739
1740
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1741
return false;
1742
1743
if (!hash)
1744
return false;
1745
1746
for (i = 0; i < hash->size; i++) {
1747
head = &hash->table[i];
1748
1749
rcu_read_lock();
1750
hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
1751
if (batadv_compare_eth(backbone_gw->orig, orig) &&
1752
backbone_gw->vid == vid) {
1753
rcu_read_unlock();
1754
return true;
1755
}
1756
}
1757
rcu_read_unlock();
1758
}
1759
1760
return false;
1761
}
1762
1763
/**
1764
* batadv_bla_is_backbone_gw() - check if originator is a backbone gw for a VLAN
1765
* @skb: the frame to be checked
1766
* @orig_node: the orig_node of the frame
1767
* @hdr_size: maximum length of the frame
1768
*
1769
* Return: true if the orig_node is also a gateway on the mesh interface,
1770
* otherwise it returns false.
1771
*/
1772
bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
1773
struct batadv_orig_node *orig_node, int hdr_size)
1774
{
1775
struct batadv_bla_backbone_gw *backbone_gw;
1776
unsigned short vid;
1777
1778
if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
1779
return false;
1780
1781
/* first, find out the vid. */
1782
if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
1783
return false;
1784
1785
vid = batadv_get_vid(skb, hdr_size);
1786
1787
/* see if this originator is a backbone gw for this VLAN */
1788
backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,
1789
orig_node->orig, vid);
1790
if (!backbone_gw)
1791
return false;
1792
1793
batadv_backbone_gw_put(backbone_gw);
1794
return true;
1795
}
1796
1797
/**
1798
* batadv_bla_free() - free all bla structures
1799
* @bat_priv: the bat priv with all the mesh interface information
1800
*
1801
* for meshinterface free or module unload
1802
*/
1803
void batadv_bla_free(struct batadv_priv *bat_priv)
1804
{
1805
struct batadv_hard_iface *primary_if;
1806
1807
cancel_delayed_work_sync(&bat_priv->bla.work);
1808
primary_if = batadv_primary_if_get_selected(bat_priv);
1809
1810
if (bat_priv->bla.claim_hash) {
1811
batadv_bla_purge_claims(bat_priv, primary_if, 1);
1812
batadv_hash_destroy(bat_priv->bla.claim_hash);
1813
bat_priv->bla.claim_hash = NULL;
1814
}
1815
if (bat_priv->bla.backbone_hash) {
1816
batadv_bla_purge_backbone_gw(bat_priv, 1);
1817
batadv_hash_destroy(bat_priv->bla.backbone_hash);
1818
bat_priv->bla.backbone_hash = NULL;
1819
}
1820
batadv_hardif_put(primary_if);
1821
}
1822
1823
/**
1824
* batadv_bla_loopdetect_check() - check and handle a detected loop
1825
* @bat_priv: the bat priv with all the mesh interface information
1826
* @skb: the packet to check
1827
* @primary_if: interface where the request came on
1828
* @vid: the VLAN ID of the frame
1829
*
1830
* Checks if this packet is a loop detect frame which has been sent by us,
1831
* throws an uevent and logs the event if that is the case.
1832
*
1833
* Return: true if it is a loop detect frame which is to be dropped, false
1834
* otherwise.
1835
*/
1836
static bool
1837
batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
1838
struct batadv_hard_iface *primary_if,
1839
unsigned short vid)
1840
{
1841
struct batadv_bla_backbone_gw *backbone_gw;
1842
struct ethhdr *ethhdr;
1843
bool ret;
1844
1845
ethhdr = eth_hdr(skb);
1846
1847
/* Only check for the MAC address and skip more checks here for
1848
* performance reasons - this function is on the hotpath, after all.
1849
*/
1850
if (!batadv_compare_eth(ethhdr->h_source,
1851
bat_priv->bla.loopdetect_addr))
1852
return false;
1853
1854
/* If the packet came too late, don't forward it on the mesh
1855
* but don't consider that as loop. It might be a coincidence.
1856
*/
1857
if (batadv_has_timed_out(bat_priv->bla.loopdetect_lasttime,
1858
BATADV_BLA_LOOPDETECT_TIMEOUT))
1859
return true;
1860
1861
backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
1862
primary_if->net_dev->dev_addr,
1863
vid, true);
1864
if (unlikely(!backbone_gw))
1865
return true;
1866
1867
ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work);
1868
1869
/* backbone_gw is unreferenced in the report work function
1870
* if queue_work() call was successful
1871
*/
1872
if (!ret)
1873
batadv_backbone_gw_put(backbone_gw);
1874
1875
return true;
1876
}
1877
1878
/**
1879
* batadv_bla_rx() - check packets coming from the mesh.
1880
* @bat_priv: the bat priv with all the mesh interface information
1881
* @skb: the frame to be checked
1882
* @vid: the VLAN ID of the frame
1883
* @packet_type: the batman packet type this frame came in
1884
*
1885
* batadv_bla_rx avoidance checks if:
1886
* * we have to race for a claim
1887
* * if the frame is allowed on the LAN
1888
*
1889
* In these cases, the skb is further handled by this function
1890
*
1891
* Return: true if handled, otherwise it returns false and the caller shall
1892
* further process the skb.
1893
*/
1894
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
1895
unsigned short vid, int packet_type)
1896
{
1897
struct batadv_bla_backbone_gw *backbone_gw;
1898
struct ethhdr *ethhdr;
1899
struct batadv_bla_claim search_claim, *claim = NULL;
1900
struct batadv_hard_iface *primary_if;
1901
bool own_claim;
1902
bool ret;
1903
1904
ethhdr = eth_hdr(skb);
1905
1906
primary_if = batadv_primary_if_get_selected(bat_priv);
1907
if (!primary_if)
1908
goto handled;
1909
1910
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1911
goto allow;
1912
1913
if (batadv_bla_loopdetect_check(bat_priv, skb, primary_if, vid))
1914
goto handled;
1915
1916
if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
1917
/* don't allow multicast packets while requests are in flight */
1918
if (is_multicast_ether_addr(ethhdr->h_dest))
1919
/* Both broadcast flooding or multicast-via-unicasts
1920
* delivery might send to multiple backbone gateways
1921
* sharing the same LAN and therefore need to coordinate
1922
* which backbone gateway forwards into the LAN,
1923
* by claiming the payload source address.
1924
*
1925
* Broadcast flooding and multicast-via-unicasts
1926
* delivery use the following two batman packet types.
1927
* Note: explicitly exclude BATADV_UNICAST_4ADDR,
1928
* as the DHCP gateway feature will send explicitly
1929
* to only one BLA gateway, so the claiming process
1930
* should be avoided there.
1931
*/
1932
if (packet_type == BATADV_BCAST ||
1933
packet_type == BATADV_UNICAST)
1934
goto handled;
1935
1936
/* potential duplicates from foreign BLA backbone gateways via
1937
* multicast-in-unicast packets
1938
*/
1939
if (is_multicast_ether_addr(ethhdr->h_dest) &&
1940
packet_type == BATADV_UNICAST &&
1941
batadv_bla_check_ucast_duplist(bat_priv, skb))
1942
goto handled;
1943
1944
ether_addr_copy(search_claim.addr, ethhdr->h_source);
1945
search_claim.vid = vid;
1946
claim = batadv_claim_hash_find(bat_priv, &search_claim);
1947
1948
if (!claim) {
1949
bool local = batadv_is_my_client(bat_priv, ethhdr->h_source, vid);
1950
1951
/* possible optimization: race for a claim */
1952
/* No claim exists yet, claim it for us!
1953
*/
1954
1955
batadv_dbg(BATADV_DBG_BLA, bat_priv,
1956
"%s(): Unclaimed MAC %pM found. Claim it. Local: %s\n",
1957
__func__, ethhdr->h_source, str_yes_no(local));
1958
batadv_handle_claim(bat_priv, primary_if,
1959
primary_if->net_dev->dev_addr,
1960
ethhdr->h_source, vid);
1961
goto allow;
1962
}
1963
1964
/* if it is our own claim ... */
1965
backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
1966
own_claim = batadv_compare_eth(backbone_gw->orig,
1967
primary_if->net_dev->dev_addr);
1968
batadv_backbone_gw_put(backbone_gw);
1969
1970
if (own_claim) {
1971
/* ... allow it in any case */
1972
claim->lasttime = jiffies;
1973
goto allow;
1974
}
1975
1976
/* if it is a multicast ... */
1977
if (is_multicast_ether_addr(ethhdr->h_dest) &&
1978
(packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
1979
/* ... drop it. the responsible gateway is in charge.
1980
*
1981
* We need to check packet type because with the gateway
1982
* feature, broadcasts (like DHCP requests) may be sent
1983
* using a unicast 4 address packet type. See comment above.
1984
*/
1985
goto handled;
1986
} else {
1987
/* seems the client considers us as its best gateway.
1988
* send a claim and update the claim table
1989
* immediately.
1990
*/
1991
batadv_handle_claim(bat_priv, primary_if,
1992
primary_if->net_dev->dev_addr,
1993
ethhdr->h_source, vid);
1994
goto allow;
1995
}
1996
allow:
1997
batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
1998
ret = false;
1999
goto out;
2000
2001
handled:
2002
kfree_skb(skb);
2003
ret = true;
2004
2005
out:
2006
batadv_hardif_put(primary_if);
2007
batadv_claim_put(claim);
2008
return ret;
2009
}
2010
2011
/**
2012
* batadv_bla_tx() - check packets going into the mesh
2013
* @bat_priv: the bat priv with all the mesh interface information
2014
* @skb: the frame to be checked
2015
* @vid: the VLAN ID of the frame
2016
*
2017
* batadv_bla_tx checks if:
2018
* * a claim was received which has to be processed
2019
* * the frame is allowed on the mesh
2020
*
2021
* in these cases, the skb is further handled by this function.
2022
*
2023
* This call might reallocate skb data.
2024
*
2025
* Return: true if handled, otherwise it returns false and the caller shall
2026
* further process the skb.
2027
*/
2028
bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
2029
unsigned short vid)
2030
{
2031
struct ethhdr *ethhdr;
2032
struct batadv_bla_claim search_claim, *claim = NULL;
2033
struct batadv_bla_backbone_gw *backbone_gw;
2034
struct batadv_hard_iface *primary_if;
2035
bool client_roamed;
2036
bool ret = false;
2037
2038
primary_if = batadv_primary_if_get_selected(bat_priv);
2039
if (!primary_if)
2040
goto out;
2041
2042
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
2043
goto allow;
2044
2045
if (batadv_bla_process_claim(bat_priv, primary_if, skb))
2046
goto handled;
2047
2048
ethhdr = eth_hdr(skb);
2049
2050
if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
2051
/* don't allow broadcasts while requests are in flight */
2052
if (is_multicast_ether_addr(ethhdr->h_dest))
2053
goto handled;
2054
2055
ether_addr_copy(search_claim.addr, ethhdr->h_source);
2056
search_claim.vid = vid;
2057
2058
claim = batadv_claim_hash_find(bat_priv, &search_claim);
2059
2060
/* if no claim exists, allow it. */
2061
if (!claim)
2062
goto allow;
2063
2064
/* check if we are responsible. */
2065
backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
2066
client_roamed = batadv_compare_eth(backbone_gw->orig,
2067
primary_if->net_dev->dev_addr);
2068
batadv_backbone_gw_put(backbone_gw);
2069
2070
if (client_roamed) {
2071
/* if yes, the client has roamed and we have
2072
* to unclaim it.
2073
*/
2074
if (batadv_has_timed_out(claim->lasttime, 100)) {
2075
/* only unclaim if the last claim entry is
2076
* older than 100 ms to make sure we really
2077
* have a roaming client here.
2078
*/
2079
batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): Roaming client %pM detected. Unclaim it.\n",
2080
__func__, ethhdr->h_source);
2081
batadv_handle_unclaim(bat_priv, primary_if,
2082
primary_if->net_dev->dev_addr,
2083
ethhdr->h_source, vid);
2084
goto allow;
2085
} else {
2086
batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): Race for claim %pM detected. Drop packet.\n",
2087
__func__, ethhdr->h_source);
2088
goto handled;
2089
}
2090
}
2091
2092
/* check if it is a multicast/broadcast frame */
2093
if (is_multicast_ether_addr(ethhdr->h_dest)) {
2094
/* drop it. the responsible gateway has forwarded it into
2095
* the backbone network.
2096
*/
2097
goto handled;
2098
} else {
2099
/* we must allow it. at least if we are
2100
* responsible for the DESTINATION.
2101
*/
2102
goto allow;
2103
}
2104
allow:
2105
batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
2106
ret = false;
2107
goto out;
2108
handled:
2109
ret = true;
2110
out:
2111
batadv_hardif_put(primary_if);
2112
batadv_claim_put(claim);
2113
return ret;
2114
}
2115
2116
/**
2117
* batadv_bla_claim_dump_entry() - dump one entry of the claim table
2118
* to a netlink socket
2119
* @msg: buffer for the message
2120
* @portid: netlink port
2121
* @cb: Control block containing additional options
2122
* @primary_if: primary interface
2123
* @claim: entry to dump
2124
*
2125
* Return: 0 or error code.
2126
*/
2127
static int
2128
batadv_bla_claim_dump_entry(struct sk_buff *msg, u32 portid,
2129
struct netlink_callback *cb,
2130
struct batadv_hard_iface *primary_if,
2131
struct batadv_bla_claim *claim)
2132
{
2133
const u8 *primary_addr = primary_if->net_dev->dev_addr;
2134
u16 backbone_crc;
2135
bool is_own;
2136
void *hdr;
2137
int ret = -EINVAL;
2138
2139
hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
2140
&batadv_netlink_family, NLM_F_MULTI,
2141
BATADV_CMD_GET_BLA_CLAIM);
2142
if (!hdr) {
2143
ret = -ENOBUFS;
2144
goto out;
2145
}
2146
2147
genl_dump_check_consistent(cb, hdr);
2148
2149
is_own = batadv_compare_eth(claim->backbone_gw->orig,
2150
primary_addr);
2151
2152
spin_lock_bh(&claim->backbone_gw->crc_lock);
2153
backbone_crc = claim->backbone_gw->crc;
2154
spin_unlock_bh(&claim->backbone_gw->crc_lock);
2155
2156
if (is_own)
2157
if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) {
2158
genlmsg_cancel(msg, hdr);
2159
goto out;
2160
}
2161
2162
if (nla_put(msg, BATADV_ATTR_BLA_ADDRESS, ETH_ALEN, claim->addr) ||
2163
nla_put_u16(msg, BATADV_ATTR_BLA_VID, claim->vid) ||
2164
nla_put(msg, BATADV_ATTR_BLA_BACKBONE, ETH_ALEN,
2165
claim->backbone_gw->orig) ||
2166
nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
2167
backbone_crc)) {
2168
genlmsg_cancel(msg, hdr);
2169
goto out;
2170
}
2171
2172
genlmsg_end(msg, hdr);
2173
ret = 0;
2174
2175
out:
2176
return ret;
2177
}
2178
2179
/**
2180
* batadv_bla_claim_dump_bucket() - dump one bucket of the claim table
2181
* to a netlink socket
2182
* @msg: buffer for the message
2183
* @portid: netlink port
2184
* @cb: Control block containing additional options
2185
* @primary_if: primary interface
2186
* @hash: hash to dump
2187
* @bucket: bucket index to dump
2188
* @idx_skip: How many entries to skip
2189
*
2190
* Return: always 0.
2191
*/
2192
static int
2193
batadv_bla_claim_dump_bucket(struct sk_buff *msg, u32 portid,
2194
struct netlink_callback *cb,
2195
struct batadv_hard_iface *primary_if,
2196
struct batadv_hashtable *hash, unsigned int bucket,
2197
int *idx_skip)
2198
{
2199
struct batadv_bla_claim *claim;
2200
int idx = 0;
2201
int ret = 0;
2202
2203
spin_lock_bh(&hash->list_locks[bucket]);
2204
cb->seq = atomic_read(&hash->generation) << 1 | 1;
2205
2206
hlist_for_each_entry(claim, &hash->table[bucket], hash_entry) {
2207
if (idx++ < *idx_skip)
2208
continue;
2209
2210
ret = batadv_bla_claim_dump_entry(msg, portid, cb,
2211
primary_if, claim);
2212
if (ret) {
2213
*idx_skip = idx - 1;
2214
goto unlock;
2215
}
2216
}
2217
2218
*idx_skip = 0;
2219
unlock:
2220
spin_unlock_bh(&hash->list_locks[bucket]);
2221
return ret;
2222
}
2223
2224
/**
2225
* batadv_bla_claim_dump() - dump claim table to a netlink socket
2226
* @msg: buffer for the message
2227
* @cb: callback structure containing arguments
2228
*
2229
* Return: message length.
2230
*/
2231
int batadv_bla_claim_dump(struct sk_buff *msg, struct netlink_callback *cb)
2232
{
2233
struct batadv_hard_iface *primary_if = NULL;
2234
int portid = NETLINK_CB(cb->skb).portid;
2235
struct net_device *mesh_iface;
2236
struct batadv_hashtable *hash;
2237
struct batadv_priv *bat_priv;
2238
int bucket = cb->args[0];
2239
int idx = cb->args[1];
2240
int ret = 0;
2241
2242
mesh_iface = batadv_netlink_get_meshif(cb);
2243
if (IS_ERR(mesh_iface))
2244
return PTR_ERR(mesh_iface);
2245
2246
bat_priv = netdev_priv(mesh_iface);
2247
hash = bat_priv->bla.claim_hash;
2248
2249
primary_if = batadv_primary_if_get_selected(bat_priv);
2250
if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
2251
ret = -ENOENT;
2252
goto out;
2253
}
2254
2255
while (bucket < hash->size) {
2256
if (batadv_bla_claim_dump_bucket(msg, portid, cb, primary_if,
2257
hash, bucket, &idx))
2258
break;
2259
bucket++;
2260
}
2261
2262
cb->args[0] = bucket;
2263
cb->args[1] = idx;
2264
2265
ret = msg->len;
2266
2267
out:
2268
batadv_hardif_put(primary_if);
2269
2270
dev_put(mesh_iface);
2271
2272
return ret;
2273
}
2274
2275
/**
2276
* batadv_bla_backbone_dump_entry() - dump one entry of the backbone table to a
2277
* netlink socket
2278
* @msg: buffer for the message
2279
* @portid: netlink port
2280
* @cb: Control block containing additional options
2281
* @primary_if: primary interface
2282
* @backbone_gw: entry to dump
2283
*
2284
* Return: 0 or error code.
2285
*/
2286
static int
2287
batadv_bla_backbone_dump_entry(struct sk_buff *msg, u32 portid,
2288
struct netlink_callback *cb,
2289
struct batadv_hard_iface *primary_if,
2290
struct batadv_bla_backbone_gw *backbone_gw)
2291
{
2292
const u8 *primary_addr = primary_if->net_dev->dev_addr;
2293
u16 backbone_crc;
2294
bool is_own;
2295
int msecs;
2296
void *hdr;
2297
int ret = -EINVAL;
2298
2299
hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
2300
&batadv_netlink_family, NLM_F_MULTI,
2301
BATADV_CMD_GET_BLA_BACKBONE);
2302
if (!hdr) {
2303
ret = -ENOBUFS;
2304
goto out;
2305
}
2306
2307
genl_dump_check_consistent(cb, hdr);
2308
2309
is_own = batadv_compare_eth(backbone_gw->orig, primary_addr);
2310
2311
spin_lock_bh(&backbone_gw->crc_lock);
2312
backbone_crc = backbone_gw->crc;
2313
spin_unlock_bh(&backbone_gw->crc_lock);
2314
2315
msecs = jiffies_to_msecs(jiffies - backbone_gw->lasttime);
2316
2317
if (is_own)
2318
if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) {
2319
genlmsg_cancel(msg, hdr);
2320
goto out;
2321
}
2322
2323
if (nla_put(msg, BATADV_ATTR_BLA_BACKBONE, ETH_ALEN,
2324
backbone_gw->orig) ||
2325
nla_put_u16(msg, BATADV_ATTR_BLA_VID, backbone_gw->vid) ||
2326
nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
2327
backbone_crc) ||
2328
nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) {
2329
genlmsg_cancel(msg, hdr);
2330
goto out;
2331
}
2332
2333
genlmsg_end(msg, hdr);
2334
ret = 0;
2335
2336
out:
2337
return ret;
2338
}
2339
2340
/**
2341
* batadv_bla_backbone_dump_bucket() - dump one bucket of the backbone table to
2342
* a netlink socket
2343
* @msg: buffer for the message
2344
* @portid: netlink port
2345
* @cb: Control block containing additional options
2346
* @primary_if: primary interface
2347
* @hash: hash to dump
2348
* @bucket: bucket index to dump
2349
* @idx_skip: How many entries to skip
2350
*
2351
* Return: always 0.
2352
*/
2353
static int
2354
batadv_bla_backbone_dump_bucket(struct sk_buff *msg, u32 portid,
2355
struct netlink_callback *cb,
2356
struct batadv_hard_iface *primary_if,
2357
struct batadv_hashtable *hash,
2358
unsigned int bucket, int *idx_skip)
2359
{
2360
struct batadv_bla_backbone_gw *backbone_gw;
2361
int idx = 0;
2362
int ret = 0;
2363
2364
spin_lock_bh(&hash->list_locks[bucket]);
2365
cb->seq = atomic_read(&hash->generation) << 1 | 1;
2366
2367
hlist_for_each_entry(backbone_gw, &hash->table[bucket], hash_entry) {
2368
if (idx++ < *idx_skip)
2369
continue;
2370
2371
ret = batadv_bla_backbone_dump_entry(msg, portid, cb,
2372
primary_if, backbone_gw);
2373
if (ret) {
2374
*idx_skip = idx - 1;
2375
goto unlock;
2376
}
2377
}
2378
2379
*idx_skip = 0;
2380
unlock:
2381
spin_unlock_bh(&hash->list_locks[bucket]);
2382
return ret;
2383
}
2384
2385
/**
2386
* batadv_bla_backbone_dump() - dump backbone table to a netlink socket
2387
* @msg: buffer for the message
2388
* @cb: callback structure containing arguments
2389
*
2390
* Return: message length.
2391
*/
2392
int batadv_bla_backbone_dump(struct sk_buff *msg, struct netlink_callback *cb)
2393
{
2394
struct batadv_hard_iface *primary_if = NULL;
2395
int portid = NETLINK_CB(cb->skb).portid;
2396
struct net_device *mesh_iface;
2397
struct batadv_hashtable *hash;
2398
struct batadv_priv *bat_priv;
2399
int bucket = cb->args[0];
2400
int idx = cb->args[1];
2401
int ret = 0;
2402
2403
mesh_iface = batadv_netlink_get_meshif(cb);
2404
if (IS_ERR(mesh_iface))
2405
return PTR_ERR(mesh_iface);
2406
2407
bat_priv = netdev_priv(mesh_iface);
2408
hash = bat_priv->bla.backbone_hash;
2409
2410
primary_if = batadv_primary_if_get_selected(bat_priv);
2411
if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
2412
ret = -ENOENT;
2413
goto out;
2414
}
2415
2416
while (bucket < hash->size) {
2417
if (batadv_bla_backbone_dump_bucket(msg, portid, cb, primary_if,
2418
hash, bucket, &idx))
2419
break;
2420
bucket++;
2421
}
2422
2423
cb->args[0] = bucket;
2424
cb->args[1] = idx;
2425
2426
ret = msg->len;
2427
2428
out:
2429
batadv_hardif_put(primary_if);
2430
2431
dev_put(mesh_iface);
2432
2433
return ret;
2434
}
2435
2436
#ifdef CONFIG_BATMAN_ADV_DAT
2437
/**
2438
* batadv_bla_check_claim() - check if address is claimed
2439
*
2440
* @bat_priv: the bat priv with all the mesh interface information
2441
* @addr: mac address of which the claim status is checked
2442
* @vid: the VLAN ID
2443
*
2444
* addr is checked if this address is claimed by the local device itself.
2445
*
2446
* Return: true if bla is disabled or the mac is claimed by the device,
2447
* false if the device addr is already claimed by another gateway
2448
*/
2449
bool batadv_bla_check_claim(struct batadv_priv *bat_priv,
2450
u8 *addr, unsigned short vid)
2451
{
2452
struct batadv_bla_claim search_claim;
2453
struct batadv_bla_claim *claim = NULL;
2454
struct batadv_hard_iface *primary_if = NULL;
2455
bool ret = true;
2456
2457
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
2458
return ret;
2459
2460
primary_if = batadv_primary_if_get_selected(bat_priv);
2461
if (!primary_if)
2462
return ret;
2463
2464
/* First look if the mac address is claimed */
2465
ether_addr_copy(search_claim.addr, addr);
2466
search_claim.vid = vid;
2467
2468
claim = batadv_claim_hash_find(bat_priv, &search_claim);
2469
2470
/* If there is a claim and we are not owner of the claim,
2471
* return false.
2472
*/
2473
if (claim) {
2474
if (!batadv_compare_eth(claim->backbone_gw->orig,
2475
primary_if->net_dev->dev_addr))
2476
ret = false;
2477
batadv_claim_put(claim);
2478
}
2479
2480
batadv_hardif_put(primary_if);
2481
return ret;
2482
}
2483
#endif
2484
2485