Blame view

net/batman-adv/bridge_loop_avoidance.c 72.9 KB
7db7d9f36   Sven Eckelmann   batman-adv: Add S...
1
  // SPDX-License-Identifier: GPL-2.0
68e039f96   Sven Eckelmann   batman-adv: Updat...
2
  /* Copyright (C) 2011-2020  B.A.T.M.A.N. contributors:
23721387c   Simon Wunderlich   batman-adv: add b...
3
4
   *
   * Simon Wunderlich
23721387c   Simon Wunderlich   batman-adv: add b...
5
   */
23721387c   Simon Wunderlich   batman-adv: add b...
6
  #include "bridge_loop_avoidance.h"
1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
7
  #include "main.h"
23721387c   Simon Wunderlich   batman-adv: add b...
8

1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
9
10
11
  #include <linux/atomic.h>
  #include <linux/byteorder/generic.h>
  #include <linux/compiler.h>
23721387c   Simon Wunderlich   batman-adv: add b...
12
  #include <linux/crc16.h>
1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
13
14
  #include <linux/errno.h>
  #include <linux/etherdevice.h>
b92b94ac7   Sven Eckelmann   batman-adv: inclu...
15
  #include <linux/gfp.h>
23721387c   Simon Wunderlich   batman-adv: add b...
16
  #include <linux/if_arp.h>
1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
17
  #include <linux/if_ether.h>
23721387c   Simon Wunderlich   batman-adv: add b...
18
  #include <linux/if_vlan.h>
1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
19
20
21
  #include <linux/jhash.h>
  #include <linux/jiffies.h>
  #include <linux/kernel.h>
06e56ded8   Sven Eckelmann   batman-adv: Conve...
22
  #include <linux/kref.h>
1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
23
24
25
  #include <linux/list.h>
  #include <linux/lockdep.h>
  #include <linux/netdevice.h>
04f3f5bf1   Andrew Lunn   batman-adv: add B...
26
  #include <linux/netlink.h>
4bba9dab8   Sven Eckelmann   batman-adv: Add m...
27
  #include <linux/preempt.h>
1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
28
29
30
31
32
33
34
35
36
37
  #include <linux/rculist.h>
  #include <linux/rcupdate.h>
  #include <linux/seq_file.h>
  #include <linux/skbuff.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/stddef.h>
  #include <linux/string.h>
  #include <linux/workqueue.h>
  #include <net/arp.h>
04f3f5bf1   Andrew Lunn   batman-adv: add B...
38
39
40
  #include <net/genetlink.h>
  #include <net/netlink.h>
  #include <net/sock.h>
fec149f5d   Sven Eckelmann   batman-adv: Conve...
41
  #include <uapi/linux/batadv_packet.h>
04f3f5bf1   Andrew Lunn   batman-adv: add B...
42
  #include <uapi/linux/batman_adv.h>
1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
43
44
45
  
  #include "hard-interface.h"
  #include "hash.h"
ba412080f   Sven Eckelmann   batman-adv: Conso...
46
  #include "log.h"
04f3f5bf1   Andrew Lunn   batman-adv: add B...
47
  #include "netlink.h"
1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
48
  #include "originator.h"
04f3f5bf1   Andrew Lunn   batman-adv: add B...
49
  #include "soft-interface.h"
1e2c2a4fe   Sven Eckelmann   batman-adv: Add r...
50
  #include "translation-table.h"
23721387c   Simon Wunderlich   batman-adv: add b...
51

6b5e971a2   Sven Eckelmann   batman-adv: Repla...
52
  static const u8 batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05};
23721387c   Simon Wunderlich   batman-adv: add b...
53

3b300de32   Sven Eckelmann   batman-adv: Prefi...
54
  static void batadv_bla_periodic_work(struct work_struct *work);
