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