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