bae987747   Marek Lindner   batman-adv: renam...
55
56
57
  static void
  batadv_bla_send_announce(struct batadv_priv *bat_priv,
  			 struct batadv_bla_backbone_gw *backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
58

62fe710f6   Sven Eckelmann   batman-adv: Fix k...
59
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
60
   * batadv_choose_claim() - choose the right bucket for a claim.
04e14be65   Simon Wunderlich   batman-adv: Updat...
61
62
   * @data: data to hash
   * @size: size of the hash table
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
63
   *
04e14be65   Simon Wunderlich   batman-adv: Updat...
64
   * Return: the hash index of the claim
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
65
   */
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
66
  static inline u32 batadv_choose_claim(const void *data, u32 size)
23721387c   Simon Wunderlich   batman-adv: add b...
67
  {
712bbfe46   Marek Lindner   batman-adv: renam...
68
  	struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
69
  	u32 hash = 0;
23721387c   Simon Wunderlich   batman-adv: add b...
70

36fd61cb8   Sven Eckelmann   batman-adv: Use c...
71
72
  	hash = jhash(&claim->addr, sizeof(claim->addr), hash);
  	hash = jhash(&claim->vid, sizeof(claim->vid), hash);
23721387c   Simon Wunderlich   batman-adv: add b...
73
74
75
  
  	return hash % size;
  }
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
76
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
77
   * batadv_choose_backbone_gw() - choose the right bucket for a backbone gateway.
04e14be65   Simon Wunderlich   batman-adv: Updat...
78
79
   * @data: data to hash
   * @size: size of the hash table
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
80
   *
04e14be65   Simon Wunderlich   batman-adv: Updat...
81
   * Return: the hash index of the backbone gateway
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
82
   */
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
83
  static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
23721387c   Simon Wunderlich   batman-adv: add b...
84
  {
097930e85   Linus Lüssing   batman-adv: bla: ...
85
  	const struct batadv_bla_backbone_gw *gw;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
86
  	u32 hash = 0;
23721387c   Simon Wunderlich   batman-adv: add b...
87

097930e85   Linus Lüssing   batman-adv: bla: ...
88
89
90
  	gw = (struct batadv_bla_backbone_gw *)data;
  	hash = jhash(&gw->orig, sizeof(gw->orig), hash);
  	hash = jhash(&gw->vid, sizeof(gw->vid), hash);
23721387c   Simon Wunderlich   batman-adv: add b...
91
92
93
  
  	return hash % size;
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
94
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
95
   * batadv_compare_backbone_gw() - compare address and vid of two backbone gws
04e14be65   Simon Wunderlich   batman-adv: Updat...
96
97
98
   * @node: list node of the first entry to compare
   * @data2: pointer to the second backbone gateway
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
99
   * Return: true if the backbones have the same data, false otherwise
04e14be65   Simon Wunderlich   batman-adv: Updat...
100
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
101
102
  static bool batadv_compare_backbone_gw(const struct hlist_node *node,
  				       const void *data2)
23721387c   Simon Wunderlich   batman-adv: add b...
103
  {
bae987747   Marek Lindner   batman-adv: renam...
104
  	const void *data1 = container_of(node, struct batadv_bla_backbone_gw,
23721387c   Simon Wunderlich   batman-adv: add b...
105
  					 hash_entry);
4f248cff9   Sven Eckelmann   batman-adv: Remov...
106
107
  	const struct batadv_bla_backbone_gw *gw1 = data1;
  	const struct batadv_bla_backbone_gw *gw2 = data2;
23721387c   Simon Wunderlich   batman-adv: add b...
108

c76d15253   Simon Wunderlich   batman-adv: fix b...
109
  	if (!batadv_compare_eth(gw1->orig, gw2->orig))
4b426b108   Sven Eckelmann   batman-adv: Use b...
110
  		return false;
c76d15253   Simon Wunderlich   batman-adv: fix b...
111
112
  
  	if (gw1->vid != gw2->vid)
4b426b108   Sven Eckelmann   batman-adv: Use b...
113
  		return false;
c76d15253   Simon Wunderlich   batman-adv: fix b...
114

4b426b108   Sven Eckelmann   batman-adv: Use b...
115
  	return true;
23721387c   Simon Wunderlich   batman-adv: add b...
116
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
117
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
118
   * batadv_compare_claim() - compare address and vid of two claims
04e14be65   Simon Wunderlich   batman-adv: Updat...
119
120
121
   * @node: list node of the first entry to compare
   * @data2: pointer to the second claims
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
122
   * Return: true if the claim have the same data, 0 otherwise
04e14be65   Simon Wunderlich   batman-adv: Updat...
123
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
124
125
  static bool batadv_compare_claim(const struct hlist_node *node,
  				 const void *data2)
23721387c   Simon Wunderlich   batman-adv: add b...
126
  {
712bbfe46   Marek Lindner   batman-adv: renam...
127
  	const void *data1 = container_of(node, struct batadv_bla_claim,
23721387c   Simon Wunderlich   batman-adv: add b...
128
  					 hash_entry);
4f248cff9   Sven Eckelmann   batman-adv: Remov...
129
130
  	const struct batadv_bla_claim *cl1 = data1;
  	const struct batadv_bla_claim *cl2 = data2;
c76d15253   Simon Wunderlich   batman-adv: fix b...
131
132
  
  	if (!batadv_compare_eth(cl1->addr, cl2->addr))
4b426b108   Sven Eckelmann   batman-adv: Use b...
133
  		return false;
c76d15253   Simon Wunderlich   batman-adv: fix b...
134
135
  
  	if (cl1->vid != cl2->vid)
4b426b108   Sven Eckelmann   batman-adv: Use b...
136
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
137

4b426b108   Sven Eckelmann   batman-adv: Use b...
138
  	return true;
23721387c   Simon Wunderlich   batman-adv: add b...
139
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
140
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
141
   * batadv_backbone_gw_release() - release backbone gw from lists and queue for
06e56ded8   Sven Eckelmann   batman-adv: Conve...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
   *  free after rcu grace period
   * @ref: kref pointer of the backbone gw
   */
  static void batadv_backbone_gw_release(struct kref *ref)
  {
  	struct batadv_bla_backbone_gw *backbone_gw;
  
  	backbone_gw = container_of(ref, struct batadv_bla_backbone_gw,
  				   refcount);
  
  	kfree_rcu(backbone_gw, rcu);
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
156
   * batadv_backbone_gw_put() - decrement the backbone gw refcounter and possibly
c8b86c124   Sven Eckelmann   batman-adv: Renam...
157
   *  release it
04e14be65   Simon Wunderlich   batman-adv: Updat...
158
159
   * @backbone_gw: backbone gateway to be free'd
   */
c8b86c124   Sven Eckelmann   batman-adv: Renam...
160
  static void batadv_backbone_gw_put(struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
161
  {
06e56ded8   Sven Eckelmann   batman-adv: Conve...
162
  	kref_put(&backbone_gw->refcount, batadv_backbone_gw_release);
23721387c   Simon Wunderlich   batman-adv: add b...
163
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
164
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
165
166
   * batadv_claim_release() - release claim from lists and queue for free after
   *  rcu grace period
04e14be65   Simon Wunderlich   batman-adv: Updat...
167
168
   * @ref: kref pointer of the claim
   */
71b7e3d31   Sven Eckelmann   batman-adv: Conve...
169
  static void batadv_claim_release(struct kref *ref)
23721387c   Simon Wunderlich   batman-adv: add b...
170
  {
71b7e3d31   Sven Eckelmann   batman-adv: Conve...
171
  	struct batadv_bla_claim *claim;
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
172
  	struct batadv_bla_backbone_gw *old_backbone_gw;
71b7e3d31   Sven Eckelmann   batman-adv: Conve...
173
174
  
  	claim = container_of(ref, struct batadv_bla_claim, refcount);
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
175
176
177
178
179
180
181
182
183
184
  	spin_lock_bh(&claim->backbone_lock);
  	old_backbone_gw = claim->backbone_gw;
  	claim->backbone_gw = NULL;
  	spin_unlock_bh(&claim->backbone_lock);
  
  	spin_lock_bh(&old_backbone_gw->crc_lock);
  	old_backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
  	spin_unlock_bh(&old_backbone_gw->crc_lock);
  
  	batadv_backbone_gw_put(old_backbone_gw);
63b399272   Sven Eckelmann   batman-adv: Avoid...
185
  	kfree_rcu(claim, rcu);
23721387c   Simon Wunderlich   batman-adv: add b...
186
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
187
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
188
   * batadv_claim_put() - decrement the claim refcounter and possibly release it
04e14be65   Simon Wunderlich   batman-adv: Updat...
189
190
   * @claim: claim to be free'd
   */
321e3e088   Sven Eckelmann   batman-adv: Renam...
191
  static void batadv_claim_put(struct batadv_bla_claim *claim)
23721387c   Simon Wunderlich   batman-adv: add b...
192
  {
71b7e3d31   Sven Eckelmann   batman-adv: Conve...
193
  	kref_put(&claim->refcount, batadv_claim_release);
23721387c   Simon Wunderlich   batman-adv: add b...
194
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
195
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
196
   * batadv_claim_hash_find() - looks for a claim in the claim hash
1b371d130   Simon Wunderlich   batman-adv: use c...
197
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
198
199
   * @data: search data (may be local/static data)
   *
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
200
   * Return: claim if found or NULL otherwise.
23721387c   Simon Wunderlich   batman-adv: add b...
201
   */
6fc77a548   Sven Eckelmann   batman-adv: Fix f...
202
203
204
  static struct batadv_bla_claim *
  batadv_claim_hash_find(struct batadv_priv *bat_priv,
  		       struct batadv_bla_claim *data)
23721387c   Simon Wunderlich   batman-adv: add b...
205
  {
807736f6e   Sven Eckelmann   batman-adv: Split...
206
  	struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
207
  	struct hlist_head *head;
712bbfe46   Marek Lindner   batman-adv: renam...
208
209
  	struct batadv_bla_claim *claim;
  	struct batadv_bla_claim *claim_tmp = NULL;
23721387c   Simon Wunderlich   batman-adv: add b...
210
211
212
213
  	int index;
  
  	if (!hash)
  		return NULL;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
214
  	index = batadv_choose_claim(data, hash->size);
23721387c   Simon Wunderlich   batman-adv: add b...
215
216
217
  	head = &hash->table[index];
  
  	rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
218
  	hlist_for_each_entry_rcu(claim, head, hash_entry) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
219
  		if (!batadv_compare_claim(&claim->hash_entry, data))
23721387c   Simon Wunderlich   batman-adv: add b...
220
  			continue;
71b7e3d31   Sven Eckelmann   batman-adv: Conve...
221
  		if (!kref_get_unless_zero(&claim->refcount))
23721387c   Simon Wunderlich   batman-adv: add b...
222
223
224
225
226
227
228
229
230
  			continue;
  
  		claim_tmp = claim;
  		break;
  	}
  	rcu_read_unlock();
  
  	return claim_tmp;
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
231
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
232
   * batadv_backbone_hash_find() - looks for a backbone gateway in the hash
2c53040f0   Ben Hutchings   net: Fix (nearly-...
233
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
234
235
236
   * @addr: the address of the originator
   * @vid: the VLAN ID
   *
04e14be65   Simon Wunderlich   batman-adv: Updat...
237
   * Return: backbone gateway if found or NULL otherwise
23721387c   Simon Wunderlich   batman-adv: add b...
238
   */
bae987747   Marek Lindner   batman-adv: renam...
239
  static struct batadv_bla_backbone_gw *
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
240
241
  batadv_backbone_hash_find(struct batadv_priv *bat_priv, u8 *addr,
  			  unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
242
  {
807736f6e   Sven Eckelmann   batman-adv: Split...
243
  	struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
244
  	struct hlist_head *head;
bae987747   Marek Lindner   batman-adv: renam...
245
246
  	struct batadv_bla_backbone_gw search_entry, *backbone_gw;
  	struct batadv_bla_backbone_gw *backbone_gw_tmp = NULL;
23721387c   Simon Wunderlich   batman-adv: add b...
247
248
249
250
  	int index;
  
  	if (!hash)
  		return NULL;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
251
  	ether_addr_copy(search_entry.orig, addr);
23721387c   Simon Wunderlich   batman-adv: add b...
252
  	search_entry.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
253
  	index = batadv_choose_backbone_gw(&search_entry, hash->size);
23721387c   Simon Wunderlich   batman-adv: add b...
254
255
256
  	head = &hash->table[index];
  
  	rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
257
  	hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
258
259
  		if (!batadv_compare_backbone_gw(&backbone_gw->hash_entry,
  						&search_entry))
23721387c   Simon Wunderlich   batman-adv: add b...
260
  			continue;
06e56ded8   Sven Eckelmann   batman-adv: Conve...
261
  		if (!kref_get_unless_zero(&backbone_gw->refcount))
23721387c   Simon Wunderlich   batman-adv: add b...
262
263
264
265
266
267
268
269
270
  			continue;
  
  		backbone_gw_tmp = backbone_gw;
  		break;
  	}
  	rcu_read_unlock();
  
  	return backbone_gw_tmp;
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
271
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
272
   * batadv_bla_del_backbone_claims() - delete all claims for a backbone
04e14be65   Simon Wunderlich   batman-adv: Updat...
273
274
   * @backbone_gw: backbone gateway where the claims should be removed
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
275
  static void
bae987747   Marek Lindner   batman-adv: renam...
276
  batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
277
  {
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
278
  	struct batadv_hashtable *hash;
b67bfe0d4   Sasha Levin   hlist: drop the n...
279
  	struct hlist_node *node_tmp;
23721387c   Simon Wunderlich   batman-adv: add b...
280
  	struct hlist_head *head;
712bbfe46   Marek Lindner   batman-adv: renam...
281
  	struct batadv_bla_claim *claim;
23721387c   Simon Wunderlich   batman-adv: add b...
282
283
  	int i;
  	spinlock_t *list_lock;	/* protects write access to the hash lists */
807736f6e   Sven Eckelmann   batman-adv: Split...
284
  	hash = backbone_gw->bat_priv->bla.claim_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
285
286
287
288
289
290
291
292
  	if (!hash)
  		return;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  		list_lock = &hash->list_locks[i];
  
  		spin_lock_bh(list_lock);
b67bfe0d4   Sasha Levin   hlist: drop the n...
293
  		hlist_for_each_entry_safe(claim, node_tmp,
23721387c   Simon Wunderlich   batman-adv: add b...
294
  					  head, hash_entry) {
23721387c   Simon Wunderlich   batman-adv: add b...
295
296
  			if (claim->backbone_gw != backbone_gw)
  				continue;
321e3e088   Sven Eckelmann   batman-adv: Renam...
297
  			batadv_claim_put(claim);
b67bfe0d4   Sasha Levin   hlist: drop the n...
298
  			hlist_del_rcu(&claim->hash_entry);
23721387c   Simon Wunderlich   batman-adv: add b...
299
300
301
  		}
  		spin_unlock_bh(list_lock);
  	}
3f68785e6   Antonio Quartulli   batman-adv: fix m...
302
  	/* all claims gone, initialize CRC */
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
303
  	spin_lock_bh(&backbone_gw->crc_lock);
3964f7285   Sven Eckelmann   batman-adv: Prefi...
304
  	backbone_gw->crc = BATADV_BLA_CRC_INIT;
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
305
  	spin_unlock_bh(&backbone_gw->crc_lock);
23721387c   Simon Wunderlich   batman-adv: add b...
306
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
307
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
308
   * batadv_bla_send_claim() - sends a claim frame according to the provided info
2c53040f0   Ben Hutchings   net: Fix (nearly-...
309
   * @bat_priv: the bat priv with all the soft interface information
e33571898   Martin Hundebøll   batman-adv: kerne...
310
   * @mac: the mac address to be announced within the claim
23721387c   Simon Wunderlich   batman-adv: add b...
311
312
   * @vid: the VLAN ID
   * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...)
23721387c   Simon Wunderlich   batman-adv: add b...
313
   */
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
314
  static void batadv_bla_send_claim(struct batadv_priv *bat_priv, u8 *mac,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
315
  				  unsigned short vid, int claimtype)
23721387c   Simon Wunderlich   batman-adv: add b...
316
317
318
  {
  	struct sk_buff *skb;
  	struct ethhdr *ethhdr;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
319
  	struct batadv_hard_iface *primary_if;
23721387c   Simon Wunderlich   batman-adv: add b...
320
  	struct net_device *soft_iface;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
321
  	u8 *hw_src;
964126901   Sven Eckelmann   batman-adv: Prefi...
322
  	struct batadv_bla_claim_dst local_claim_dest;
3e2f1a1bb   Al Viro   batman-adv: trivi...
323
  	__be32 zeroip = 0;
23721387c   Simon Wunderlich   batman-adv: add b...
324

e5d89254b   Sven Eckelmann   batman-adv: Prefi...
325
  	primary_if = batadv_primary_if_get_selected(bat_priv);
23721387c   Simon Wunderlich   batman-adv: add b...
326
327
  	if (!primary_if)
  		return;
807736f6e   Sven Eckelmann   batman-adv: Split...
328
  	memcpy(&local_claim_dest, &bat_priv->bla.claim_dest,
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
329
  	       sizeof(local_claim_dest));
23721387c   Simon Wunderlich   batman-adv: add b...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
  	local_claim_dest.type = claimtype;
  
  	soft_iface = primary_if->soft_iface;
  
  	skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
  			 /* IP DST: 0.0.0.0 */
  			 zeroip,
  			 primary_if->soft_iface,
  			 /* IP SRC: 0.0.0.0 */
  			 zeroip,
  			 /* Ethernet DST: Broadcast */
  			 NULL,
  			 /* Ethernet SRC/HW SRC:  originator mac */
  			 primary_if->net_dev->dev_addr,
99e966fc9   Simon Wunderlich   batman-adv: corre...
344
  			 /* HW DST: FF:43:05:XX:YY:YY
23721387c   Simon Wunderlich   batman-adv: add b...
345
  			  * with XX   = claim type
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
346
  			  * and YY:YY = group id
23721387c   Simon Wunderlich   batman-adv: add b...
347
  			  */
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
348
  			 (u8 *)&local_claim_dest);
23721387c   Simon Wunderlich   batman-adv: add b...
349
350
351
352
353
  
  	if (!skb)
  		goto out;
  
  	ethhdr = (struct ethhdr *)skb->data;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
354
  	hw_src = (u8 *)ethhdr + ETH_HLEN + sizeof(struct arphdr);
23721387c   Simon Wunderlich   batman-adv: add b...
355
356
357
  
  	/* now we pretend that the client would have sent this ... */
  	switch (claimtype) {
3eb8773e3   Simon Wunderlich   batman-adv: renam...
358
  	case BATADV_CLAIM_TYPE_CLAIM:
23721387c   Simon Wunderlich   batman-adv: add b...
359
360
361
  		/* normal claim frame
  		 * set Ethernet SRC to the clients mac
  		 */
8fdd01530   Antonio Quartulli   batman-adv: prefe...
362
  		ether_addr_copy(ethhdr->h_source, mac);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
363
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
364
365
  			   "%s(): CLAIM %pM on vid %d
  ", __func__, mac,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
366
  			   batadv_print_vid(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
367
  		break;
3eb8773e3   Simon Wunderlich   batman-adv: renam...
368
  	case BATADV_CLAIM_TYPE_UNCLAIM:
23721387c   Simon Wunderlich   batman-adv: add b...
369
370
371
  		/* unclaim frame
  		 * set HW SRC to the clients mac
  		 */
8fdd01530   Antonio Quartulli   batman-adv: prefe...
372
  		ether_addr_copy(hw_src, mac);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
373
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
374
375
  			   "%s(): UNCLAIM %pM on vid %d
  ", __func__, mac,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
376
  			   batadv_print_vid(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
377
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
378
  	case BATADV_CLAIM_TYPE_ANNOUNCE:
23721387c   Simon Wunderlich   batman-adv: add b...
379
380
381
  		/* announcement frame
  		 * set HW SRC to the special mac containg the crc
  		 */
8fdd01530   Antonio Quartulli   batman-adv: prefe...
382
  		ether_addr_copy(hw_src, mac);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
383
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
384
385
  			   "%s(): ANNOUNCE of %pM on vid %d
  ", __func__,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
386
  			   ethhdr->h_source, batadv_print_vid(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
387
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
388
  	case BATADV_CLAIM_TYPE_REQUEST:
23721387c   Simon Wunderlich   batman-adv: add b...
389
  		/* request frame
99e966fc9   Simon Wunderlich   batman-adv: corre...
390
391
  		 * set HW SRC and header destination to the receiving backbone
  		 * gws mac
23721387c   Simon Wunderlich   batman-adv: add b...
392
  		 */
8fdd01530   Antonio Quartulli   batman-adv: prefe...
393
394
  		ether_addr_copy(hw_src, mac);
  		ether_addr_copy(ethhdr->h_dest, mac);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
395
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
396
397
  			   "%s(): REQUEST of %pM to %pM on vid %d
  ", __func__,
5f80df670   Antonio Quartulli   batman-adv: print...
398
  			   ethhdr->h_source, ethhdr->h_dest,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
399
  			   batadv_print_vid(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
400
  		break;
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
401
402
403
  	case BATADV_CLAIM_TYPE_LOOPDETECT:
  		ether_addr_copy(ethhdr->h_source, mac);
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
404
405
406
  			   "%s(): LOOPDETECT of %pM to %pM on vid %d
  ",
  			   __func__, ethhdr->h_source, ethhdr->h_dest,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
407
  			   batadv_print_vid(vid));
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
408
409
  
  		break;
23721387c   Simon Wunderlich   batman-adv: add b...
410
  	}
10c78f585   Sven Eckelmann   batman-adv: Avoid...
411
  	if (vid & BATADV_VLAN_HAS_TAG) {
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
412
413
  		skb = vlan_insert_tag(skb, htons(ETH_P_8021Q),
  				      vid & VLAN_VID_MASK);
10c78f585   Sven Eckelmann   batman-adv: Avoid...
414
415
416
  		if (!skb)
  			goto out;
  	}
23721387c   Simon Wunderlich   batman-adv: add b...
417
418
419
  
  	skb_reset_mac_header(skb);
  	skb->protocol = eth_type_trans(skb, soft_iface);
1c9b0550f   Marek Lindner   batman-adv: conve...
420
421
422
  	batadv_inc_counter(bat_priv, BATADV_CNT_RX);
  	batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
  			   skb->len + ETH_HLEN);
23721387c   Simon Wunderlich   batman-adv: add b...
423

279e89b22   Jussi Kivilinna   batman-adv: bla: ...
424
425
426
427
  	if (in_interrupt())
  		netif_rx(skb);
  	else
  		netif_rx_ni(skb);
23721387c   Simon Wunderlich   batman-adv: add b...
428
429
  out:
  	if (primary_if)
82047ad7f   Sven Eckelmann   batman-adv: Renam...
430
  		batadv_hardif_put(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
431
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
432
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
433
   * batadv_bla_loopdetect_report() - worker for reporting the loop
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
   * @work: work queue item
   *
   * Throws an uevent, as the loopdetect check function can't do that itself
   * since the kernel may sleep while throwing uevents.
   */
  static void batadv_bla_loopdetect_report(struct work_struct *work)
  {
  	struct batadv_bla_backbone_gw *backbone_gw;
  	struct batadv_priv *bat_priv;
  	char vid_str[6] = { '\0' };
  
  	backbone_gw = container_of(work, struct batadv_bla_backbone_gw,
  				   report_work);
  	bat_priv = backbone_gw->bat_priv;
  
  	batadv_info(bat_priv->soft_iface,
  		    "Possible loop on VLAN %d detected which can't be handled by BLA - please check your network setup!
  ",
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
452
  		    batadv_print_vid(backbone_gw->vid));
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
453
  	snprintf(vid_str, sizeof(vid_str), "%d",
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
454
  		 batadv_print_vid(backbone_gw->vid));
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
455
456
457
458
459
460
461
462
463
  	vid_str[sizeof(vid_str) - 1] = 0;
  
  	batadv_throw_uevent(bat_priv, BATADV_UEV_BLA, BATADV_UEV_LOOPDETECT,
  			    vid_str);
  
  	batadv_backbone_gw_put(backbone_gw);
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
464
   * batadv_bla_get_backbone_gw() - finds or creates a backbone gateway
2c53040f0   Ben Hutchings   net: Fix (nearly-...
465
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
466
467
   * @orig: the mac address of the originator
   * @vid: the VLAN ID
e33571898   Martin Hundebøll   batman-adv: kerne...
468
   * @own_backbone: set if the requested backbone is local
23721387c   Simon Wunderlich   batman-adv: add b...
469
   *
04e14be65   Simon Wunderlich   batman-adv: Updat...
470
   * Return: the (possibly created) backbone gateway or NULL on error
23721387c   Simon Wunderlich   batman-adv: add b...
471
   */
bae987747   Marek Lindner   batman-adv: renam...
472
  static struct batadv_bla_backbone_gw *
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
473
  batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, u8 *orig,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
474
  			   unsigned short vid, bool own_backbone)
23721387c   Simon Wunderlich   batman-adv: add b...
475
  {
bae987747   Marek Lindner   batman-adv: renam...
476
  	struct batadv_bla_backbone_gw *entry;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
477
  	struct batadv_orig_node *orig_node;
23721387c   Simon Wunderlich   batman-adv: add b...
478
  	int hash_added;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
479
  	entry = batadv_backbone_hash_find(bat_priv, orig, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
480
481
482
  
  	if (entry)
  		return entry;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
483
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
484
485
  		   "%s(): not found (%pM, %d), creating new entry
  ", __func__,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
486
  		   orig, batadv_print_vid(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
487
488
489
490
491
492
493
  
  	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
  	if (!entry)
  		return NULL;
  
  	entry->vid = vid;
  	entry->lasttime = jiffies;
3964f7285   Sven Eckelmann   batman-adv: Prefi...
494
  	entry->crc = BATADV_BLA_CRC_INIT;
23721387c   Simon Wunderlich   batman-adv: add b...
495
  	entry->bat_priv = bat_priv;
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
496
  	spin_lock_init(&entry->crc_lock);
23721387c   Simon Wunderlich   batman-adv: add b...
497
  	atomic_set(&entry->request_sent, 0);
28709878b   Simon Wunderlich   batman-adv: wait ...
498
  	atomic_set(&entry->wait_periods, 0);
8fdd01530   Antonio Quartulli   batman-adv: prefe...
499
  	ether_addr_copy(entry->orig, orig);
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
500
  	INIT_WORK(&entry->report_work, batadv_bla_loopdetect_report);
06e56ded8   Sven Eckelmann   batman-adv: Conve...
501
  	kref_init(&entry->refcount);
23721387c   Simon Wunderlich   batman-adv: add b...
502

4e8389e17   Sven Eckelmann   batman-adv: Place...
503
  	kref_get(&entry->refcount);
807736f6e   Sven Eckelmann   batman-adv: Split...
504
  	hash_added = batadv_hash_add(bat_priv->bla.backbone_hash,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
505
506
507
  				     batadv_compare_backbone_gw,
  				     batadv_choose_backbone_gw, entry,
  				     &entry->hash_entry);
23721387c   Simon Wunderlich   batman-adv: add b...
508
509
510
511
512
513
  
  	if (unlikely(hash_added != 0)) {
  		/* hash failed, free the structure */
  		kfree(entry);
  		return NULL;
  	}
95fb130d6   Antonio Quartulli   batman-adv: make ...
514
  	/* this is a gateway now, remove any TT entry on this VLAN */
da641193d   Sven Eckelmann   batman-adv: Prefi...
515
  	orig_node = batadv_orig_hash_find(bat_priv, orig);
20ff9d593   Simon Wunderlich   batman-adv: don't...
516
  	if (orig_node) {
95fb130d6   Antonio Quartulli   batman-adv: make ...
517
  		batadv_tt_global_del_orig(bat_priv, orig_node, vid,
08c36d3e8   Sven Eckelmann   batman-adv: Prefi...
518
  					  "became a backbone gateway");
5d9673109   Sven Eckelmann   batman-adv: Renam...
519
  		batadv_orig_node_put(orig_node);
20ff9d593   Simon Wunderlich   batman-adv: don't...
520
  	}
52aebd6a9   Simon Wunderlich   batman-adv: send ...
521

d807f2728   Simon Wunderlich   batman-adv: allow...
522
  	if (own_backbone) {
52aebd6a9   Simon Wunderlich   batman-adv: send ...
523
  		batadv_bla_send_announce(bat_priv, entry);
d807f2728   Simon Wunderlich   batman-adv: allow...
524
525
  		/* this will be decreased in the worker thread */
  		atomic_inc(&entry->request_sent);
28709878b   Simon Wunderlich   batman-adv: wait ...
526
  		atomic_set(&entry->wait_periods, BATADV_BLA_WAIT_PERIODS);
d807f2728   Simon Wunderlich   batman-adv: allow...
527
528
  		atomic_inc(&bat_priv->bla.num_requests);
  	}
23721387c   Simon Wunderlich   batman-adv: add b...
529
530
  	return entry;
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
531
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
532
   * batadv_bla_update_own_backbone_gw() - updates the own backbone gw for a VLAN
04e14be65   Simon Wunderlich   batman-adv: Updat...
533
534
535
536
537
   * @bat_priv: the bat priv with all the soft interface information
   * @primary_if: the selected primary interface
   * @vid: VLAN identifier
   *
   * update or add the own backbone gw to make sure we announce
23721387c   Simon Wunderlich   batman-adv: add b...
538
539
   * where we receive other backbone gws
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
540
541
542
  static void
  batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,
  				  struct batadv_hard_iface *primary_if,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
543
  				  unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
544
  {
bae987747   Marek Lindner   batman-adv: renam...
545
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
546

3b300de32   Sven Eckelmann   batman-adv: Prefi...
547
548
  	backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
  						 primary_if->net_dev->dev_addr,
52aebd6a9   Simon Wunderlich   batman-adv: send ...
549
  						 vid, true);
23721387c   Simon Wunderlich   batman-adv: add b...
550
551
552
553
  	if (unlikely(!backbone_gw))
  		return;
  
  	backbone_gw->lasttime = jiffies;
c8b86c124   Sven Eckelmann   batman-adv: Renam...
554
  	batadv_backbone_gw_put(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
555
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
556
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
557
   * batadv_bla_answer_request() - answer a bla request by sending own claims
1b371d130   Simon Wunderlich   batman-adv: use c...
558
   * @bat_priv: the bat priv with all the soft interface information
e33571898   Martin Hundebøll   batman-adv: kerne...
559
   * @primary_if: interface where the request came on
23721387c   Simon Wunderlich   batman-adv: add b...
560
561
562
563
564
   * @vid: the vid where the request came on
   *
   * Repeat all of our own claims, and finally send an ANNOUNCE frame
   * to allow the requester another check if the CRC is correct now.
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
565
566
  static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
  				      struct batadv_hard_iface *primary_if,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
567
  				      unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
568
  {
23721387c   Simon Wunderlich   batman-adv: add b...
569
  	struct hlist_head *head;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
570
  	struct batadv_hashtable *hash;
712bbfe46   Marek Lindner   batman-adv: renam...
571
  	struct batadv_bla_claim *claim;
bae987747   Marek Lindner   batman-adv: renam...
572
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
573
  	int i;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
574
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
575
576
577
  		   "%s(): received a claim request, send all of our own claims again
  ",
  		   __func__);
23721387c   Simon Wunderlich   batman-adv: add b...
578

3b300de32   Sven Eckelmann   batman-adv: Prefi...
579
580
581
  	backbone_gw = batadv_backbone_hash_find(bat_priv,
  						primary_if->net_dev->dev_addr,
  						vid);
23721387c   Simon Wunderlich   batman-adv: add b...
582
583
  	if (!backbone_gw)
  		return;
807736f6e   Sven Eckelmann   batman-adv: Split...
584
  	hash = bat_priv->bla.claim_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
585
586
587
588
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
589
  		hlist_for_each_entry_rcu(claim, head, hash_entry) {
23721387c   Simon Wunderlich   batman-adv: add b...
590
591
592
  			/* only own claims are interesting */
  			if (claim->backbone_gw != backbone_gw)
  				continue;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
593
  			batadv_bla_send_claim(bat_priv, claim->addr, claim->vid,
3eb8773e3   Simon Wunderlich   batman-adv: renam...
594
  					      BATADV_CLAIM_TYPE_CLAIM);
23721387c   Simon Wunderlich   batman-adv: add b...
595
596
597
598
599
  		}
  		rcu_read_unlock();
  	}
  
  	/* finally, send an announcement frame */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
600
  	batadv_bla_send_announce(bat_priv, backbone_gw);
c8b86c124   Sven Eckelmann   batman-adv: Renam...
601
  	batadv_backbone_gw_put(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
602
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
603
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
604
   * batadv_bla_send_request() - send a request to repeat claims
1b371d130   Simon Wunderlich   batman-adv: use c...
605
   * @backbone_gw: the backbone gateway from whom we are out of sync
23721387c   Simon Wunderlich   batman-adv: add b...
606
607
608
609
610
   *
   * When the crc is wrong, ask the backbone gateway for a full table update.
   * After the request, it will repeat all of his own claims and finally
   * send an announcement claim with which we can check again.
   */
bae987747   Marek Lindner   batman-adv: renam...
611
  static void batadv_bla_send_request(struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
612
613
  {
  	/* first, remove all old entries */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
614
  	batadv_bla_del_backbone_claims(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
615

39c75a51e   Sven Eckelmann   batman-adv: Prefi...
616
617
618
  	batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
  		   "Sending REQUEST to %pM
  ", backbone_gw->orig);
23721387c   Simon Wunderlich   batman-adv: add b...
619
620
  
  	/* send request */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
621
  	batadv_bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig,
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
622
  			      backbone_gw->vid, BATADV_CLAIM_TYPE_REQUEST);
23721387c   Simon Wunderlich   batman-adv: add b...
623
624
625
  
  	/* no local broadcasts should be sent or received, for now. */
  	if (!atomic_read(&backbone_gw->request_sent)) {
807736f6e   Sven Eckelmann   batman-adv: Split...
626
  		atomic_inc(&backbone_gw->bat_priv->bla.num_requests);
23721387c   Simon Wunderlich   batman-adv: add b...
627
628
629
  		atomic_set(&backbone_gw->request_sent, 1);
  	}
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
630
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
631
   * batadv_bla_send_announce() - Send an announcement frame
1b371d130   Simon Wunderlich   batman-adv: use c...
632
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
633
   * @backbone_gw: our backbone gateway which should be announced
23721387c   Simon Wunderlich   batman-adv: add b...
634
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
635
  static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
bae987747   Marek Lindner   batman-adv: renam...
636
  				     struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
637
  {
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
638
  	u8 mac[ETH_ALEN];
3e2f1a1bb   Al Viro   batman-adv: trivi...
639
  	__be16 crc;
23721387c   Simon Wunderlich   batman-adv: add b...
640

3b300de32   Sven Eckelmann   batman-adv: Prefi...
641
  	memcpy(mac, batadv_announce_mac, 4);
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
642
  	spin_lock_bh(&backbone_gw->crc_lock);
23721387c   Simon Wunderlich   batman-adv: add b...
643
  	crc = htons(backbone_gw->crc);
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
644
  	spin_unlock_bh(&backbone_gw->crc_lock);
1a5852d81   Al Viro   batman-adv: get r...
645
  	memcpy(&mac[4], &crc, 2);
23721387c   Simon Wunderlich   batman-adv: add b...
646

3b300de32   Sven Eckelmann   batman-adv: Prefi...
647
  	batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
648
  			      BATADV_CLAIM_TYPE_ANNOUNCE);
23721387c   Simon Wunderlich   batman-adv: add b...
649
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
650
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
651
   * batadv_bla_add_claim() - Adds a claim in the claim hash
2c53040f0   Ben Hutchings   net: Fix (nearly-...
652
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
653
654
655
   * @mac: the mac address of the claim
   * @vid: the VLAN ID of the frame
   * @backbone_gw: the backbone gateway which claims it
23721387c   Simon Wunderlich   batman-adv: add b...
656
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
657
  static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
658
  				 const u8 *mac, const unsigned short vid,
bae987747   Marek Lindner   batman-adv: renam...
659
  				 struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
660
  {
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
661
  	struct batadv_bla_backbone_gw *old_backbone_gw;
712bbfe46   Marek Lindner   batman-adv: renam...
662
663
  	struct batadv_bla_claim *claim;
  	struct batadv_bla_claim search_claim;
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
664
  	bool remove_crc = false;
23721387c   Simon Wunderlich   batman-adv: add b...
665
  	int hash_added;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
666
  	ether_addr_copy(search_claim.addr, mac);
23721387c   Simon Wunderlich   batman-adv: add b...
667
  	search_claim.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
668
  	claim = batadv_claim_hash_find(bat_priv, &search_claim);
23721387c   Simon Wunderlich   batman-adv: add b...
669
670
671
672
673
674
  
  	/* create a new claim entry if it does not exist yet. */
  	if (!claim) {
  		claim = kzalloc(sizeof(*claim), GFP_ATOMIC);
  		if (!claim)
  			return;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
675
  		ether_addr_copy(claim->addr, mac);
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
676
  		spin_lock_init(&claim->backbone_lock);
23721387c   Simon Wunderlich   batman-adv: add b...
677
678
  		claim->vid = vid;
  		claim->lasttime = jiffies;
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
679
  		kref_get(&backbone_gw->refcount);
23721387c   Simon Wunderlich   batman-adv: add b...
680
  		claim->backbone_gw = backbone_gw;
71b7e3d31   Sven Eckelmann   batman-adv: Conve...
681
  		kref_init(&claim->refcount);
7282ac396   Sven Eckelmann   batman-adv: Place...
682

39c75a51e   Sven Eckelmann   batman-adv: Prefi...
683
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
684
685
686
  			   "%s(): adding new entry %pM, vid %d to hash ...
  ",
  			   __func__, mac, batadv_print_vid(vid));
7282ac396   Sven Eckelmann   batman-adv: Place...
687
688
  
  		kref_get(&claim->refcount);
807736f6e   Sven Eckelmann   batman-adv: Split...
689
  		hash_added = batadv_hash_add(bat_priv->bla.claim_hash,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
690
691
692
  					     batadv_compare_claim,
  					     batadv_choose_claim, claim,
  					     &claim->hash_entry);
23721387c   Simon Wunderlich   batman-adv: add b...
693
694
695
696
697
698
699
700
701
702
703
  
  		if (unlikely(hash_added != 0)) {
  			/* only local changes happened. */
  			kfree(claim);
  			return;
  		}
  	} else {
  		claim->lasttime = jiffies;
  		if (claim->backbone_gw == backbone_gw)
  			/* no need to register a new backbone */
  			goto claim_free_ref;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
704
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
705
706
707
708
  			   "%s(): changing ownership for %pM, vid %d to gw %pM
  ",
  			   __func__, mac, batadv_print_vid(vid),
  			   backbone_gw->orig);
23721387c   Simon Wunderlich   batman-adv: add b...
709

3db0decf1   Sven Eckelmann   batman-adv: Fix n...
710
  		remove_crc = true;
23721387c   Simon Wunderlich   batman-adv: add b...
711
  	}
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
712
713
714
715
  
  	/* replace backbone_gw atomically and adjust reference counters */
  	spin_lock_bh(&claim->backbone_lock);
  	old_backbone_gw = claim->backbone_gw;
06e56ded8   Sven Eckelmann   batman-adv: Conve...
716
  	kref_get(&backbone_gw->refcount);
23721387c   Simon Wunderlich   batman-adv: add b...
717
  	claim->backbone_gw = backbone_gw;
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
718
  	spin_unlock_bh(&claim->backbone_lock);
23721387c   Simon Wunderlich   batman-adv: add b...
719

3db0decf1   Sven Eckelmann   batman-adv: Fix n...
720
721
722
723
724
725
  	if (remove_crc) {
  		/* remove claim address from old backbone_gw */
  		spin_lock_bh(&old_backbone_gw->crc_lock);
  		old_backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
  		spin_unlock_bh(&old_backbone_gw->crc_lock);
  	}
23721387c   Simon Wunderlich   batman-adv: add b...
726

3db0decf1   Sven Eckelmann   batman-adv: Fix n...
727
728
729
  	batadv_backbone_gw_put(old_backbone_gw);
  
  	/* add claim address to new backbone_gw */
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
730
  	spin_lock_bh(&backbone_gw->crc_lock);
23721387c   Simon Wunderlich   batman-adv: add b...
731
  	backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
732
  	spin_unlock_bh(&backbone_gw->crc_lock);
23721387c   Simon Wunderlich   batman-adv: add b...
733
734
735
  	backbone_gw->lasttime = jiffies;
  
  claim_free_ref:
321e3e088   Sven Eckelmann   batman-adv: Renam...
736
  	batadv_claim_put(claim);
23721387c   Simon Wunderlich   batman-adv: add b...
737
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
738
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
739
   * batadv_bla_claim_get_backbone_gw() - Get valid reference for backbone_gw of
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
   *  claim
   * @claim: claim whose backbone_gw should be returned
   *
   * Return: valid reference to claim::backbone_gw
   */
  static struct batadv_bla_backbone_gw *
  batadv_bla_claim_get_backbone_gw(struct batadv_bla_claim *claim)
  {
  	struct batadv_bla_backbone_gw *backbone_gw;
  
  	spin_lock_bh(&claim->backbone_lock);
  	backbone_gw = claim->backbone_gw;
  	kref_get(&backbone_gw->refcount);
  	spin_unlock_bh(&claim->backbone_lock);
  
  	return backbone_gw;
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
759
   * batadv_bla_del_claim() - delete a claim from the claim hash
04e14be65   Simon Wunderlich   batman-adv: Updat...
760
761
762
   * @bat_priv: the bat priv with all the soft interface information
   * @mac: mac address of the claim to be removed
   * @vid: VLAN id for the claim to be removed
23721387c   Simon Wunderlich   batman-adv: add b...
763
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
764
  static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
765
  				 const u8 *mac, const unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
766
  {
712bbfe46   Marek Lindner   batman-adv: renam...
767
  	struct batadv_bla_claim search_claim, *claim;
4ba104f46   Sven Eckelmann   batman-adv: Reduc...
768
769
  	struct batadv_bla_claim *claim_removed_entry;
  	struct hlist_node *claim_removed_node;
23721387c   Simon Wunderlich   batman-adv: add b...
770

8fdd01530   Antonio Quartulli   batman-adv: prefe...
771
  	ether_addr_copy(search_claim.addr, mac);
23721387c   Simon Wunderlich   batman-adv: add b...
772
  	search_claim.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
773
  	claim = batadv_claim_hash_find(bat_priv, &search_claim);
23721387c   Simon Wunderlich   batman-adv: add b...
774
775
  	if (!claim)
  		return;
22f0502ed   Sven Eckelmann   batman-adv: Print...
776
777
  	batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): %pM, vid %d
  ", __func__,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
778
  		   mac, batadv_print_vid(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
779

4ba104f46   Sven Eckelmann   batman-adv: Reduc...
780
781
782
783
784
  	claim_removed_node = batadv_hash_remove(bat_priv->bla.claim_hash,
  						batadv_compare_claim,
  						batadv_choose_claim, claim);
  	if (!claim_removed_node)
  		goto free_claim;
23721387c   Simon Wunderlich   batman-adv: add b...
785

4ba104f46   Sven Eckelmann   batman-adv: Reduc...
786
787
788
789
790
791
  	/* reference from the hash is gone */
  	claim_removed_entry = hlist_entry(claim_removed_node,
  					  struct batadv_bla_claim, hash_entry);
  	batadv_claim_put(claim_removed_entry);
  
  free_claim:
23721387c   Simon Wunderlich   batman-adv: add b...
792
  	/* don't need the reference from hash_find() anymore */
321e3e088   Sven Eckelmann   batman-adv: Renam...
793
  	batadv_claim_put(claim);
23721387c   Simon Wunderlich   batman-adv: add b...
794
  }
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
795
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
796
   * batadv_handle_announce() - check for ANNOUNCE frame
04e14be65   Simon Wunderlich   batman-adv: Updat...
797
798
799
800
   * @bat_priv: the bat priv with all the soft interface information
   * @an_addr: announcement mac address (ARP Sender HW address)
   * @backbone_addr: originator address of the sender (Ethernet source MAC)
   * @vid: the VLAN ID of the frame
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
801
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
802
   * Return: true if handled
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
803
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
804
805
  static bool batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr,
  				   u8 *backbone_addr, unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
806
  {
bae987747   Marek Lindner   batman-adv: renam...
807
  	struct batadv_bla_backbone_gw *backbone_gw;
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
808
  	u16 backbone_crc, crc;
23721387c   Simon Wunderlich   batman-adv: add b...
809

3b300de32   Sven Eckelmann   batman-adv: Prefi...
810
  	if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
4b426b108   Sven Eckelmann   batman-adv: Use b...
811
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
812

52aebd6a9   Simon Wunderlich   batman-adv: send ...
813
814
  	backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
  						 false);
23721387c   Simon Wunderlich   batman-adv: add b...
815
816
  
  	if (unlikely(!backbone_gw))
4b426b108   Sven Eckelmann   batman-adv: Use b...
817
  		return true;
23721387c   Simon Wunderlich   batman-adv: add b...
818

23721387c   Simon Wunderlich   batman-adv: add b...
819
820
  	/* handle as ANNOUNCE frame */
  	backbone_gw->lasttime = jiffies;
61a292860   Sven Eckelmann   batman-adv: Annot...
821
  	crc = ntohs(*((__force __be16 *)(&an_addr[4])));
23721387c   Simon Wunderlich   batman-adv: add b...
822

39c75a51e   Sven Eckelmann   batman-adv: Prefi...
823
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
824
825
826
  		   "%s(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x
  ",
  		   __func__, batadv_print_vid(vid), backbone_gw->orig, crc);
23721387c   Simon Wunderlich   batman-adv: add b...
827

5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
828
829
830
831
832
  	spin_lock_bh(&backbone_gw->crc_lock);
  	backbone_crc = backbone_gw->crc;
  	spin_unlock_bh(&backbone_gw->crc_lock);
  
  	if (backbone_crc != crc) {
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
833
  		batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
834
835
836
  			   "%s(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)
  ",
  			   __func__, backbone_gw->orig,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
837
  			   batadv_print_vid(backbone_gw->vid),
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
838
  			   backbone_crc, crc);
23721387c   Simon Wunderlich   batman-adv: add b...
839

3b300de32   Sven Eckelmann   batman-adv: Prefi...
840
  		batadv_bla_send_request(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
841
842
843
844
845
  	} else {
  		/* if we have sent a request and the crc was OK,
  		 * we can allow traffic again.
  		 */
  		if (atomic_read(&backbone_gw->request_sent)) {
807736f6e   Sven Eckelmann   batman-adv: Split...
846
  			atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
23721387c   Simon Wunderlich   batman-adv: add b...
847
848
849
  			atomic_set(&backbone_gw->request_sent, 0);
  		}
  	}
c8b86c124   Sven Eckelmann   batman-adv: Renam...
850
  	batadv_backbone_gw_put(backbone_gw);
4b426b108   Sven Eckelmann   batman-adv: Use b...
851
  	return true;
23721387c   Simon Wunderlich   batman-adv: add b...
852
  }
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
853
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
854
   * batadv_handle_request() - check for REQUEST frame
04e14be65   Simon Wunderlich   batman-adv: Updat...
855
856
857
858
859
   * @bat_priv: the bat priv with all the soft interface information
   * @primary_if: the primary hard interface of this batman soft interface
   * @backbone_addr: backbone address to be requested (ARP sender HW MAC)
   * @ethhdr: ethernet header of a packet
   * @vid: the VLAN ID of the frame
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
860
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
861
   * Return: true if handled
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
862
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
863
864
865
866
  static bool batadv_handle_request(struct batadv_priv *bat_priv,
  				  struct batadv_hard_iface *primary_if,
  				  u8 *backbone_addr, struct ethhdr *ethhdr,
  				  unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
867
868
  {
  	/* check for REQUEST frame */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
869
  	if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest))
4b426b108   Sven Eckelmann   batman-adv: Use b...
870
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
871
872
873
874
  
  	/* sanity check, this should not happen on a normal switch,
  	 * we ignore it in this case.
  	 */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
875
  	if (!batadv_compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr))
4b426b108   Sven Eckelmann   batman-adv: Use b...
876
  		return true;
23721387c   Simon Wunderlich   batman-adv: add b...
877

39c75a51e   Sven Eckelmann   batman-adv: Prefi...
878
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
879
880
881
  		   "%s(): REQUEST vid %d (sent by %pM)...
  ",
  		   __func__, batadv_print_vid(vid), ethhdr->h_source);
23721387c   Simon Wunderlich   batman-adv: add b...
882

3b300de32   Sven Eckelmann   batman-adv: Prefi...
883
  	batadv_bla_answer_request(bat_priv, primary_if, vid);
4b426b108   Sven Eckelmann   batman-adv: Use b...
884
  	return true;
23721387c   Simon Wunderlich   batman-adv: add b...
885
  }
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
886
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
887
   * batadv_handle_unclaim() - check for UNCLAIM frame
04e14be65   Simon Wunderlich   batman-adv: Updat...
888
889
890
891
892
   * @bat_priv: the bat priv with all the soft interface information
   * @primary_if: the primary hard interface of this batman soft interface
   * @backbone_addr: originator address of the backbone (Ethernet source)
   * @claim_addr: Client to be unclaimed (ARP sender HW MAC)
   * @vid: the VLAN ID of the frame
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
893
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
894
   * Return: true if handled
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
895
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
896
897
898
899
  static bool batadv_handle_unclaim(struct batadv_priv *bat_priv,
  				  struct batadv_hard_iface *primary_if,
  				  u8 *backbone_addr, u8 *claim_addr,
  				  unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
900
  {
bae987747   Marek Lindner   batman-adv: renam...
901
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
902
903
  
  	/* unclaim in any case if it is our own */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
904
905
  	if (primary_if && batadv_compare_eth(backbone_addr,
  					     primary_if->net_dev->dev_addr))
3b300de32   Sven Eckelmann   batman-adv: Prefi...
906
  		batadv_bla_send_claim(bat_priv, claim_addr, vid,
3eb8773e3   Simon Wunderlich   batman-adv: renam...
907
  				      BATADV_CLAIM_TYPE_UNCLAIM);
23721387c   Simon Wunderlich   batman-adv: add b...
908

3b300de32   Sven Eckelmann   batman-adv: Prefi...
909
  	backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
910
911
  
  	if (!backbone_gw)
4b426b108   Sven Eckelmann   batman-adv: Use b...
912
  		return true;
23721387c   Simon Wunderlich   batman-adv: add b...
913
914
  
  	/* this must be an UNCLAIM frame */
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
915
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
916
917
  		   "%s(): UNCLAIM %pM on vid %d (sent by %pM)...
  ", __func__,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
918
  		   claim_addr, batadv_print_vid(vid), backbone_gw->orig);
23721387c   Simon Wunderlich   batman-adv: add b...
919

3b300de32   Sven Eckelmann   batman-adv: Prefi...
920
  	batadv_bla_del_claim(bat_priv, claim_addr, vid);
c8b86c124   Sven Eckelmann   batman-adv: Renam...
921
  	batadv_backbone_gw_put(backbone_gw);
4b426b108   Sven Eckelmann   batman-adv: Use b...
922
  	return true;
23721387c   Simon Wunderlich   batman-adv: add b...
923
  }
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
924
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
925
   * batadv_handle_claim() - check for CLAIM frame
04e14be65   Simon Wunderlich   batman-adv: Updat...
926
927
928
929
930
   * @bat_priv: the bat priv with all the soft interface information
   * @primary_if: the primary hard interface of this batman soft interface
   * @backbone_addr: originator address of the backbone (Ethernet Source)
   * @claim_addr: client mac address to be claimed (ARP sender HW MAC)
   * @vid: the VLAN ID of the frame
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
931
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
932
   * Return: true if handled
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
933
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
934
935
936
937
  static bool batadv_handle_claim(struct batadv_priv *bat_priv,
  				struct batadv_hard_iface *primary_if,
  				u8 *backbone_addr, u8 *claim_addr,
  				unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
938
  {
bae987747   Marek Lindner   batman-adv: renam...
939
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
940
941
  
  	/* register the gateway if not yet available, and add the claim. */
52aebd6a9   Simon Wunderlich   batman-adv: send ...
942
943
  	backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
  						 false);
23721387c   Simon Wunderlich   batman-adv: add b...
944
945
  
  	if (unlikely(!backbone_gw))
4b426b108   Sven Eckelmann   batman-adv: Use b...
946
  		return true;
23721387c   Simon Wunderlich   batman-adv: add b...
947
948
  
  	/* this must be a CLAIM frame */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
949
  	batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw);
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
950
  	if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
3b300de32   Sven Eckelmann   batman-adv: Prefi...
951
  		batadv_bla_send_claim(bat_priv, claim_addr, vid,
3eb8773e3   Simon Wunderlich   batman-adv: renam...
952
  				      BATADV_CLAIM_TYPE_CLAIM);
23721387c   Simon Wunderlich   batman-adv: add b...
953
954
  
  	/* TODO: we could call something like tt_local_del() here. */
c8b86c124   Sven Eckelmann   batman-adv: Renam...
955
  	batadv_backbone_gw_put(backbone_gw);
4b426b108   Sven Eckelmann   batman-adv: Use b...
956
  	return true;
23721387c   Simon Wunderlich   batman-adv: add b...
957
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
958
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
959
   * batadv_check_claim_group() - check for claim group membership
2c53040f0   Ben Hutchings   net: Fix (nearly-...
960
   * @bat_priv: the bat priv with all the soft interface information
e33571898   Martin Hundebøll   batman-adv: kerne...
961
   * @primary_if: the primary interface of this batman interface
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
962
963
964
965
   * @hw_src: the Hardware source in the ARP Header
   * @hw_dst: the Hardware destination in the ARP Header
   * @ethhdr: pointer to the Ethernet header of the claim frame
   *
bccb48c89   Sven Eckelmann   batman-adv: Fix t...
966
   * checks if it is a claim packet and if it's on the same group.
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
967
968
969
   * This function also applies the group ID of the sender
   * if it is in the same mesh.
   *
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
970
   * Return:
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
971
972
973
974
   *	2  - if it is a claim packet and on the same group
   *	1  - if is a claim packet from another group
   *	0  - if it is not a claim packet
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
975
976
  static int batadv_check_claim_group(struct batadv_priv *bat_priv,
  				    struct batadv_hard_iface *primary_if,
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
977
  				    u8 *hw_src, u8 *hw_dst,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
978
  				    struct ethhdr *ethhdr)
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
979
  {
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
980
  	u8 *backbone_addr;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
981
  	struct batadv_orig_node *orig_node;
964126901   Sven Eckelmann   batman-adv: Prefi...
982
  	struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
983

964126901   Sven Eckelmann   batman-adv: Prefi...
984
  	bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
807736f6e   Sven Eckelmann   batman-adv: Split...
985
  	bla_dst_own = &bat_priv->bla.claim_dest;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
986

38ef3d1d9   Simon Wunderlich   batman-adv: form ...
987
988
989
990
  	/* if announcement packet, use the source,
  	 * otherwise assume it is in the hw_src
  	 */
  	switch (bla_dst->type) {
3eb8773e3   Simon Wunderlich   batman-adv: renam...
991
  	case BATADV_CLAIM_TYPE_CLAIM:
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
992
993
  		backbone_addr = hw_src;
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
994
995
  	case BATADV_CLAIM_TYPE_REQUEST:
  	case BATADV_CLAIM_TYPE_ANNOUNCE:
3eb8773e3   Simon Wunderlich   batman-adv: renam...
996
  	case BATADV_CLAIM_TYPE_UNCLAIM:
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
997
998
999
1000
1001
1002
1003
  		backbone_addr = ethhdr->h_source;
  		break;
  	default:
  		return 0;
  	}
  
  	/* don't accept claim frames from ourselves */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1004
  	if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1005
1006
1007
1008
1009
1010
1011
  		return 0;
  
  	/* if its already the same group, it is fine. */
  	if (bla_dst->group == bla_dst_own->group)
  		return 2;
  
  	/* lets see if this originator is in our mesh */
da641193d   Sven Eckelmann   batman-adv: Prefi...
1012
  	orig_node = batadv_orig_hash_find(bat_priv, backbone_addr);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1013
1014
1015
1016
1017
1018
1019
1020
1021
  
  	/* dont accept claims from gateways which are not in
  	 * the same mesh or group.
  	 */
  	if (!orig_node)
  		return 1;
  
  	/* if our mesh friends mac is bigger, use it for ourselves. */
  	if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) {
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
1022
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
39a329915   Antonio Quartulli   batman-adv: unify...
1023
1024
  			   "taking other backbones claim group: %#.4x
  ",
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1025
  			   ntohs(bla_dst->group));
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1026
1027
  		bla_dst_own->group = bla_dst->group;
  	}
5d9673109   Sven Eckelmann   batman-adv: Renam...
1028
  	batadv_orig_node_put(orig_node);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1029
1030
1031
  
  	return 2;
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
1032
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1033
   * batadv_bla_process_claim() - Check if this is a claim frame, and process it
1b371d130   Simon Wunderlich   batman-adv: use c...
1034
   * @bat_priv: the bat priv with all the soft interface information
e33571898   Martin Hundebøll   batman-adv: kerne...
1035
   * @primary_if: the primary hard interface of this batman soft interface
23721387c   Simon Wunderlich   batman-adv: add b...
1036
1037
   * @skb: the frame to be checked
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
1038
   * Return: true if it was a claim frame, otherwise return false to
23721387c   Simon Wunderlich   batman-adv: add b...
1039
1040
   * tell the callee that it can use the frame on its own.
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
1041
1042
1043
  static bool batadv_bla_process_claim(struct batadv_priv *bat_priv,
  				     struct batadv_hard_iface *primary_if,
  				     struct sk_buff *skb)
23721387c   Simon Wunderlich   batman-adv: add b...
1044
  {
d46b6bfa7   Simon Wunderlich   batman-adv: drop ...
1045
  	struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
1046
  	u8 *hw_src, *hw_dst;
d46b6bfa7   Simon Wunderlich   batman-adv: drop ...
1047
  	struct vlan_hdr *vhdr, vhdr_buf;
c018ad3de   Antonio Quartulli   batman-adv: add t...
1048
  	struct ethhdr *ethhdr;
23721387c   Simon Wunderlich   batman-adv: add b...
1049
  	struct arphdr *arphdr;
c018ad3de   Antonio Quartulli   batman-adv: add t...
1050
  	unsigned short vid;
d46b6bfa7   Simon Wunderlich   batman-adv: drop ...
1051
  	int vlan_depth = 0;
293e93385   Antonio Quartulli   batman-adv: use h...
1052
  	__be16 proto;
23721387c   Simon Wunderlich   batman-adv: add b...
1053
  	int headlen;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1054
  	int ret;
23721387c   Simon Wunderlich   batman-adv: add b...
1055

c018ad3de   Antonio Quartulli   batman-adv: add t...
1056
  	vid = batadv_get_vid(skb, 0);
7ed4be952   Antonio Quartulli   batman-adv: use e...
1057
  	ethhdr = eth_hdr(skb);
23721387c   Simon Wunderlich   batman-adv: add b...
1058

c018ad3de   Antonio Quartulli   batman-adv: add t...
1059
1060
1061
  	proto = ethhdr->h_proto;
  	headlen = ETH_HLEN;
  	if (vid & BATADV_VLAN_HAS_TAG) {
d46b6bfa7   Simon Wunderlich   batman-adv: drop ...
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
  		/* Traverse the VLAN/Ethertypes.
  		 *
  		 * At this point it is known that the first protocol is a VLAN
  		 * header, so start checking at the encapsulated protocol.
  		 *
  		 * The depth of the VLAN headers is recorded to drop BLA claim
  		 * frames encapsulated into multiple VLAN headers (QinQ).
  		 */
  		do {
  			vhdr = skb_header_pointer(skb, headlen, VLAN_HLEN,
  						  &vhdr_buf);
  			if (!vhdr)
4b426b108   Sven Eckelmann   batman-adv: Use b...
1074
  				return false;
d46b6bfa7   Simon Wunderlich   batman-adv: drop ...
1075
1076
1077
1078
1079
  
  			proto = vhdr->h_vlan_encapsulated_proto;
  			headlen += VLAN_HLEN;
  			vlan_depth++;
  		} while (proto == htons(ETH_P_8021Q));
23721387c   Simon Wunderlich   batman-adv: add b...
1080
  	}
293e93385   Antonio Quartulli   batman-adv: use h...
1081
  	if (proto != htons(ETH_P_ARP))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1082
  		return false; /* not a claim frame */
23721387c   Simon Wunderlich   batman-adv: add b...
1083
1084
1085
1086
  
  	/* this must be a ARP frame. check if it is a claim. */
  
  	if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev))))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1087
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
1088
1089
  
  	/* pskb_may_pull() may have modified the pointers, get ethhdr again */
7ed4be952   Antonio Quartulli   batman-adv: use e...
1090
  	ethhdr = eth_hdr(skb);
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
1091
  	arphdr = (struct arphdr *)((u8 *)ethhdr + headlen);
23721387c   Simon Wunderlich   batman-adv: add b...
1092
1093
1094
1095
  
  	/* Check whether the ARP frame carries a valid
  	 * IP information
  	 */
23721387c   Simon Wunderlich   batman-adv: add b...
1096
  	if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1097
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
1098
  	if (arphdr->ar_pro != htons(ETH_P_IP))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1099
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
1100
  	if (arphdr->ar_hln != ETH_ALEN)
4b426b108   Sven Eckelmann   batman-adv: Use b...
1101
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
1102
  	if (arphdr->ar_pln != 4)
4b426b108   Sven Eckelmann   batman-adv: Use b...
1103
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
1104

6b5e971a2   Sven Eckelmann   batman-adv: Repla...
1105
  	hw_src = (u8 *)arphdr + sizeof(struct arphdr);
23721387c   Simon Wunderlich   batman-adv: add b...
1106
  	hw_dst = hw_src + ETH_ALEN + 4;
964126901   Sven Eckelmann   batman-adv: Prefi...
1107
  	bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
d46b6bfa7   Simon Wunderlich   batman-adv: drop ...
1108
1109
1110
1111
1112
  	bla_dst_own = &bat_priv->bla.claim_dest;
  
  	/* check if it is a claim frame in general */
  	if (memcmp(bla_dst->magic, bla_dst_own->magic,
  		   sizeof(bla_dst->magic)) != 0)
4b426b108   Sven Eckelmann   batman-adv: Use b...
1113
  		return false;
d46b6bfa7   Simon Wunderlich   batman-adv: drop ...
1114
1115
1116
1117
1118
1119
  
  	/* check if there is a claim frame encapsulated deeper in (QinQ) and
  	 * drop that, as this is not supported by BLA but should also not be
  	 * sent via the mesh.
  	 */
  	if (vlan_depth > 1)
4b426b108   Sven Eckelmann   batman-adv: Use b...
1120
  		return true;
23721387c   Simon Wunderlich   batman-adv: add b...
1121

cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1122
1123
  	/* Let the loopdetect frames on the mesh in any case. */
  	if (bla_dst->type == BATADV_CLAIM_TYPE_LOOPDETECT)
4fd261bf5   kbuild test robot   batman-adv: fix b...
1124
  		return false;
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1125

23721387c   Simon Wunderlich   batman-adv: add b...
1126
  	/* check if it is a claim frame. */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1127
1128
  	ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst,
  				       ethhdr);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1129
  	if (ret == 1)
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
1130
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
1131
1132
1133
1134
  			   "%s(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)
  ",
  			   __func__, ethhdr->h_source, batadv_print_vid(vid),
  			   hw_src, hw_dst);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1135
1136
  
  	if (ret < 2)
4b426b108   Sven Eckelmann   batman-adv: Use b...
1137
  		return !!ret;
23721387c   Simon Wunderlich   batman-adv: add b...
1138
1139
  
  	/* become a backbone gw ourselves on this vlan if not happened yet */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1140
  	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1141
1142
1143
  
  	/* check for the different types of claim frames ... */
  	switch (bla_dst->type) {
3eb8773e3   Simon Wunderlich   batman-adv: renam...
1144
  	case BATADV_CLAIM_TYPE_CLAIM:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1145
1146
  		if (batadv_handle_claim(bat_priv, primary_if, hw_src,
  					ethhdr->h_source, vid))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1147
  			return true;
23721387c   Simon Wunderlich   batman-adv: add b...
1148
  		break;
3eb8773e3   Simon Wunderlich   batman-adv: renam...
1149
  	case BATADV_CLAIM_TYPE_UNCLAIM:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1150
1151
  		if (batadv_handle_unclaim(bat_priv, primary_if,
  					  ethhdr->h_source, hw_src, vid))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1152
  			return true;
23721387c   Simon Wunderlich   batman-adv: add b...
1153
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
1154
  	case BATADV_CLAIM_TYPE_ANNOUNCE:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1155
1156
  		if (batadv_handle_announce(bat_priv, hw_src, ethhdr->h_source,
  					   vid))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1157
  			return true;
23721387c   Simon Wunderlich   batman-adv: add b...
1158
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
1159
  	case BATADV_CLAIM_TYPE_REQUEST:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1160
1161
  		if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr,
  					  vid))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1162
  			return true;
23721387c   Simon Wunderlich   batman-adv: add b...
1163
1164
  		break;
  	}
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
1165
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
1166
1167
1168
1169
  		   "%s(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)
  ",
  		   __func__, ethhdr->h_source, batadv_print_vid(vid), hw_src,
  		   hw_dst);
4b426b108   Sven Eckelmann   batman-adv: Use b...
1170
  	return true;
23721387c   Simon Wunderlich   batman-adv: add b...
1171
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
1172
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1173
   * batadv_bla_purge_backbone_gw() - Remove backbone gateways after a timeout or
04e14be65   Simon Wunderlich   batman-adv: Updat...
1174
1175
1176
1177
1178
   *  immediately
   * @bat_priv: the bat priv with all the soft interface information
   * @now: whether the whole hash shall be wiped now
   *
   * Check when we last heard from other nodes, and remove them in case of
23721387c   Simon Wunderlich   batman-adv: add b...
1179
1180
   * a time out, or clean all backbone gws if now is set.
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1181
  static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
23721387c   Simon Wunderlich   batman-adv: add b...
1182
  {
bae987747   Marek Lindner   batman-adv: renam...
1183
  	struct batadv_bla_backbone_gw *backbone_gw;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1184
  	struct hlist_node *node_tmp;
23721387c   Simon Wunderlich   batman-adv: add b...
1185
  	struct hlist_head *head;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
1186
  	struct batadv_hashtable *hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1187
1188
  	spinlock_t *list_lock;	/* protects write access to the hash lists */
  	int i;
807736f6e   Sven Eckelmann   batman-adv: Split...
1189
  	hash = bat_priv->bla.backbone_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1190
1191
1192
1193
1194
1195
1196
1197
  	if (!hash)
  		return;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  		list_lock = &hash->list_locks[i];
  
  		spin_lock_bh(list_lock);
b67bfe0d4   Sasha Levin   hlist: drop the n...
1198
  		hlist_for_each_entry_safe(backbone_gw, node_tmp,
23721387c   Simon Wunderlich   batman-adv: add b...
1199
1200
1201
  					  head, hash_entry) {
  			if (now)
  				goto purge_now;
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1202
  			if (!batadv_has_timed_out(backbone_gw->lasttime,
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1203
  						  BATADV_BLA_BACKBONE_TIMEOUT))
23721387c   Simon Wunderlich   batman-adv: add b...
1204
  				continue;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
1205
  			batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
1206
1207
1208
  				   "%s(): backbone gw %pM timed out
  ",
  				   __func__, backbone_gw->orig);
23721387c   Simon Wunderlich   batman-adv: add b...
1209
1210
1211
1212
  
  purge_now:
  			/* don't wait for the pending request anymore */
  			if (atomic_read(&backbone_gw->request_sent))
807736f6e   Sven Eckelmann   batman-adv: Split...
1213
  				atomic_dec(&bat_priv->bla.num_requests);
23721387c   Simon Wunderlich   batman-adv: add b...
1214

3b300de32   Sven Eckelmann   batman-adv: Prefi...
1215
  			batadv_bla_del_backbone_claims(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
1216

b67bfe0d4   Sasha Levin   hlist: drop the n...
1217
  			hlist_del_rcu(&backbone_gw->hash_entry);
c8b86c124   Sven Eckelmann   batman-adv: Renam...
1218
  			batadv_backbone_gw_put(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
1219
1220
1221
1222
  		}
  		spin_unlock_bh(list_lock);
  	}
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1223
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1224
   * batadv_bla_purge_claims() - Remove claims after a timeout or immediately
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1225
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
1226
1227
1228
1229
1230
1231
   * @primary_if: the selected primary interface, may be NULL if now is set
   * @now: whether the whole hash shall be wiped now
   *
   * Check when we heard last time from our own claims, and remove them in case of
   * a time out, or clean all claims if now is set
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1232
1233
1234
  static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
  				    struct batadv_hard_iface *primary_if,
  				    int now)
23721387c   Simon Wunderlich   batman-adv: add b...
1235
  {
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1236
  	struct batadv_bla_backbone_gw *backbone_gw;
712bbfe46   Marek Lindner   batman-adv: renam...
1237
  	struct batadv_bla_claim *claim;
23721387c   Simon Wunderlich   batman-adv: add b...
1238
  	struct hlist_head *head;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
1239
  	struct batadv_hashtable *hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1240
  	int i;
807736f6e   Sven Eckelmann   batman-adv: Split...
1241
  	hash = bat_priv->bla.claim_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1242
1243
1244
1245
1246
1247
1248
  	if (!hash)
  		return;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
1249
  		hlist_for_each_entry_rcu(claim, head, hash_entry) {
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1250
  			backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
23721387c   Simon Wunderlich   batman-adv: add b...
1251
1252
  			if (now)
  				goto purge_now;
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1253
1254
  
  			if (!batadv_compare_eth(backbone_gw->orig,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1255
  						primary_if->net_dev->dev_addr))
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1256
  				goto skip;
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1257
  			if (!batadv_has_timed_out(claim->lasttime,
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1258
  						  BATADV_BLA_CLAIM_TIMEOUT))
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1259
  				goto skip;
23721387c   Simon Wunderlich   batman-adv: add b...
1260

39c75a51e   Sven Eckelmann   batman-adv: Prefi...
1261
  			batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
1262
1263
  				   "%s(): timed out.
  ", __func__);
23721387c   Simon Wunderlich   batman-adv: add b...
1264
1265
  
  purge_now:
4dd72f736   Andreas Pape   batman-adv: chang...
1266
  			batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
1267
1268
  				   "%s(): %pM, vid %d
  ", __func__,
4dd72f736   Andreas Pape   batman-adv: chang...
1269
  				   claim->addr, claim->vid);
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1270
  			batadv_handle_unclaim(bat_priv, primary_if,
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1271
  					      backbone_gw->orig,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1272
  					      claim->addr, claim->vid);
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1273
1274
  skip:
  			batadv_backbone_gw_put(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
1275
1276
1277
1278
  		}
  		rcu_read_unlock();
  	}
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1279
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1280
   * batadv_bla_update_orig_address() - Update the backbone gateways when the own
04e14be65   Simon Wunderlich   batman-adv: Updat...
1281
   *  originator address changes
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1282
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
1283
1284
   * @primary_if: the new selected primary_if
   * @oldif: the old primary interface, may be NULL
23721387c   Simon Wunderlich   batman-adv: add b...
1285
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1286
1287
1288
  void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
  				    struct batadv_hard_iface *primary_if,
  				    struct batadv_hard_iface *oldif)
23721387c   Simon Wunderlich   batman-adv: add b...
1289
  {
bae987747   Marek Lindner   batman-adv: renam...
1290
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
1291
  	struct hlist_head *head;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
1292
  	struct batadv_hashtable *hash;
807736f6e   Sven Eckelmann   batman-adv: Split...
1293
  	__be16 group;
23721387c   Simon Wunderlich   batman-adv: add b...
1294
  	int i;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1295
  	/* reset bridge loop avoidance group id */
807736f6e   Sven Eckelmann   batman-adv: Split...
1296
1297
  	group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN));
  	bat_priv->bla.claim_dest.group = group;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1298

d5b4c93e6   Simon Wunderlich   batman-adv: Don't...
1299
1300
1301
  	/* purge everything when bridge loop avoidance is turned off */
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
  		oldif = NULL;
23721387c   Simon Wunderlich   batman-adv: add b...
1302
  	if (!oldif) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1303
1304
  		batadv_bla_purge_claims(bat_priv, NULL, 1);
  		batadv_bla_purge_backbone_gw(bat_priv, 1);
23721387c   Simon Wunderlich   batman-adv: add b...
1305
1306
  		return;
  	}
807736f6e   Sven Eckelmann   batman-adv: Split...
1307
  	hash = bat_priv->bla.backbone_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1308
1309
1310
1311
1312
1313
1314
  	if (!hash)
  		return;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
1315
  		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
23721387c   Simon Wunderlich   batman-adv: add b...
1316
  			/* own orig still holds the old value. */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1317
1318
  			if (!batadv_compare_eth(backbone_gw->orig,
  						oldif->net_dev->dev_addr))
23721387c   Simon Wunderlich   batman-adv: add b...
1319
  				continue;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
1320
1321
  			ether_addr_copy(backbone_gw->orig,
  					primary_if->net_dev->dev_addr);
23721387c   Simon Wunderlich   batman-adv: add b...
1322
1323
1324
  			/* send an announce frame so others will ask for our
  			 * claims and update their tables.
  			 */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1325
  			batadv_bla_send_announce(bat_priv, backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
1326
1327
1328
1329
  		}
  		rcu_read_unlock();
  	}
  }
d68081a24   Simon Wunderlich   batman-adv: purge...
1330
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1331
   * batadv_bla_send_loopdetect() - send a loopdetect frame
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
   * @bat_priv: the bat priv with all the soft interface information
   * @backbone_gw: the backbone gateway for which a loop should be detected
   *
   * To detect loops that the bridge loop avoidance can't handle, send a loop
   * detection packet on the backbone. Unlike other BLA frames, this frame will
   * be allowed on the mesh by other nodes. If it is received on the mesh, this
   * indicates that there is a loop.
   */
  static void
  batadv_bla_send_loopdetect(struct batadv_priv *bat_priv,
  			   struct batadv_bla_backbone_gw *backbone_gw)
  {
  	batadv_dbg(BATADV_DBG_BLA, bat_priv, "Send loopdetect frame for vid %d
  ",
  		   backbone_gw->vid);
  	batadv_bla_send_claim(bat_priv, bat_priv->bla.loopdetect_addr,
  			      backbone_gw->vid, BATADV_CLAIM_TYPE_LOOPDETECT);
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1352
   * batadv_bla_status_update() - purge bla interfaces if necessary
d68081a24   Simon Wunderlich   batman-adv: purge...
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
   * @net_dev: the soft interface net device
   */
  void batadv_bla_status_update(struct net_device *net_dev)
  {
  	struct batadv_priv *bat_priv = netdev_priv(net_dev);
  	struct batadv_hard_iface *primary_if;
  
  	primary_if = batadv_primary_if_get_selected(bat_priv);
  	if (!primary_if)
  		return;
  
  	/* this function already purges everything when bla is disabled,
  	 * so just call that one.
  	 */
  	batadv_bla_update_orig_address(bat_priv, primary_if, primary_if);
82047ad7f   Sven Eckelmann   batman-adv: Renam...
1368
  	batadv_hardif_put(primary_if);
d68081a24   Simon Wunderlich   batman-adv: purge...
1369
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
1370
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1371
   * batadv_bla_periodic_work() - performs periodic bla work
04e14be65   Simon Wunderlich   batman-adv: Updat...
1372
1373
1374
   * @work: kernel work struct
   *
   * periodic work to do:
23721387c   Simon Wunderlich   batman-adv: add b...
1375
1376
1377
   *  * purge structures when they are too old
   *  * send announcements
   */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1378
  static void batadv_bla_periodic_work(struct work_struct *work)
23721387c   Simon Wunderlich   batman-adv: add b...
1379
  {
bbb1f90ef   Sven Eckelmann   batman-adv: Don't...
1380
  	struct delayed_work *delayed_work;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1381
  	struct batadv_priv *bat_priv;
807736f6e   Sven Eckelmann   batman-adv: Split...
1382
  	struct batadv_priv_bla *priv_bla;
23721387c   Simon Wunderlich   batman-adv: add b...
1383
  	struct hlist_head *head;
bae987747   Marek Lindner   batman-adv: renam...
1384
  	struct batadv_bla_backbone_gw *backbone_gw;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
1385
  	struct batadv_hashtable *hash;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1386
  	struct batadv_hard_iface *primary_if;
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1387
  	bool send_loopdetect = false;
23721387c   Simon Wunderlich   batman-adv: add b...
1388
  	int i;
4ba4bc0f7   Geliang Tang   batman-adv: use t...
1389
  	delayed_work = to_delayed_work(work);
807736f6e   Sven Eckelmann   batman-adv: Split...
1390
1391
  	priv_bla = container_of(delayed_work, struct batadv_priv_bla, work);
  	bat_priv = container_of(priv_bla, struct batadv_priv, bla);
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1392
  	primary_if = batadv_primary_if_get_selected(bat_priv);
23721387c   Simon Wunderlich   batman-adv: add b...
1393
1394
  	if (!primary_if)
  		goto out;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1395
1396
  	batadv_bla_purge_claims(bat_priv, primary_if, 0);
  	batadv_bla_purge_backbone_gw(bat_priv, 0);
23721387c   Simon Wunderlich   batman-adv: add b...
1397
1398
1399
  
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
  		goto out;
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1400
1401
1402
1403
1404
  	if (atomic_dec_and_test(&bat_priv->bla.loopdetect_next)) {
  		/* set a new random mac address for the next bridge loop
  		 * detection frames. Set the locally administered bit to avoid
  		 * collisions with users mac addresses.
  		 */
6c1f0a1ff   Joe Perches   net: drivers/net:...
1405
  		eth_random_addr(bat_priv->bla.loopdetect_addr);
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1406
1407
1408
1409
1410
1411
1412
1413
1414
  		bat_priv->bla.loopdetect_addr[0] = 0xba;
  		bat_priv->bla.loopdetect_addr[1] = 0xbe;
  		bat_priv->bla.loopdetect_lasttime = jiffies;
  		atomic_set(&bat_priv->bla.loopdetect_next,
  			   BATADV_BLA_LOOPDETECT_PERIODS);
  
  		/* mark for sending loop detect on all VLANs */
  		send_loopdetect = true;
  	}
807736f6e   Sven Eckelmann   batman-adv: Split...
1415
  	hash = bat_priv->bla.backbone_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1416
1417
1418
1419
1420
1421
1422
  	if (!hash)
  		goto out;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
1423
  		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1424
1425
  			if (!batadv_compare_eth(backbone_gw->orig,
  						primary_if->net_dev->dev_addr))
23721387c   Simon Wunderlich   batman-adv: add b...
1426
1427
1428
  				continue;
  
  			backbone_gw->lasttime = jiffies;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1429
  			batadv_bla_send_announce(bat_priv, backbone_gw);
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1430
1431
1432
  			if (send_loopdetect)
  				batadv_bla_send_loopdetect(bat_priv,
  							   backbone_gw);
d807f2728   Simon Wunderlich   batman-adv: allow...
1433
1434
1435
1436
1437
  
  			/* request_sent is only set after creation to avoid
  			 * problems when we are not yet known as backbone gw
  			 * in the backbone.
  			 *
28709878b   Simon Wunderlich   batman-adv: wait ...
1438
1439
1440
  			 * We can reset this now after we waited some periods
  			 * to give bridge forward delays and bla group forming
  			 * some grace time.
d807f2728   Simon Wunderlich   batman-adv: allow...
1441
1442
1443
1444
  			 */
  
  			if (atomic_read(&backbone_gw->request_sent) == 0)
  				continue;
28709878b   Simon Wunderlich   batman-adv: wait ...
1445
1446
  			if (!atomic_dec_and_test(&backbone_gw->wait_periods))
  				continue;
d807f2728   Simon Wunderlich   batman-adv: allow...
1447
1448
  			atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
  			atomic_set(&backbone_gw->request_sent, 0);
23721387c   Simon Wunderlich   batman-adv: add b...
1449
1450
1451
1452
1453
  		}
  		rcu_read_unlock();
  	}
  out:
  	if (primary_if)
82047ad7f   Sven Eckelmann   batman-adv: Renam...
1454
  		batadv_hardif_put(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
1455

724144420   Antonio Quartulli   batman-adv: a del...
1456
1457
  	queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work,
  			   msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH));
23721387c   Simon Wunderlich   batman-adv: add b...
1458
  }
5d52dad27   Sven Eckelmann   batman-adv: Initi...
1459
1460
1461
1462
1463
  /* The hash for claim and backbone hash receive the same key because they
   * are getting initialized by hash_new with the same key. Reinitializing
   * them with to different keys to allow nested locking without generating
   * lockdep warnings
   */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1464
1465
  static struct lock_class_key batadv_claim_hash_lock_class_key;
  static struct lock_class_key batadv_backbone_hash_lock_class_key;
5d52dad27   Sven Eckelmann   batman-adv: Initi...
1466

04e14be65   Simon Wunderlich   batman-adv: Updat...
1467
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1468
   * batadv_bla_init() - initialize all bla structures
04e14be65   Simon Wunderlich   batman-adv: Updat...
1469
1470
1471
1472
   * @bat_priv: the bat priv with all the soft interface information
   *
   * Return: 0 on success, < 0 on error.
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1473
  int batadv_bla_init(struct batadv_priv *bat_priv)
23721387c   Simon Wunderlich   batman-adv: add b...
1474
  {
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1475
  	int i;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
1476
  	u8 claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1477
  	struct batadv_hard_iface *primary_if;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
1478
  	u16 crc;
807736f6e   Sven Eckelmann   batman-adv: Split...
1479
  	unsigned long entrytime;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1480

7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1481
  	spin_lock_init(&bat_priv->bla.bcast_duplist_lock);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
1482
1483
  	batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering
  ");
23721387c   Simon Wunderlich   batman-adv: add b...
1484

38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1485
  	/* setting claim destination address */
807736f6e   Sven Eckelmann   batman-adv: Split...
1486
1487
  	memcpy(&bat_priv->bla.claim_dest.magic, claim_dest, 3);
  	bat_priv->bla.claim_dest.type = 0;
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1488
  	primary_if = batadv_primary_if_get_selected(bat_priv);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1489
  	if (primary_if) {
807736f6e   Sven Eckelmann   batman-adv: Split...
1490
1491
  		crc = crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN);
  		bat_priv->bla.claim_dest.group = htons(crc);
82047ad7f   Sven Eckelmann   batman-adv: Renam...
1492
  		batadv_hardif_put(primary_if);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1493
  	} else {
807736f6e   Sven Eckelmann   batman-adv: Split...
1494
  		bat_priv->bla.claim_dest.group = 0; /* will be set later */
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1495
  	}
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1496
  	/* initialize the duplicate list */
807736f6e   Sven Eckelmann   batman-adv: Split...
1497
  	entrytime = jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT);
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1498
  	for (i = 0; i < BATADV_DUPLIST_SIZE; i++)
807736f6e   Sven Eckelmann   batman-adv: Split...
1499
1500
  		bat_priv->bla.bcast_duplist[i].entrytime = entrytime;
  	bat_priv->bla.bcast_duplist_curr = 0;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1501

cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1502
1503
  	atomic_set(&bat_priv->bla.loopdetect_next,
  		   BATADV_BLA_LOOPDETECT_PERIODS);
807736f6e   Sven Eckelmann   batman-adv: Split...
1504
  	if (bat_priv->bla.claim_hash)
5346c35eb   Sven Eckelmann   batman-adv: Retur...
1505
  		return 0;
23721387c   Simon Wunderlich   batman-adv: add b...
1506

807736f6e   Sven Eckelmann   batman-adv: Split...
1507
1508
  	bat_priv->bla.claim_hash = batadv_hash_new(128);
  	bat_priv->bla.backbone_hash = batadv_hash_new(32);
23721387c   Simon Wunderlich   batman-adv: add b...
1509

807736f6e   Sven Eckelmann   batman-adv: Split...
1510
  	if (!bat_priv->bla.claim_hash || !bat_priv->bla.backbone_hash)
5346c35eb   Sven Eckelmann   batman-adv: Retur...
1511
  		return -ENOMEM;
23721387c   Simon Wunderlich   batman-adv: add b...
1512

807736f6e   Sven Eckelmann   batman-adv: Split...
1513
  	batadv_hash_set_lock_class(bat_priv->bla.claim_hash,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1514
  				   &batadv_claim_hash_lock_class_key);
807736f6e   Sven Eckelmann   batman-adv: Split...
1515
  	batadv_hash_set_lock_class(bat_priv->bla.backbone_hash,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1516
  				   &batadv_backbone_hash_lock_class_key);
5d52dad27   Sven Eckelmann   batman-adv: Initi...
1517

39c75a51e   Sven Eckelmann   batman-adv: Prefi...
1518
1519
  	batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hashes initialized
  ");
23721387c   Simon Wunderlich   batman-adv: add b...
1520

724144420   Antonio Quartulli   batman-adv: a del...
1521
1522
1523
1524
  	INIT_DELAYED_WORK(&bat_priv->bla.work, batadv_bla_periodic_work);
  
  	queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work,
  			   msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH));
