cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bridge_loop_avoidance.c (70998B)


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