5346c35eb   Sven Eckelmann   batman-adv: Retur...
1525
  	return 0;
23721387c   Simon Wunderlich   batman-adv: add b...
1526
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1527
  /**
2369e8270   Linus Lüssing   batman-adv: mcast...
1528
   * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup.
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1529
   * @bat_priv: the bat priv with all the soft interface information
2369e8270   Linus Lüssing   batman-adv: mcast...
1530
1531
1532
1533
   * @skb: contains the multicast packet to be checked
   * @payload_ptr: pointer to position inside the head buffer of the skb
   *  marking the start of the data to be CRC'ed
   * @orig: originator mac address, NULL if unknown
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1534
   *
2369e8270   Linus Lüssing   batman-adv: mcast...
1535
1536
1537
   * Check if it is on our broadcast list. Another gateway might have sent the
   * same packet because it is connected to the same backbone, so we have to
   * remove this duplicate.
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1538
1539
1540
1541
1542
   *
   * This is performed by checking the CRC, which will tell us
   * with a good chance that it is the same packet. If it is furthermore
   * sent by another host, drop it. We allow equal packets from
   * the same host however as this might be intended.
04e14be65   Simon Wunderlich   batman-adv: Updat...
1543
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
1544
   * Return: true if a packet is in the duplicate list, false otherwise.
9cfc7bd60   Sven Eckelmann   batman-adv: Refor...
1545
   */
2369e8270   Linus Lüssing   batman-adv: mcast...
1546
1547
1548
  static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
  				     struct sk_buff *skb, u8 *payload_ptr,
  				     const u8 *orig)
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1549
  {
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1550
  	struct batadv_bcast_duplist_entry *entry;
4b426b108   Sven Eckelmann   batman-adv: Use b...
1551
  	bool ret = false;
2369e8270   Linus Lüssing   batman-adv: mcast...
1552
1553
  	int i, curr;
  	__be32 crc;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1554
1555
  
  	/* calculate the crc ... */
2369e8270   Linus Lüssing   batman-adv: mcast...
1556
  	crc = batadv_skb_crc32(skb, payload_ptr);
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1557

7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1558
  	spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1559
  	for (i = 0; i < BATADV_DUPLIST_SIZE; i++) {
807736f6e   Sven Eckelmann   batman-adv: Split...
1560
1561
1562
  		curr = (bat_priv->bla.bcast_duplist_curr + i);
  		curr %= BATADV_DUPLIST_SIZE;
  		entry = &bat_priv->bla.bcast_duplist[curr];
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1563
1564
1565
1566
  
  		/* we can stop searching if the entry is too old ;
  		 * later entries will be even older
  		 */
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1567
1568
  		if (batadv_has_timed_out(entry->entrytime,
  					 BATADV_DUPLIST_TIMEOUT))
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1569
1570
1571
1572
  			break;
  
  		if (entry->crc != crc)
  			continue;
2369e8270   Linus Lüssing   batman-adv: mcast...
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
  		/* are the originators both known and not anonymous? */
  		if (orig && !is_zero_ether_addr(orig) &&
  		    !is_zero_ether_addr(entry->orig)) {
  			/* If known, check if the new frame came from
  			 * the same originator:
  			 * We are safe to take identical frames from the
  			 * same orig, if known, as multiplications in
  			 * the mesh are detected via the (orig, seqno) pair.
  			 * So we can be a bit more liberal here and allow
  			 * identical frames from the same orig which the source
  			 * host might have sent multiple times on purpose.
  			 */
  			if (batadv_compare_eth(entry->orig, orig))
  				continue;
  		}
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1588
1589
  
  		/* this entry seems to match: same crc, not too old,
4b426b108   Sven Eckelmann   batman-adv: Use b...
1590
  		 * and from another gw. therefore return true to forbid it.
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1591
  		 */
4b426b108   Sven Eckelmann   batman-adv: Use b...
1592
  		ret = true;
7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1593
  		goto out;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1594
  	}
7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1595
  	/* not found, add a new entry (overwrite the oldest entry)
3f68785e6   Antonio Quartulli   batman-adv: fix m...
1596
  	 * and allow it, its the first occurrence.
7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1597
  	 */
807736f6e   Sven Eckelmann   batman-adv: Split...
1598
  	curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1);
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1599
  	curr %= BATADV_DUPLIST_SIZE;
807736f6e   Sven Eckelmann   batman-adv: Split...
1600
  	entry = &bat_priv->bla.bcast_duplist[curr];
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1601
1602
  	entry->crc = crc;
  	entry->entrytime = jiffies;
2369e8270   Linus Lüssing   batman-adv: mcast...
1603
1604
1605
1606
1607
1608
1609
  
  	/* known originator */
  	if (orig)
  		ether_addr_copy(entry->orig, orig);
  	/* anonymous originator */
  	else
  		eth_zero_addr(entry->orig);
807736f6e   Sven Eckelmann   batman-adv: Split...
1610
  	bat_priv->bla.bcast_duplist_curr = curr;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1611

7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1612
1613
1614
1615
  out:
  	spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock);
  
  	return ret;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1616
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
1617
  /**
2369e8270   Linus Lüssing   batman-adv: mcast...
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
   * batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
   * @bat_priv: the bat priv with all the soft interface information
   * @skb: contains the multicast packet to be checked, decapsulated from a
   *  unicast_packet
   *
   * Check if it is on our broadcast list. Another gateway might have sent the
   * same packet because it is connected to the same backbone, so we have to
   * remove this duplicate.
   *
   * Return: true if a packet is in the duplicate list, false otherwise.
   */
  static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
  					   struct sk_buff *skb)
  {
  	return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL);
  }
  
  /**
   * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
   * @bat_priv: the bat priv with all the soft interface information
   * @skb: contains the bcast_packet to be checked
   *
   * Check if it is on our broadcast list. Another gateway might have sent the
   * same packet because it is connected to the same backbone, so we have to
   * remove this duplicate.
   *
   * Return: true if a packet is in the duplicate list, false otherwise.
   */
  bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
  				    struct sk_buff *skb)
  {
  	struct batadv_bcast_packet *bcast_packet;
  	u8 *payload_ptr;
  
  	bcast_packet = (struct batadv_bcast_packet *)skb->data;
  	payload_ptr = (u8 *)(bcast_packet + 1);
  
  	return batadv_bla_check_duplist(bat_priv, skb, payload_ptr,
  					bcast_packet->orig);
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1660
   * batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
04e14be65   Simon Wunderlich   batman-adv: Updat...
1661
   *  the VLAN identified by vid.
1b371d130   Simon Wunderlich   batman-adv: use c...
1662
   * @bat_priv: the bat priv with all the soft interface information
20ff9d593   Simon Wunderlich   batman-adv: don't...
1663
   * @orig: originator mac address
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1664
   * @vid: VLAN identifier
20ff9d593   Simon Wunderlich   batman-adv: don't...
1665
   *
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
1666
   * Return: true if orig is a backbone for this vid, false otherwise.
20ff9d593   Simon Wunderlich   batman-adv: don't...
1667
   */
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
1668
  bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig,
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1669
  				    unsigned short vid)
20ff9d593   Simon Wunderlich   batman-adv: don't...
1670
  {
807736f6e   Sven Eckelmann   batman-adv: Split...
1671
  	struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1672
  	struct hlist_head *head;
bae987747   Marek Lindner   batman-adv: renam...
1673
  	struct batadv_bla_backbone_gw *backbone_gw;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1674
1675
1676
  	int i;
  
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1677
  		return false;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1678
1679
  
  	if (!hash)
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1680
  		return false;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1681
1682
1683
1684
1685
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
1686
  		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1687
1688
  			if (batadv_compare_eth(backbone_gw->orig, orig) &&
  			    backbone_gw->vid == vid) {
20ff9d593   Simon Wunderlich   batman-adv: don't...
1689
  				rcu_read_unlock();
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1690
  				return true;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1691
1692
1693
1694
  			}
  		}
  		rcu_read_unlock();
  	}
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1695
  	return false;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1696
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1697
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1698
   * batadv_bla_is_backbone_gw() - check if originator is a backbone gw for a VLAN
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1699
   * @skb: the frame to be checked
23721387c   Simon Wunderlich   batman-adv: add b...
1700
1701
1702
   * @orig_node: the orig_node of the frame
   * @hdr_size: maximum length of the frame
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
1703
1704
   * Return: true if the orig_node is also a gateway on the soft interface,
   * otherwise it returns false.
23721387c   Simon Wunderlich   batman-adv: add b...
1705
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
1706
1707
  bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
  			       struct batadv_orig_node *orig_node, int hdr_size)
23721387c   Simon Wunderlich   batman-adv: add b...
1708
  {
bae987747   Marek Lindner   batman-adv: renam...
1709
  	struct batadv_bla_backbone_gw *backbone_gw;
c018ad3de   Antonio Quartulli   batman-adv: add t...
1710
  	unsigned short vid;
23721387c   Simon Wunderlich   batman-adv: add b...
1711
1712
  
  	if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1713
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
1714
1715
  
  	/* first, find out the vid. */
0d125074e   Antonio Quartulli   batman-adv: use E...
1716
  	if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
4b426b108   Sven Eckelmann   batman-adv: Use b...
1717
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
1718

c018ad3de   Antonio Quartulli   batman-adv: add t...
1719
  	vid = batadv_get_vid(skb, hdr_size);
23721387c   Simon Wunderlich   batman-adv: add b...
1720
1721
  
  	/* see if this originator is a backbone gw for this VLAN */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1722
1723
  	backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,
  						orig_node->orig, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1724
  	if (!backbone_gw)
4b426b108   Sven Eckelmann   batman-adv: Use b...
1725
  		return false;
23721387c   Simon Wunderlich   batman-adv: add b...
1726

c8b86c124   Sven Eckelmann   batman-adv: Renam...
1727
  	batadv_backbone_gw_put(backbone_gw);
4b426b108   Sven Eckelmann   batman-adv: Use b...
1728
  	return true;
23721387c   Simon Wunderlich   batman-adv: add b...
1729
  }
04e14be65   Simon Wunderlich   batman-adv: Updat...
1730
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1731
   * batadv_bla_free() - free all bla structures
04e14be65   Simon Wunderlich   batman-adv: Updat...
1732
1733
1734
1735
   * @bat_priv: the bat priv with all the soft interface information
   *
   * for softinterface free or module unload
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1736
  void batadv_bla_free(struct batadv_priv *bat_priv)
23721387c   Simon Wunderlich   batman-adv: add b...
1737
  {
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1738
  	struct batadv_hard_iface *primary_if;
23721387c   Simon Wunderlich   batman-adv: add b...
1739

807736f6e   Sven Eckelmann   batman-adv: Split...
1740
  	cancel_delayed_work_sync(&bat_priv->bla.work);
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1741
  	primary_if = batadv_primary_if_get_selected(bat_priv);
23721387c   Simon Wunderlich   batman-adv: add b...
1742

807736f6e   Sven Eckelmann   batman-adv: Split...
1743
  	if (bat_priv->bla.claim_hash) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1744
  		batadv_bla_purge_claims(bat_priv, primary_if, 1);
807736f6e   Sven Eckelmann   batman-adv: Split...
1745
1746
  		batadv_hash_destroy(bat_priv->bla.claim_hash);
  		bat_priv->bla.claim_hash = NULL;
23721387c   Simon Wunderlich   batman-adv: add b...
1747
  	}
807736f6e   Sven Eckelmann   batman-adv: Split...
1748
  	if (bat_priv->bla.backbone_hash) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1749
  		batadv_bla_purge_backbone_gw(bat_priv, 1);
807736f6e   Sven Eckelmann   batman-adv: Split...
1750
1751
  		batadv_hash_destroy(bat_priv->bla.backbone_hash);
  		bat_priv->bla.backbone_hash = NULL;
23721387c   Simon Wunderlich   batman-adv: add b...
1752
1753
  	}
  	if (primary_if)
82047ad7f   Sven Eckelmann   batman-adv: Renam...
1754
  		batadv_hardif_put(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
1755
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1756
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1757
   * batadv_bla_loopdetect_check() - check and handle a detected loop
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1758
1759
1760
1761
1762
1763
   * @bat_priv: the bat priv with all the soft interface information
   * @skb: the packet to check
   * @primary_if: interface where the request came on
   * @vid: the VLAN ID of the frame
   *
   * Checks if this packet is a loop detect frame which has been sent by us,
bccb48c89   Sven Eckelmann   batman-adv: Fix t...
1764
   * throws an uevent and logs the event if that is the case.
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
   *
   * Return: true if it is a loop detect frame which is to be dropped, false
   * otherwise.
   */
  static bool
  batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
  			    struct batadv_hard_iface *primary_if,
  			    unsigned short vid)
  {
  	struct batadv_bla_backbone_gw *backbone_gw;
  	struct ethhdr *ethhdr;
5af96b9c5   Marek Lindner   batman-adv: fix b...
1776
  	bool ret;
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
  
  	ethhdr = eth_hdr(skb);
  
  	/* Only check for the MAC address and skip more checks here for
  	 * performance reasons - this function is on the hotpath, after all.
  	 */
  	if (!batadv_compare_eth(ethhdr->h_source,
  				bat_priv->bla.loopdetect_addr))
  		return false;
  
  	/* If the packet came too late, don't forward it on the mesh
  	 * but don't consider that as loop. It might be a coincidence.
  	 */
  	if (batadv_has_timed_out(bat_priv->bla.loopdetect_lasttime,
  				 BATADV_BLA_LOOPDETECT_TIMEOUT))
  		return true;
  
  	backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
  						 primary_if->net_dev->dev_addr,
  						 vid, true);
  	if (unlikely(!backbone_gw))
  		return true;
5af96b9c5   Marek Lindner   batman-adv: fix b...
1799
  	ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work);
21ba5ab2a   Sven Eckelmann   batman-adv: Drop ...
1800
  	/* backbone_gw is unreferenced in the report work function
5af96b9c5   Marek Lindner   batman-adv: fix b...
1801
1802
1803
1804
  	 * if queue_work() call was successful
  	 */
  	if (!ret)
  		batadv_backbone_gw_put(backbone_gw);
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1805
1806
1807
1808
1809
  
  	return true;
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1810
   * batadv_bla_rx() - check packets coming from the mesh.
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1811
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
1812
1813
   * @skb: the frame to be checked
   * @vid: the VLAN ID of the frame
74c09b727   Linus Lüssing   batman-adv: mcast...
1814
   * @packet_type: the batman packet type this frame came in
23721387c   Simon Wunderlich   batman-adv: add b...
1815
   *
04e14be65   Simon Wunderlich   batman-adv: Updat...
1816
   * batadv_bla_rx avoidance checks if:
23721387c   Simon Wunderlich   batman-adv: add b...
1817
1818
1819
   *  * we have to race for a claim
   *  * if the frame is allowed on the LAN
   *
bccb48c89   Sven Eckelmann   batman-adv: Fix t...
1820
   * In these cases, the skb is further handled by this function
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
1821
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
1822
1823
   * Return: true if handled, otherwise it returns false and the caller shall
   * further process the skb.
23721387c   Simon Wunderlich   batman-adv: add b...
1824
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
1825
  bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
74c09b727   Linus Lüssing   batman-adv: mcast...
1826
  		   unsigned short vid, int packet_type)
23721387c   Simon Wunderlich   batman-adv: add b...
1827
  {
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1828
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
1829
  	struct ethhdr *ethhdr;
712bbfe46   Marek Lindner   batman-adv: renam...
1830
  	struct batadv_bla_claim search_claim, *claim = NULL;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1831
  	struct batadv_hard_iface *primary_if;
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1832
  	bool own_claim;
4b426b108   Sven Eckelmann   batman-adv: Use b...
1833
  	bool ret;
23721387c   Simon Wunderlich   batman-adv: add b...
1834

7ed4be952   Antonio Quartulli   batman-adv: use e...
1835
  	ethhdr = eth_hdr(skb);
23721387c   Simon Wunderlich   batman-adv: add b...
1836

e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1837
  	primary_if = batadv_primary_if_get_selected(bat_priv);
23721387c   Simon Wunderlich   batman-adv: add b...
1838
1839
1840
1841
1842
  	if (!primary_if)
  		goto handled;
  
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
  		goto allow;
cd9c7bfbb   Simon Wunderlich   batman-adv: add d...
1843
1844
  	if (batadv_bla_loopdetect_check(bat_priv, skb, primary_if, vid))
  		goto handled;
807736f6e   Sven Eckelmann   batman-adv: Split...
1845
  	if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
74c09b727   Linus Lüssing   batman-adv: mcast...
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
  		/* don't allow multicast packets while requests are in flight */
  		if (is_multicast_ether_addr(ethhdr->h_dest))
  			/* Both broadcast flooding or multicast-via-unicasts
  			 * delivery might send to multiple backbone gateways
  			 * sharing the same LAN and therefore need to coordinate
  			 * which backbone gateway forwards into the LAN,
  			 * by claiming the payload source address.
  			 *
  			 * Broadcast flooding and multicast-via-unicasts
  			 * delivery use the following two batman packet types.
  			 * Note: explicitly exclude BATADV_UNICAST_4ADDR,
  			 * as the DHCP gateway feature will send explicitly
  			 * to only one BLA gateway, so the claiming process
  			 * should be avoided there.
  			 */
  			if (packet_type == BATADV_BCAST ||
  			    packet_type == BATADV_UNICAST)
  				goto handled;
23721387c   Simon Wunderlich   batman-adv: add b...
1864

2369e8270   Linus Lüssing   batman-adv: mcast...
1865
1866
1867
1868
1869
1870
1871
  	/* potential duplicates from foreign BLA backbone gateways via
  	 * multicast-in-unicast packets
  	 */
  	if (is_multicast_ether_addr(ethhdr->h_dest) &&
  	    packet_type == BATADV_UNICAST &&
  	    batadv_bla_check_ucast_duplist(bat_priv, skb))
  		goto handled;
23721387c   Simon Wunderlich   batman-adv: add b...
1872

8fdd01530   Antonio Quartulli   batman-adv: prefe...
1873
  	ether_addr_copy(search_claim.addr, ethhdr->h_source);
23721387c   Simon Wunderlich   batman-adv: add b...
1874
  	search_claim.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1875
  	claim = batadv_claim_hash_find(bat_priv, &search_claim);
23721387c   Simon Wunderlich   batman-adv: add b...
1876
1877
1878
1879
1880
  
  	if (!claim) {
  		/* possible optimization: race for a claim */
  		/* No claim exists yet, claim it for us!
  		 */
4dd72f736   Andreas Pape   batman-adv: chang...
1881
1882
  
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
22f0502ed   Sven Eckelmann   batman-adv: Print...
1883
1884
1885
  			   "%s(): Unclaimed MAC %pM found. Claim it. Local: %s
  ",
  			   __func__, ethhdr->h_source,
4dd72f736   Andreas Pape   batman-adv: chang...
1886
1887
1888
  			   batadv_is_my_client(bat_priv,
  					       ethhdr->h_source, vid) ?
  			   "yes" : "no");
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1889
1890
1891
  		batadv_handle_claim(bat_priv, primary_if,
  				    primary_if->net_dev->dev_addr,
  				    ethhdr->h_source, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1892
1893
1894
1895
  		goto allow;
  	}
  
  	/* if it is our own claim ... */
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1896
1897
1898
1899
1900
1901
  	backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
  	own_claim = batadv_compare_eth(backbone_gw->orig,
  				       primary_if->net_dev->dev_addr);
  	batadv_backbone_gw_put(backbone_gw);
  
  	if (own_claim) {
23721387c   Simon Wunderlich   batman-adv: add b...
1902
1903
1904
1905
  		/* ... allow it in any case */
  		claim->lasttime = jiffies;
  		goto allow;
  	}
74c09b727   Linus Lüssing   batman-adv: mcast...
1906
1907
1908
  	/* if it is a multicast ... */
  	if (is_multicast_ether_addr(ethhdr->h_dest) &&
  	    (packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
2d3f6ccc4   Simon Wunderlich   batman-adv: check...
1909
1910
  		/* ... drop it. the responsible gateway is in charge.
  		 *
74c09b727   Linus Lüssing   batman-adv: mcast...
1911
  		 * We need to check packet type because with the gateway
2d3f6ccc4   Simon Wunderlich   batman-adv: check...
1912
  		 * feature, broadcasts (like DHCP requests) may be sent
74c09b727   Linus Lüssing   batman-adv: mcast...
1913
  		 * using a unicast 4 address packet type. See comment above.
2d3f6ccc4   Simon Wunderlich   batman-adv: check...
1914
  		 */
23721387c   Simon Wunderlich   batman-adv: add b...
1915
1916
1917
1918
1919
1920
  		goto handled;
  	} else {
  		/* seems the client considers us as its best gateway.
  		 * send a claim and update the claim table
  		 * immediately.
  		 */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1921
1922
1923
  		batadv_handle_claim(bat_priv, primary_if,
  				    primary_if->net_dev->dev_addr,
  				    ethhdr->h_source, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1924
1925
1926
  		goto allow;
  	}
  allow:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1927
  	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
4b426b108   Sven Eckelmann   batman-adv: Use b...
1928
  	ret = false;
23721387c   Simon Wunderlich   batman-adv: add b...
1929
1930
1931
1932
  	goto out;
  
  handled:
  	kfree_skb(skb);
4b426b108   Sven Eckelmann   batman-adv: Use b...
1933
  	ret = true;
23721387c   Simon Wunderlich   batman-adv: add b...
1934
1935
1936
  
  out:
  	if (primary_if)
82047ad7f   Sven Eckelmann   batman-adv: Renam...
1937
  		batadv_hardif_put(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
1938
  	if (claim)
321e3e088   Sven Eckelmann   batman-adv: Renam...
1939
  		batadv_claim_put(claim);
23721387c   Simon Wunderlich   batman-adv: add b...
1940
1941
  	return ret;
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1942
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
1943
   * batadv_bla_tx() - check packets going into the mesh
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1944
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
1945
1946
1947
   * @skb: the frame to be checked
   * @vid: the VLAN ID of the frame
   *
04e14be65   Simon Wunderlich   batman-adv: Updat...
1948
   * batadv_bla_tx checks if:
23721387c   Simon Wunderlich   batman-adv: add b...
1949
1950
1951
   *  * a claim was received which has to be processed
   *  * the frame is allowed on the mesh
   *
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
1952
   * in these cases, the skb is further handled by this function.
9d2c9488c   Linus Lüssing   batman-adv: fix p...
1953
1954
   *
   * This call might reallocate skb data.
62fe710f6   Sven Eckelmann   batman-adv: Fix k...
1955
   *
4b426b108   Sven Eckelmann   batman-adv: Use b...
1956
1957
   * Return: true if handled, otherwise it returns false and the caller shall
   * further process the skb.
23721387c   Simon Wunderlich   batman-adv: add b...
1958
   */
4b426b108   Sven Eckelmann   batman-adv: Use b...
1959
1960
  bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
  		   unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
1961
1962
  {
  	struct ethhdr *ethhdr;
712bbfe46   Marek Lindner   batman-adv: renam...
1963
  	struct batadv_bla_claim search_claim, *claim = NULL;
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1964
  	struct batadv_bla_backbone_gw *backbone_gw;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1965
  	struct batadv_hard_iface *primary_if;
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1966
  	bool client_roamed;
4b426b108   Sven Eckelmann   batman-adv: Use b...
1967
  	bool ret = false;
23721387c   Simon Wunderlich   batman-adv: add b...
1968

e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1969
  	primary_if = batadv_primary_if_get_selected(bat_priv);
23721387c   Simon Wunderlich   batman-adv: add b...
1970
1971
1972
1973
1974
  	if (!primary_if)
  		goto out;
  
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
  		goto allow;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1975
  	if (batadv_bla_process_claim(bat_priv, primary_if, skb))
23721387c   Simon Wunderlich   batman-adv: add b...
1976
  		goto handled;
7ed4be952   Antonio Quartulli   batman-adv: use e...
1977
  	ethhdr = eth_hdr(skb);
23721387c   Simon Wunderlich   batman-adv: add b...
1978

807736f6e   Sven Eckelmann   batman-adv: Split...
1979
  	if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
23721387c   Simon Wunderlich   batman-adv: add b...
1980
1981
1982
  		/* don't allow broadcasts while requests are in flight */
  		if (is_multicast_ether_addr(ethhdr->h_dest))
  			goto handled;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
1983
  	ether_addr_copy(search_claim.addr, ethhdr->h_source);
23721387c   Simon Wunderlich   batman-adv: add b...
1984
  	search_claim.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1985
  	claim = batadv_claim_hash_find(bat_priv, &search_claim);
23721387c   Simon Wunderlich   batman-adv: add b...
1986
1987
1988
1989
1990
1991
  
  	/* if no claim exists, allow it. */
  	if (!claim)
  		goto allow;
  
  	/* check if we are responsible. */
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
1992
1993
1994
1995
1996
1997
  	backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
  	client_roamed = batadv_compare_eth(backbone_gw->orig,
  					   primary_if->net_dev->dev_addr);
  	batadv_backbone_gw_put(backbone_gw);
  
  	if (client_roamed) {
23721387c   Simon Wunderlich   batman-adv: add b...
1998
1999
2000
  		/* if yes, the client has roamed and we have
  		 * to unclaim it.
  		 */
a3a5129e1   Andreas Pape   batman-adv: handl...
2001
2002
2003
2004
2005
  		if (batadv_has_timed_out(claim->lasttime, 100)) {
  			/* only unclaim if the last claim entry is
  			 * older than 100 ms to make sure we really
  			 * have a roaming client here.
  			 */
22f0502ed   Sven Eckelmann   batman-adv: Print...
2006
2007
2008
  			batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): Roaming client %pM detected. Unclaim it.
  ",
  				   __func__, ethhdr->h_source);
a3a5129e1   Andreas Pape   batman-adv: handl...
2009
2010
2011
2012
2013
  			batadv_handle_unclaim(bat_priv, primary_if,
  					      primary_if->net_dev->dev_addr,
  					      ethhdr->h_source, vid);
  			goto allow;
  		} else {
22f0502ed   Sven Eckelmann   batman-adv: Print...
2014
2015
2016
  			batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): Race for claim %pM detected. Drop packet.
  ",
  				   __func__, ethhdr->h_source);
a3a5129e1   Andreas Pape   batman-adv: handl...
2017
2018
  			goto handled;
  		}
23721387c   Simon Wunderlich   batman-adv: add b...
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
  	}
  
  	/* check if it is a multicast/broadcast frame */
  	if (is_multicast_ether_addr(ethhdr->h_dest)) {
  		/* drop it. the responsible gateway has forwarded it into
  		 * the backbone network.
  		 */
  		goto handled;
  	} else {
  		/* we must allow it. at least if we are
  		 * responsible for the DESTINATION.
  		 */
  		goto allow;
  	}
  allow:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
2034
  	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
4b426b108   Sven Eckelmann   batman-adv: Use b...
2035
  	ret = false;
23721387c   Simon Wunderlich   batman-adv: add b...
2036
2037
  	goto out;
  handled:
4b426b108   Sven Eckelmann   batman-adv: Use b...
2038
  	ret = true;
23721387c   Simon Wunderlich   batman-adv: add b...
2039
2040
  out:
  	if (primary_if)
82047ad7f   Sven Eckelmann   batman-adv: Renam...
2041
  		batadv_hardif_put(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
2042
  	if (claim)
321e3e088   Sven Eckelmann   batman-adv: Renam...
2043
  		batadv_claim_put(claim);
23721387c   Simon Wunderlich   batman-adv: add b...
2044
2045
  	return ret;
  }
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2046

dc1cbd145   Sven Eckelmann   batman-adv: Allow...
2047
  #ifdef CONFIG_BATMAN_ADV_DEBUGFS
04e14be65   Simon Wunderlich   batman-adv: Updat...
2048
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
2049
   * batadv_bla_claim_table_seq_print_text() - print the claim table in a seq file
04e14be65   Simon Wunderlich   batman-adv: Updat...
2050
2051
2052
2053
2054
   * @seq: seq file to print on
   * @offset: not used
   *
   * Return: always 0
   */
08adf1512   Sven Eckelmann   batman-adv: Prefi...
2055
  int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2056
2057
  {
  	struct net_device *net_dev = (struct net_device *)seq->private;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
2058
  	struct batadv_priv *bat_priv = netdev_priv(net_dev);
807736f6e   Sven Eckelmann   batman-adv: Split...
2059
  	struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
2060
  	struct batadv_bla_backbone_gw *backbone_gw;
712bbfe46   Marek Lindner   batman-adv: renam...
2061
  	struct batadv_bla_claim *claim;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
2062
  	struct batadv_hard_iface *primary_if;
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2063
  	struct hlist_head *head;
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
2064
  	u16 backbone_crc;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
2065
  	u32 i;
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2066
  	bool is_own;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
2067
  	u8 *primary_addr;
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2068

30da63a6a   Marek Lindner   batman-adv: conso...
2069
2070
  	primary_if = batadv_seq_print_text_primary_if_get(seq);
  	if (!primary_if)
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2071
  		goto out;
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2072

1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
2073
  	primary_addr = primary_if->net_dev->dev_addr;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
2074
  	seq_printf(seq,
39a329915   Antonio Quartulli   batman-adv: unify...
2075
2076
  		   "Claims announced for the mesh %s (orig %pM, group id %#.4x)
  ",
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
2077
  		   net_dev->name, primary_addr,
807736f6e   Sven Eckelmann   batman-adv: Split...
2078
  		   ntohs(bat_priv->bla.claim_dest.group));
925a6f379   Antonio Quartulli   batman-adv: use s...
2079
2080
2081
  	seq_puts(seq,
  		 "   Client               VID      Originator        [o] (CRC   )
  ");
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2082
2083
2084
2085
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
2086
  		hlist_for_each_entry_rcu(claim, head, hash_entry) {
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
2087
2088
2089
  			backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
  
  			is_own = batadv_compare_eth(backbone_gw->orig,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
2090
  						    primary_addr);
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
2091

3db0decf1   Sven Eckelmann   batman-adv: Fix n...
2092
2093
2094
  			spin_lock_bh(&backbone_gw->crc_lock);
  			backbone_crc = backbone_gw->crc;
  			spin_unlock_bh(&backbone_gw->crc_lock);
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
2095
2096
  			seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)
  ",
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
2097
  				   claim->addr, batadv_print_vid(claim->vid),
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
2098
  				   backbone_gw->orig,
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2099
  				   (is_own ? 'x' : ' '),
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
2100
  				   backbone_crc);
3db0decf1   Sven Eckelmann   batman-adv: Fix n...
2101
2102
  
  			batadv_backbone_gw_put(backbone_gw);
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2103
2104
2105
2106
2107
  		}
  		rcu_read_unlock();
  	}
  out:
  	if (primary_if)
82047ad7f   Sven Eckelmann   batman-adv: Renam...
2108
  		batadv_hardif_put(primary_if);
30da63a6a   Marek Lindner   batman-adv: conso...
2109
  	return 0;
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
2110
  }
dc1cbd145   Sven Eckelmann   batman-adv: Allow...
2111
  #endif
536a23f11   Simon Wunderlich   batman-adv: Add t...
2112

04e14be65   Simon Wunderlich   batman-adv: Updat...
2113
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
2114
   * batadv_bla_claim_dump_entry() - dump one entry of the claim table
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2115
2116
2117
   * to a netlink socket
   * @msg: buffer for the message
   * @portid: netlink port
24d71b923   Sven Eckelmann   batman-adv: Add i...
2118
   * @cb: Control block containing additional options
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2119
2120
2121
2122
2123
2124
   * @primary_if: primary interface
   * @claim: entry to dump
   *
   * Return: 0 or error code.
   */
  static int
24d71b923   Sven Eckelmann   batman-adv: Add i...
2125
2126
  batadv_bla_claim_dump_entry(struct sk_buff *msg, u32 portid,
  			    struct netlink_callback *cb,
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2127
2128
2129
2130
2131
2132
2133
2134
  			    struct batadv_hard_iface *primary_if,
  			    struct batadv_bla_claim *claim)
  {
  	u8 *primary_addr = primary_if->net_dev->dev_addr;
  	u16 backbone_crc;
  	bool is_own;
  	void *hdr;
  	int ret = -EINVAL;
24d71b923   Sven Eckelmann   batman-adv: Add i...
2135
2136
2137
  	hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
  			  &batadv_netlink_family, NLM_F_MULTI,
  			  BATADV_CMD_GET_BLA_CLAIM);
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2138
2139
2140
2141
  	if (!hdr) {
  		ret = -ENOBUFS;
  		goto out;
  	}
24d71b923   Sven Eckelmann   batman-adv: Add i...
2142
  	genl_dump_check_consistent(cb, hdr);
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
  	is_own = batadv_compare_eth(claim->backbone_gw->orig,
  				    primary_addr);
  
  	spin_lock_bh(&claim->backbone_gw->crc_lock);
  	backbone_crc = claim->backbone_gw->crc;
  	spin_unlock_bh(&claim->backbone_gw->crc_lock);
  
  	if (is_own)
  		if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) {
  			genlmsg_cancel(msg, hdr);
  			goto out;
  		}
  
  	if (nla_put(msg, BATADV_ATTR_BLA_ADDRESS, ETH_ALEN, claim->addr) ||
  	    nla_put_u16(msg, BATADV_ATTR_BLA_VID, claim->vid) ||
  	    nla_put(msg, BATADV_ATTR_BLA_BACKBONE, ETH_ALEN,
  		    claim->backbone_gw->orig) ||
  	    nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
  			backbone_crc)) {
  		genlmsg_cancel(msg, hdr);
  		goto out;
  	}
  
  	genlmsg_end(msg, hdr);
  	ret = 0;
  
  out:
  	return ret;
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
2174
   * batadv_bla_claim_dump_bucket() - dump one bucket of the claim table
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2175
2176
2177
   * to a netlink socket
   * @msg: buffer for the message
   * @portid: netlink port
24d71b923   Sven Eckelmann   batman-adv: Add i...
2178
   * @cb: Control block containing additional options
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2179
   * @primary_if: primary interface
24d71b923   Sven Eckelmann   batman-adv: Add i...
2180
2181
   * @hash: hash to dump
   * @bucket: bucket index to dump
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2182
2183
2184
2185
2186
   * @idx_skip: How many entries to skip
   *
   * Return: always 0.
   */
  static int
24d71b923   Sven Eckelmann   batman-adv: Add i...
2187
2188
  batadv_bla_claim_dump_bucket(struct sk_buff *msg, u32 portid,
  			     struct netlink_callback *cb,
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2189
  			     struct batadv_hard_iface *primary_if,
24d71b923   Sven Eckelmann   batman-adv: Add i...
2190
2191
  			     struct batadv_hashtable *hash, unsigned int bucket,
  			     int *idx_skip)
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2192
2193
2194
  {
  	struct batadv_bla_claim *claim;
  	int idx = 0;
b0264ecdf   Sven Eckelmann   batman-adv: Fix n...
2195
  	int ret = 0;
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2196

24d71b923   Sven Eckelmann   batman-adv: Add i...
2197
2198
2199
2200
  	spin_lock_bh(&hash->list_locks[bucket]);
  	cb->seq = atomic_read(&hash->generation) << 1 | 1;
  
  	hlist_for_each_entry(claim, &hash->table[bucket], hash_entry) {
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2201
2202
  		if (idx++ < *idx_skip)
  			continue;
b0264ecdf   Sven Eckelmann   batman-adv: Fix n...
2203

24d71b923   Sven Eckelmann   batman-adv: Add i...
2204
  		ret = batadv_bla_claim_dump_entry(msg, portid, cb,
b0264ecdf   Sven Eckelmann   batman-adv: Fix n...
2205
2206
  						  primary_if, claim);
  		if (ret) {
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2207
2208
2209
2210
  			*idx_skip = idx - 1;
  			goto unlock;
  		}
  	}
b0264ecdf   Sven Eckelmann   batman-adv: Fix n...
2211
  	*idx_skip = 0;
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2212
  unlock:
24d71b923   Sven Eckelmann   batman-adv: Add i...
2213
  	spin_unlock_bh(&hash->list_locks[bucket]);
b0264ecdf   Sven Eckelmann   batman-adv: Fix n...
2214
  	return ret;
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2215
2216
2217
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
2218
   * batadv_bla_claim_dump() - dump claim table to a netlink socket
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
   * @msg: buffer for the message
   * @cb: callback structure containing arguments
   *
   * Return: message length.
   */
  int batadv_bla_claim_dump(struct sk_buff *msg, struct netlink_callback *cb)
  {
  	struct batadv_hard_iface *primary_if = NULL;
  	int portid = NETLINK_CB(cb->skb).portid;
  	struct net *net = sock_net(cb->skb->sk);
  	struct net_device *soft_iface;
  	struct batadv_hashtable *hash;
  	struct batadv_priv *bat_priv;
  	int bucket = cb->args[0];
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
  	int idx = cb->args[1];
  	int ifindex;
  	int ret = 0;
  
  	ifindex = batadv_netlink_get_ifindex(cb->nlh,
  					     BATADV_ATTR_MESH_IFINDEX);
  	if (!ifindex)
  		return -EINVAL;
  
  	soft_iface = dev_get_by_index(net, ifindex);
  	if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
  		ret = -ENODEV;
  		goto out;
  	}
  
  	bat_priv = netdev_priv(soft_iface);
  	hash = bat_priv->bla.claim_hash;
  
  	primary_if = batadv_primary_if_get_selected(bat_priv);
  	if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
  		ret = -ENOENT;
  		goto out;
  	}
  
  	while (bucket < hash->size) {
24d71b923   Sven Eckelmann   batman-adv: Add i...
2258
2259
  		if (batadv_bla_claim_dump_bucket(msg, portid, cb, primary_if,
  						 hash, bucket, &idx))
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
  			break;
  		bucket++;
  	}
  
  	cb->args[0] = bucket;
  	cb->args[1] = idx;
  
  	ret = msg->len;
  
  out:
  	if (primary_if)
  		batadv_hardif_put(primary_if);
  
  	if (soft_iface)
  		dev_put(soft_iface);
  
  	return ret;
  }
dc1cbd145   Sven Eckelmann   batman-adv: Allow...
2278
  #ifdef CONFIG_BATMAN_ADV_DEBUGFS
04f3f5bf1   Andrew Lunn   batman-adv: add B...
2279
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
2280
2281
   * batadv_bla_backbone_table_seq_print_text() - print the backbone table in a
   *  seq file
04e14be65   Simon Wunderlich   batman-adv: Updat...
2282
2283
2284
2285
2286
   * @seq: seq file to print on
   * @offset: not used
   *
   * Return: always 0
   */
536a23f11   Simon Wunderlich   batman-adv: Add t...
2287
2288
2289
2290
  int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
  {
  	struct net_device *net_dev = (struct net_device *)seq->private;
  	struct batadv_priv *bat_priv = netdev_priv(net_dev);
807736f6e   Sven Eckelmann   batman-adv: Split...
2291
  	struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
bae987747   Marek Lindner   batman-adv: renam...
2292
  	struct batadv_bla_backbone_gw *backbone_gw;
536a23f11   Simon Wunderlich   batman-adv: Add t...
2293
  	struct batadv_hard_iface *primary_if;
536a23f11   Simon Wunderlich   batman-adv: Add t...
2294
2295
  	struct hlist_head *head;
  	int secs, msecs;
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
2296
  	u16 backbone_crc;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
2297
  	u32 i;
536a23f11   Simon Wunderlich   batman-adv: Add t...
2298
  	bool is_own;
6b5e971a2   Sven Eckelmann   batman-adv: Repla...
2299
  	u8 *primary_addr;
536a23f11   Simon Wunderlich   batman-adv: Add t...
2300

30da63a6a   Marek Lindner   batman-adv: conso...
2301
2302
  	primary_if = batadv_seq_print_text_primary_if_get(seq);
  	if (!primary_if)
536a23f11   Simon Wunderlich   batman-adv: Add t...
2303
  		goto out;
536a23f11   Simon Wunderlich   batman-adv: Add t...
2304
2305
2306
  
  	primary_addr = primary_if->net_dev->dev_addr;
  	seq_printf(seq,
39a329915   Antonio Quartulli   batman-adv: unify...
2307
2308
  		   "Backbones announced for the mesh %s (orig %pM, group id %#.4x)
  ",
536a23f11   Simon Wunderlich   batman-adv: Add t...
2309
  		   net_dev->name, primary_addr,
807736f6e   Sven Eckelmann   batman-adv: Split...
2310
  		   ntohs(bat_priv->bla.claim_dest.group));
925a6f379   Antonio Quartulli   batman-adv: use s...
2311
2312
  	seq_puts(seq, "   Originator           VID   last seen (CRC   )
  ");
536a23f11   Simon Wunderlich   batman-adv: Add t...
2313
2314
2315
2316
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
2317
  		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
536a23f11   Simon Wunderlich   batman-adv: Add t...
2318
2319
2320
2321
2322
2323
2324
2325
2326
  			msecs = jiffies_to_msecs(jiffies -
  						 backbone_gw->lasttime);
  			secs = msecs / 1000;
  			msecs = msecs % 1000;
  
  			is_own = batadv_compare_eth(backbone_gw->orig,
  						    primary_addr);
  			if (is_own)
  				continue;
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
2327
2328
2329
  			spin_lock_bh(&backbone_gw->crc_lock);
  			backbone_crc = backbone_gw->crc;
  			spin_unlock_bh(&backbone_gw->crc_lock);
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
2330
2331
  			seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
2332
  				   backbone_gw->orig,
f7a2bd654   Sven Eckelmann   batman-adv: Conve...
2333
  				   batadv_print_vid(backbone_gw->vid), secs,
5a1dd8a47   Simon Wunderlich   batman-adv: lock ...
2334
  				   msecs, backbone_crc);
536a23f11   Simon Wunderlich   batman-adv: Add t...
2335
2336
2337
2338
2339
  		}
  		rcu_read_unlock();
  	}
  out:
  	if (primary_if)
82047ad7f   Sven Eckelmann   batman-adv: Renam...
2340
  		batadv_hardif_put(primary_if);
30da63a6a   Marek Lindner   batman-adv: conso...
2341
  	return 0;
536a23f11   Simon Wunderlich   batman-adv: Add t...
2342
  }
dc1cbd145   Sven Eckelmann   batman-adv: Allow...
2343
  #endif
ea4152e11   Simon Wunderlich   batman-adv: add b...
2344
2345
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
2346
2347
   * batadv_bla_backbone_dump_entry() - dump one entry of the backbone table to a
   *  netlink socket
ea4152e11   Simon Wunderlich   batman-adv: add b...
2348
2349
   * @msg: buffer for the message
   * @portid: netlink port
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2350
   * @cb: Control block containing additional options
ea4152e11   Simon Wunderlich   batman-adv: add b...
2351
2352
2353
2354
2355
2356
   * @primary_if: primary interface
   * @backbone_gw: entry to dump
   *
   * Return: 0 or error code.
   */
  static int
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2357
2358
  batadv_bla_backbone_dump_entry(struct sk_buff *msg, u32 portid,
  			       struct netlink_callback *cb,
ea4152e11   Simon Wunderlich   batman-adv: add b...
2359
2360
2361
2362
2363
2364
2365
2366
2367
  			       struct batadv_hard_iface *primary_if,
  			       struct batadv_bla_backbone_gw *backbone_gw)
  {
  	u8 *primary_addr = primary_if->net_dev->dev_addr;
  	u16 backbone_crc;
  	bool is_own;
  	int msecs;
  	void *hdr;
  	int ret = -EINVAL;
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2368
2369
2370
  	hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
  			  &batadv_netlink_family, NLM_F_MULTI,
  			  BATADV_CMD_GET_BLA_BACKBONE);
ea4152e11   Simon Wunderlich   batman-adv: add b...
2371
2372
2373
2374
  	if (!hdr) {
  		ret = -ENOBUFS;
  		goto out;
  	}
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2375
  	genl_dump_check_consistent(cb, hdr);
ea4152e11   Simon Wunderlich   batman-adv: add b...
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
  	is_own = batadv_compare_eth(backbone_gw->orig, primary_addr);
  
  	spin_lock_bh(&backbone_gw->crc_lock);
  	backbone_crc = backbone_gw->crc;
  	spin_unlock_bh(&backbone_gw->crc_lock);
  
  	msecs = jiffies_to_msecs(jiffies - backbone_gw->lasttime);
  
  	if (is_own)
  		if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) {
  			genlmsg_cancel(msg, hdr);
  			goto out;
  		}
  
  	if (nla_put(msg, BATADV_ATTR_BLA_BACKBONE, ETH_ALEN,
  		    backbone_gw->orig) ||
  	    nla_put_u16(msg, BATADV_ATTR_BLA_VID, backbone_gw->vid) ||
  	    nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
  			backbone_crc) ||
  	    nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) {
  		genlmsg_cancel(msg, hdr);
  		goto out;
  	}
  
  	genlmsg_end(msg, hdr);
  	ret = 0;
  
  out:
  	return ret;
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
2408
2409
   * batadv_bla_backbone_dump_bucket() - dump one bucket of the backbone table to
   *  a netlink socket
ea4152e11   Simon Wunderlich   batman-adv: add b...
2410
2411
   * @msg: buffer for the message
   * @portid: netlink port
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2412
   * @cb: Control block containing additional options
ea4152e11   Simon Wunderlich   batman-adv: add b...
2413
   * @primary_if: primary interface
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2414
2415
   * @hash: hash to dump
   * @bucket: bucket index to dump
ea4152e11   Simon Wunderlich   batman-adv: add b...
2416
2417
2418
2419
2420
   * @idx_skip: How many entries to skip
   *
   * Return: always 0.
   */
  static int
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2421
2422
  batadv_bla_backbone_dump_bucket(struct sk_buff *msg, u32 portid,
  				struct netlink_callback *cb,
ea4152e11   Simon Wunderlich   batman-adv: add b...
2423
  				struct batadv_hard_iface *primary_if,
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2424
2425
  				struct batadv_hashtable *hash,
  				unsigned int bucket, int *idx_skip)
ea4152e11   Simon Wunderlich   batman-adv: add b...
2426
2427
2428
  {
  	struct batadv_bla_backbone_gw *backbone_gw;
  	int idx = 0;
fce672db5   Sven Eckelmann   batman-adv: Fix n...
2429
  	int ret = 0;
ea4152e11   Simon Wunderlich   batman-adv: add b...
2430

b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2431
2432
2433
2434
  	spin_lock_bh(&hash->list_locks[bucket]);
  	cb->seq = atomic_read(&hash->generation) << 1 | 1;
  
  	hlist_for_each_entry(backbone_gw, &hash->table[bucket], hash_entry) {
ea4152e11   Simon Wunderlich   batman-adv: add b...
2435
2436
  		if (idx++ < *idx_skip)
  			continue;
fce672db5   Sven Eckelmann   batman-adv: Fix n...
2437

b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2438
  		ret = batadv_bla_backbone_dump_entry(msg, portid, cb,
fce672db5   Sven Eckelmann   batman-adv: Fix n...
2439
2440
  						     primary_if, backbone_gw);
  		if (ret) {
ea4152e11   Simon Wunderlich   batman-adv: add b...
2441
2442
2443
2444
  			*idx_skip = idx - 1;
  			goto unlock;
  		}
  	}
fce672db5   Sven Eckelmann   batman-adv: Fix n...
2445
  	*idx_skip = 0;
ea4152e11   Simon Wunderlich   batman-adv: add b...
2446
  unlock:
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2447
  	spin_unlock_bh(&hash->list_locks[bucket]);
fce672db5   Sven Eckelmann   batman-adv: Fix n...
2448
  	return ret;
ea4152e11   Simon Wunderlich   batman-adv: add b...
2449
2450
2451
  }
  
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
2452
   * batadv_bla_backbone_dump() - dump backbone table to a netlink socket
ea4152e11   Simon Wunderlich   batman-adv: add b...
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
   * @msg: buffer for the message
   * @cb: callback structure containing arguments
   *
   * Return: message length.
   */
  int batadv_bla_backbone_dump(struct sk_buff *msg, struct netlink_callback *cb)
  {
  	struct batadv_hard_iface *primary_if = NULL;
  	int portid = NETLINK_CB(cb->skb).portid;
  	struct net *net = sock_net(cb->skb->sk);
  	struct net_device *soft_iface;
  	struct batadv_hashtable *hash;
  	struct batadv_priv *bat_priv;
  	int bucket = cb->args[0];
ea4152e11   Simon Wunderlich   batman-adv: add b...
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
  	int idx = cb->args[1];
  	int ifindex;
  	int ret = 0;
  
  	ifindex = batadv_netlink_get_ifindex(cb->nlh,
  					     BATADV_ATTR_MESH_IFINDEX);
  	if (!ifindex)
  		return -EINVAL;
  
  	soft_iface = dev_get_by_index(net, ifindex);
  	if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
  		ret = -ENODEV;
  		goto out;
  	}
  
  	bat_priv = netdev_priv(soft_iface);
  	hash = bat_priv->bla.backbone_hash;
  
  	primary_if = batadv_primary_if_get_selected(bat_priv);
  	if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
  		ret = -ENOENT;
  		goto out;
  	}
  
  	while (bucket < hash->size) {
b00d0e6a2   Sven Eckelmann   batman-adv: Add i...
2492
2493
  		if (batadv_bla_backbone_dump_bucket(msg, portid, cb, primary_if,
  						    hash, bucket, &idx))
ea4152e11   Simon Wunderlich   batman-adv: add b...
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
  			break;
  		bucket++;
  	}
  
  	cb->args[0] = bucket;
  	cb->args[1] = idx;
  
  	ret = msg->len;
  
  out:
  	if (primary_if)
  		batadv_hardif_put(primary_if);
  
  	if (soft_iface)
  		dev_put(soft_iface);
  
  	return ret;
  }
00311de5f   Andreas Pape   batman-adv: preve...
2512
2513
2514
  
  #ifdef CONFIG_BATMAN_ADV_DAT
  /**
7e9a8c2ce   Sven Eckelmann   batman-adv: Use p...
2515
   * batadv_bla_check_claim() - check if address is claimed
00311de5f   Andreas Pape   batman-adv: preve...
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
   *
   * @bat_priv: the bat priv with all the soft interface information
   * @addr: mac address of which the claim status is checked
   * @vid: the VLAN ID
   *
   * addr is checked if this address is claimed by the local device itself.
   *
   * Return: true if bla is disabled or the mac is claimed by the device,
   * false if the device addr is already claimed by another gateway
   */
  bool batadv_bla_check_claim(struct batadv_priv *bat_priv,
  			    u8 *addr, unsigned short vid)
  {
  	struct batadv_bla_claim search_claim;
  	struct batadv_bla_claim *claim = NULL;
  	struct batadv_hard_iface *primary_if = NULL;
  	bool ret = true;
  
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
  		return ret;
  
  	primary_if = batadv_primary_if_get_selected(bat_priv);
  	if (!primary_if)
  		return ret;
  
  	/* First look if the mac address is claimed */
  	ether_addr_copy(search_claim.addr, addr);
  	search_claim.vid = vid;
  
  	claim = batadv_claim_hash_find(bat_priv, &search_claim);
  
  	/* If there is a claim and we are not owner of the claim,
  	 * return false.
  	 */
  	if (claim) {
  		if (!batadv_compare_eth(claim->backbone_gw->orig,
  					primary_if->net_dev->dev_addr))
  			ret = false;
  		batadv_claim_put(claim);
  	}
  
  	batadv_hardif_put(primary_if);
  	return ret;
  }
  #endif