Blame view

net/batman-adv/bridge_loop_avoidance.c 46.6 KB
e19f9759e   Simon Wunderlich   batman-adv: updat...
1
  /* Copyright (C) 2011-2014 B.A.T.M.A.N. contributors:
23721387c   Simon Wunderlich   batman-adv: add b...
2
3
4
5
6
7
8
9
10
11
12
13
14
   *
   * Simon Wunderlich
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of version 2 of the GNU General Public
   * License as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
ebf38fb7a   Antonio Quartulli   batman-adv: remov...
15
   * along with this program; if not, see <http://www.gnu.org/licenses/>.
23721387c   Simon Wunderlich   batman-adv: add b...
16
17
18
19
20
21
22
   */
  
  #include "main.h"
  #include "hash.h"
  #include "hard-interface.h"
  #include "originator.h"
  #include "bridge_loop_avoidance.h"
20ff9d593   Simon Wunderlich   batman-adv: don't...
23
  #include "translation-table.h"
23721387c   Simon Wunderlich   batman-adv: add b...
24
25
26
27
28
29
30
  #include "send.h"
  
  #include <linux/etherdevice.h>
  #include <linux/crc16.h>
  #include <linux/if_arp.h>
  #include <net/arp.h>
  #include <linux/if_vlan.h>
3b300de32   Sven Eckelmann   batman-adv: Prefi...
31
  static const uint8_t batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05};
23721387c   Simon Wunderlich   batman-adv: add b...
32

3b300de32   Sven Eckelmann   batman-adv: Prefi...
33
  static void batadv_bla_periodic_work(struct work_struct *work);
bae987747   Marek Lindner   batman-adv: renam...
34
35
36
  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...
37
38
  
  /* return the index of the claim */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
39
  static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
23721387c   Simon Wunderlich   batman-adv: add b...
40
  {
712bbfe46   Marek Lindner   batman-adv: renam...
41
  	struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
23721387c   Simon Wunderlich   batman-adv: add b...
42
  	uint32_t hash = 0;
23721387c   Simon Wunderlich   batman-adv: add b...
43

07568d036   Simon Wunderlich   batman-adv: don't...
44
45
  	hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
  	hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
23721387c   Simon Wunderlich   batman-adv: add b...
46
47
48
49
50
51
52
53
54
  
  	hash += (hash << 3);
  	hash ^= (hash >> 11);
  	hash += (hash << 15);
  
  	return hash % size;
  }
  
  /* return the index of the backbone gateway */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
55
56
  static inline uint32_t batadv_choose_backbone_gw(const void *data,
  						 uint32_t size)
23721387c   Simon Wunderlich   batman-adv: add b...
57
  {
712bbfe46   Marek Lindner   batman-adv: renam...
58
  	const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
23721387c   Simon Wunderlich   batman-adv: add b...
59
  	uint32_t hash = 0;
23721387c   Simon Wunderlich   batman-adv: add b...
60

07568d036   Simon Wunderlich   batman-adv: don't...
61
62
  	hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
  	hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
23721387c   Simon Wunderlich   batman-adv: add b...
63
64
65
66
67
68
69
70
71
72
  
  	hash += (hash << 3);
  	hash ^= (hash >> 11);
  	hash += (hash << 15);
  
  	return hash % size;
  }
  
  
  /* compares address and vid of two backbone gws */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
73
74
  static int batadv_compare_backbone_gw(const struct hlist_node *node,
  				      const void *data2)
23721387c   Simon Wunderlich   batman-adv: add b...
75
  {
bae987747   Marek Lindner   batman-adv: renam...
76
  	const void *data1 = container_of(node, struct batadv_bla_backbone_gw,
23721387c   Simon Wunderlich   batman-adv: add b...
77
  					 hash_entry);
bae987747   Marek Lindner   batman-adv: renam...
78
  	const struct batadv_bla_backbone_gw *gw1 = data1, *gw2 = data2;
23721387c   Simon Wunderlich   batman-adv: add b...
79

c76d15253   Simon Wunderlich   batman-adv: fix b...
80
81
82
83
84
85
86
  	if (!batadv_compare_eth(gw1->orig, gw2->orig))
  		return 0;
  
  	if (gw1->vid != gw2->vid)
  		return 0;
  
  	return 1;
23721387c   Simon Wunderlich   batman-adv: add b...
87
88
89
  }
  
  /* compares address and vid of two claims */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
90
91
  static int batadv_compare_claim(const struct hlist_node *node,
  				const void *data2)
23721387c   Simon Wunderlich   batman-adv: add b...
92
  {
712bbfe46   Marek Lindner   batman-adv: renam...
93
  	const void *data1 = container_of(node, struct batadv_bla_claim,
23721387c   Simon Wunderlich   batman-adv: add b...
94
  					 hash_entry);
712bbfe46   Marek Lindner   batman-adv: renam...
95
  	const struct batadv_bla_claim *cl1 = data1, *cl2 = data2;
c76d15253   Simon Wunderlich   batman-adv: fix b...
96
97
98
99
100
101
  
  	if (!batadv_compare_eth(cl1->addr, cl2->addr))
  		return 0;
  
  	if (cl1->vid != cl2->vid)
  		return 0;
23721387c   Simon Wunderlich   batman-adv: add b...
102

c76d15253   Simon Wunderlich   batman-adv: fix b...
103
  	return 1;
23721387c   Simon Wunderlich   batman-adv: add b...
104
105
106
  }
  
  /* free a backbone gw */
bae987747   Marek Lindner   batman-adv: renam...
107
108
  static void
  batadv_backbone_gw_free_ref(struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
109
110
111
112
113
114
  {
  	if (atomic_dec_and_test(&backbone_gw->refcount))
  		kfree_rcu(backbone_gw, rcu);
  }
  
  /* finally deinitialize the claim */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
115
  static void batadv_claim_free_rcu(struct rcu_head *rcu)
23721387c   Simon Wunderlich   batman-adv: add b...
116
  {
712bbfe46   Marek Lindner   batman-adv: renam...
117
  	struct batadv_bla_claim *claim;
23721387c   Simon Wunderlich   batman-adv: add b...
118

712bbfe46   Marek Lindner   batman-adv: renam...
119
  	claim = container_of(rcu, struct batadv_bla_claim, rcu);
23721387c   Simon Wunderlich   batman-adv: add b...
120

3b300de32   Sven Eckelmann   batman-adv: Prefi...
121
  	batadv_backbone_gw_free_ref(claim->backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
122
123
124
125
  	kfree(claim);
  }
  
  /* free a claim, call claim_free_rcu if its the last reference */
712bbfe46   Marek Lindner   batman-adv: renam...
126
  static void batadv_claim_free_ref(struct batadv_bla_claim *claim)
23721387c   Simon Wunderlich   batman-adv: add b...
127
128
  {
  	if (atomic_dec_and_test(&claim->refcount))
3b300de32   Sven Eckelmann   batman-adv: Prefi...
129
  		call_rcu(&claim->rcu, batadv_claim_free_rcu);
23721387c   Simon Wunderlich   batman-adv: add b...
130
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
131
132
133
  /**
   * batadv_claim_hash_find
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
134
135
136
137
138
   * @data: search data (may be local/static data)
   *
   * looks for a claim in the hash, and returns it if found
   * or NULL otherwise.
   */
712bbfe46   Marek Lindner   batman-adv: renam...
139
140
141
  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...
142
  {
807736f6e   Sven Eckelmann   batman-adv: Split...
143
  	struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
144
  	struct hlist_head *head;
712bbfe46   Marek Lindner   batman-adv: renam...
145
146
  	struct batadv_bla_claim *claim;
  	struct batadv_bla_claim *claim_tmp = NULL;
23721387c   Simon Wunderlich   batman-adv: add b...
147
148
149
150
  	int index;
  
  	if (!hash)
  		return NULL;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
151
  	index = batadv_choose_claim(data, hash->size);
23721387c   Simon Wunderlich   batman-adv: add b...
152
153
154
  	head = &hash->table[index];
  
  	rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
155
  	hlist_for_each_entry_rcu(claim, head, hash_entry) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
156
  		if (!batadv_compare_claim(&claim->hash_entry, data))
23721387c   Simon Wunderlich   batman-adv: add b...
157
158
159
160
161
162
163
164
165
166
167
168
  			continue;
  
  		if (!atomic_inc_not_zero(&claim->refcount))
  			continue;
  
  		claim_tmp = claim;
  		break;
  	}
  	rcu_read_unlock();
  
  	return claim_tmp;
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
169
170
171
  /**
   * batadv_backbone_hash_find - looks for a claim in the hash
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
172
173
174
   * @addr: the address of the originator
   * @vid: the VLAN ID
   *
2c53040f0   Ben Hutchings   net: Fix (nearly-...
175
   * Returns claim if found or NULL otherwise.
23721387c   Simon Wunderlich   batman-adv: add b...
176
   */
bae987747   Marek Lindner   batman-adv: renam...
177
  static struct batadv_bla_backbone_gw *
56303d34a   Sven Eckelmann   batman-adv: Prefi...
178
  batadv_backbone_hash_find(struct batadv_priv *bat_priv,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
179
  			  uint8_t *addr, unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
180
  {
807736f6e   Sven Eckelmann   batman-adv: Split...
181
  	struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
182
  	struct hlist_head *head;
bae987747   Marek Lindner   batman-adv: renam...
183
184
  	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...
185
186
187
188
  	int index;
  
  	if (!hash)
  		return NULL;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
189
  	ether_addr_copy(search_entry.orig, addr);
23721387c   Simon Wunderlich   batman-adv: add b...
190
  	search_entry.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
191
  	index = batadv_choose_backbone_gw(&search_entry, hash->size);
23721387c   Simon Wunderlich   batman-adv: add b...
192
193
194
  	head = &hash->table[index];
  
  	rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
195
  	hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
196
197
  		if (!batadv_compare_backbone_gw(&backbone_gw->hash_entry,
  						&search_entry))
23721387c   Simon Wunderlich   batman-adv: add b...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
  			continue;
  
  		if (!atomic_inc_not_zero(&backbone_gw->refcount))
  			continue;
  
  		backbone_gw_tmp = backbone_gw;
  		break;
  	}
  	rcu_read_unlock();
  
  	return backbone_gw_tmp;
  }
  
  /* delete all claims for a backbone */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
212
  static void
bae987747   Marek Lindner   batman-adv: renam...
213
  batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
214
  {
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
215
  	struct batadv_hashtable *hash;
b67bfe0d4   Sasha Levin   hlist: drop the n...
216
  	struct hlist_node *node_tmp;
23721387c   Simon Wunderlich   batman-adv: add b...
217
  	struct hlist_head *head;
712bbfe46   Marek Lindner   batman-adv: renam...
218
  	struct batadv_bla_claim *claim;
23721387c   Simon Wunderlich   batman-adv: add b...
219
220
  	int i;
  	spinlock_t *list_lock;	/* protects write access to the hash lists */
807736f6e   Sven Eckelmann   batman-adv: Split...
221
  	hash = backbone_gw->bat_priv->bla.claim_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
222
223
224
225
226
227
228
229
  	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...
230
  		hlist_for_each_entry_safe(claim, node_tmp,
23721387c   Simon Wunderlich   batman-adv: add b...
231
  					  head, hash_entry) {
23721387c   Simon Wunderlich   batman-adv: add b...
232
233
  			if (claim->backbone_gw != backbone_gw)
  				continue;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
234
  			batadv_claim_free_ref(claim);
b67bfe0d4   Sasha Levin   hlist: drop the n...
235
  			hlist_del_rcu(&claim->hash_entry);
23721387c   Simon Wunderlich   batman-adv: add b...
236
237
238
239
240
  		}
  		spin_unlock_bh(list_lock);
  	}
  
  	/* all claims gone, intialize CRC */
3964f7285   Sven Eckelmann   batman-adv: Prefi...
241
  	backbone_gw->crc = BATADV_BLA_CRC_INIT;
23721387c   Simon Wunderlich   batman-adv: add b...
242
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
243
244
245
  /**
   * batadv_bla_send_claim - sends a claim frame according to the provided info
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
246
247
248
   * @orig: the mac address to be announced within the claim
   * @vid: the VLAN ID
   * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...)
23721387c   Simon Wunderlich   batman-adv: add b...
249
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
250
  static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
251
  				  unsigned short vid, int claimtype)
23721387c   Simon Wunderlich   batman-adv: add b...
252
253
254
  {
  	struct sk_buff *skb;
  	struct ethhdr *ethhdr;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
255
  	struct batadv_hard_iface *primary_if;
23721387c   Simon Wunderlich   batman-adv: add b...
256
257
  	struct net_device *soft_iface;
  	uint8_t *hw_src;
964126901   Sven Eckelmann   batman-adv: Prefi...
258
  	struct batadv_bla_claim_dst local_claim_dest;
3e2f1a1bb   Al Viro   batman-adv: trivi...
259
  	__be32 zeroip = 0;
23721387c   Simon Wunderlich   batman-adv: add b...
260

e5d89254b   Sven Eckelmann   batman-adv: Prefi...
261
  	primary_if = batadv_primary_if_get_selected(bat_priv);
23721387c   Simon Wunderlich   batman-adv: add b...
262
263
  	if (!primary_if)
  		return;
807736f6e   Sven Eckelmann   batman-adv: Split...
264
  	memcpy(&local_claim_dest, &bat_priv->bla.claim_dest,
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
265
  	       sizeof(local_claim_dest));
23721387c   Simon Wunderlich   batman-adv: add b...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
  	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...
280
  			 /* HW DST: FF:43:05:XX:YY:YY
23721387c   Simon Wunderlich   batman-adv: add b...
281
  			  * with XX   = claim type
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
282
  			  * and YY:YY = group id
23721387c   Simon Wunderlich   batman-adv: add b...
283
284
285
286
287
288
289
  			  */
  			 (uint8_t *)&local_claim_dest);
  
  	if (!skb)
  		goto out;
  
  	ethhdr = (struct ethhdr *)skb->data;
0d125074e   Antonio Quartulli   batman-adv: use E...
290
  	hw_src = (uint8_t *)ethhdr + ETH_HLEN + sizeof(struct arphdr);
23721387c   Simon Wunderlich   batman-adv: add b...
291
292
293
  
  	/* now we pretend that the client would have sent this ... */
  	switch (claimtype) {
3eb8773e3   Simon Wunderlich   batman-adv: renam...
294
  	case BATADV_CLAIM_TYPE_CLAIM:
23721387c   Simon Wunderlich   batman-adv: add b...
295
296
297
  		/* normal claim frame
  		 * set Ethernet SRC to the clients mac
  		 */
8fdd01530   Antonio Quartulli   batman-adv: prefe...
298
  		ether_addr_copy(ethhdr->h_source, mac);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
299
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
5f80df670   Antonio Quartulli   batman-adv: print...
300
301
302
  			   "bla_send_claim(): CLAIM %pM on vid %d
  ", mac,
  			   BATADV_PRINT_VID(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
303
  		break;
3eb8773e3   Simon Wunderlich   batman-adv: renam...
304
  	case BATADV_CLAIM_TYPE_UNCLAIM:
23721387c   Simon Wunderlich   batman-adv: add b...
305
306
307
  		/* unclaim frame
  		 * set HW SRC to the clients mac
  		 */
8fdd01530   Antonio Quartulli   batman-adv: prefe...
308
  		ether_addr_copy(hw_src, mac);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
309
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
310
311
  			   "bla_send_claim(): UNCLAIM %pM on vid %d
  ", mac,
5f80df670   Antonio Quartulli   batman-adv: print...
312
  			   BATADV_PRINT_VID(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
313
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
314
  	case BATADV_CLAIM_TYPE_ANNOUNCE:
23721387c   Simon Wunderlich   batman-adv: add b...
315
316
317
  		/* announcement frame
  		 * set HW SRC to the special mac containg the crc
  		 */
8fdd01530   Antonio Quartulli   batman-adv: prefe...
318
  		ether_addr_copy(hw_src, mac);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
319
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
320
321
  			   "bla_send_claim(): ANNOUNCE of %pM on vid %d
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
322
  			   ethhdr->h_source, BATADV_PRINT_VID(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
323
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
324
  	case BATADV_CLAIM_TYPE_REQUEST:
23721387c   Simon Wunderlich   batman-adv: add b...
325
  		/* request frame
99e966fc9   Simon Wunderlich   batman-adv: corre...
326
327
  		 * set HW SRC and header destination to the receiving backbone
  		 * gws mac
23721387c   Simon Wunderlich   batman-adv: add b...
328
  		 */
8fdd01530   Antonio Quartulli   batman-adv: prefe...
329
330
  		ether_addr_copy(hw_src, mac);
  		ether_addr_copy(ethhdr->h_dest, mac);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
331
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
332
333
  			   "bla_send_claim(): REQUEST of %pM to %pM on vid %d
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
334
335
  			   ethhdr->h_source, ethhdr->h_dest,
  			   BATADV_PRINT_VID(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
336
  		break;
23721387c   Simon Wunderlich   batman-adv: add b...
337
  	}
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
338
339
340
  	if (vid & BATADV_VLAN_HAS_TAG)
  		skb = vlan_insert_tag(skb, htons(ETH_P_8021Q),
  				      vid & VLAN_VID_MASK);
23721387c   Simon Wunderlich   batman-adv: add b...
341
342
343
  
  	skb_reset_mac_header(skb);
  	skb->protocol = eth_type_trans(skb, soft_iface);
1c9b0550f   Marek Lindner   batman-adv: conve...
344
345
346
  	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...
347
348
349
350
351
  	soft_iface->last_rx = jiffies;
  
  	netif_rx(skb);
  out:
  	if (primary_if)
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
352
  		batadv_hardif_free_ref(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
353
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
354
355
356
  /**
   * batadv_bla_get_backbone_gw
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
357
358
359
360
361
362
   * @orig: the mac address of the originator
   * @vid: the VLAN ID
   *
   * searches for the backbone gw or creates a new one if it could not
   * be found.
   */
bae987747   Marek Lindner   batman-adv: renam...
363
  static struct batadv_bla_backbone_gw *
56303d34a   Sven Eckelmann   batman-adv: Prefi...
364
  batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
365
  			   unsigned short vid, bool own_backbone)
23721387c   Simon Wunderlich   batman-adv: add b...
366
  {
bae987747   Marek Lindner   batman-adv: renam...
367
  	struct batadv_bla_backbone_gw *entry;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
368
  	struct batadv_orig_node *orig_node;
23721387c   Simon Wunderlich   batman-adv: add b...
369
  	int hash_added;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
370
  	entry = batadv_backbone_hash_find(bat_priv, orig, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
371
372
373
  
  	if (entry)
  		return entry;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
374
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
375
376
  		   "bla_get_backbone_gw(): not found (%pM, %d), creating new entry
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
377
  		   orig, BATADV_PRINT_VID(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
378
379
380
381
382
383
384
  
  	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
  	if (!entry)
  		return NULL;
  
  	entry->vid = vid;
  	entry->lasttime = jiffies;
3964f7285   Sven Eckelmann   batman-adv: Prefi...
385
  	entry->crc = BATADV_BLA_CRC_INIT;
23721387c   Simon Wunderlich   batman-adv: add b...
386
387
  	entry->bat_priv = bat_priv;
  	atomic_set(&entry->request_sent, 0);
28709878b   Simon Wunderlich   batman-adv: wait ...
388
  	atomic_set(&entry->wait_periods, 0);
8fdd01530   Antonio Quartulli   batman-adv: prefe...
389
  	ether_addr_copy(entry->orig, orig);
23721387c   Simon Wunderlich   batman-adv: add b...
390
391
392
  
  	/* one for the hash, one for returning */
  	atomic_set(&entry->refcount, 2);
807736f6e   Sven Eckelmann   batman-adv: Split...
393
  	hash_added = batadv_hash_add(bat_priv->bla.backbone_hash,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
394
395
396
  				     batadv_compare_backbone_gw,
  				     batadv_choose_backbone_gw, entry,
  				     &entry->hash_entry);
23721387c   Simon Wunderlich   batman-adv: add b...
397
398
399
400
401
402
  
  	if (unlikely(hash_added != 0)) {
  		/* hash failed, free the structure */
  		kfree(entry);
  		return NULL;
  	}
95fb130d6   Antonio Quartulli   batman-adv: make ...
403
  	/* this is a gateway now, remove any TT entry on this VLAN */
da641193d   Sven Eckelmann   batman-adv: Prefi...
404
  	orig_node = batadv_orig_hash_find(bat_priv, orig);
20ff9d593   Simon Wunderlich   batman-adv: don't...
405
  	if (orig_node) {
95fb130d6   Antonio Quartulli   batman-adv: make ...
406
  		batadv_tt_global_del_orig(bat_priv, orig_node, vid,
08c36d3e8   Sven Eckelmann   batman-adv: Prefi...
407
  					  "became a backbone gateway");
7d211efc5   Sven Eckelmann   batman-adv: Prefi...
408
  		batadv_orig_node_free_ref(orig_node);
20ff9d593   Simon Wunderlich   batman-adv: don't...
409
  	}
52aebd6a9   Simon Wunderlich   batman-adv: send ...
410

d807f2728   Simon Wunderlich   batman-adv: allow...
411
  	if (own_backbone) {
52aebd6a9   Simon Wunderlich   batman-adv: send ...
412
  		batadv_bla_send_announce(bat_priv, entry);
d807f2728   Simon Wunderlich   batman-adv: allow...
413
414
  		/* this will be decreased in the worker thread */
  		atomic_inc(&entry->request_sent);
28709878b   Simon Wunderlich   batman-adv: wait ...
415
  		atomic_set(&entry->wait_periods, BATADV_BLA_WAIT_PERIODS);
d807f2728   Simon Wunderlich   batman-adv: allow...
416
417
  		atomic_inc(&bat_priv->bla.num_requests);
  	}
23721387c   Simon Wunderlich   batman-adv: add b...
418
419
420
421
422
423
  	return entry;
  }
  
  /* update or add the own backbone gw to make sure we announce
   * where we receive other backbone gws
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
424
425
426
  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...
427
  				  unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
428
  {
bae987747   Marek Lindner   batman-adv: renam...
429
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
430

3b300de32   Sven Eckelmann   batman-adv: Prefi...
431
432
  	backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
  						 primary_if->net_dev->dev_addr,
52aebd6a9   Simon Wunderlich   batman-adv: send ...
433
  						 vid, true);
23721387c   Simon Wunderlich   batman-adv: add b...
434
435
436
437
  	if (unlikely(!backbone_gw))
  		return;
  
  	backbone_gw->lasttime = jiffies;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
438
  	batadv_backbone_gw_free_ref(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
439
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
440
441
442
  /**
   * batadv_bla_answer_request - answer a bla request by sending own claims
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
443
444
445
446
447
   * @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...
448
449
  static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
  				      struct batadv_hard_iface *primary_if,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
450
  				      unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
451
  {
23721387c   Simon Wunderlich   batman-adv: add b...
452
  	struct hlist_head *head;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
453
  	struct batadv_hashtable *hash;
712bbfe46   Marek Lindner   batman-adv: renam...
454
  	struct batadv_bla_claim *claim;
bae987747   Marek Lindner   batman-adv: renam...
455
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
456
  	int i;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
457
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
458
459
  		   "bla_answer_request(): received a claim request, send all of our own claims again
  ");
23721387c   Simon Wunderlich   batman-adv: add b...
460

3b300de32   Sven Eckelmann   batman-adv: Prefi...
461
462
463
  	backbone_gw = batadv_backbone_hash_find(bat_priv,
  						primary_if->net_dev->dev_addr,
  						vid);
23721387c   Simon Wunderlich   batman-adv: add b...
464
465
  	if (!backbone_gw)
  		return;
807736f6e   Sven Eckelmann   batman-adv: Split...
466
  	hash = bat_priv->bla.claim_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
467
468
469
470
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
471
  		hlist_for_each_entry_rcu(claim, head, hash_entry) {
23721387c   Simon Wunderlich   batman-adv: add b...
472
473
474
  			/* only own claims are interesting */
  			if (claim->backbone_gw != backbone_gw)
  				continue;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
475
  			batadv_bla_send_claim(bat_priv, claim->addr, claim->vid,
3eb8773e3   Simon Wunderlich   batman-adv: renam...
476
  					      BATADV_CLAIM_TYPE_CLAIM);
23721387c   Simon Wunderlich   batman-adv: add b...
477
478
479
480
481
  		}
  		rcu_read_unlock();
  	}
  
  	/* finally, send an announcement frame */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
482
483
  	batadv_bla_send_announce(bat_priv, backbone_gw);
  	batadv_backbone_gw_free_ref(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
484
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
485
486
487
  /**
   * batadv_bla_send_request - send a request to repeat claims
   * @backbone_gw: the backbone gateway from whom we are out of sync
23721387c   Simon Wunderlich   batman-adv: add b...
488
489
490
491
492
   *
   * 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...
493
  static void batadv_bla_send_request(struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
494
495
  {
  	/* first, remove all old entries */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
496
  	batadv_bla_del_backbone_claims(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
497

39c75a51e   Sven Eckelmann   batman-adv: Prefi...
498
499
500
  	batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
  		   "Sending REQUEST to %pM
  ", backbone_gw->orig);
23721387c   Simon Wunderlich   batman-adv: add b...
501
502
  
  	/* send request */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
503
  	batadv_bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig,
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
504
  			      backbone_gw->vid, BATADV_CLAIM_TYPE_REQUEST);
23721387c   Simon Wunderlich   batman-adv: add b...
505
506
507
  
  	/* no local broadcasts should be sent or received, for now. */
  	if (!atomic_read(&backbone_gw->request_sent)) {
807736f6e   Sven Eckelmann   batman-adv: Split...
508
  		atomic_inc(&backbone_gw->bat_priv->bla.num_requests);
23721387c   Simon Wunderlich   batman-adv: add b...
509
510
511
  		atomic_set(&backbone_gw->request_sent, 1);
  	}
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
512
513
514
  /**
   * batadv_bla_send_announce
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
515
516
517
518
519
   * @backbone_gw: our backbone gateway which should be announced
   *
   * This function sends an announcement. It is called from multiple
   * places.
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
520
  static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
bae987747   Marek Lindner   batman-adv: renam...
521
  				     struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
522
523
  {
  	uint8_t mac[ETH_ALEN];
3e2f1a1bb   Al Viro   batman-adv: trivi...
524
  	__be16 crc;
23721387c   Simon Wunderlich   batman-adv: add b...
525

3b300de32   Sven Eckelmann   batman-adv: Prefi...
526
  	memcpy(mac, batadv_announce_mac, 4);
23721387c   Simon Wunderlich   batman-adv: add b...
527
  	crc = htons(backbone_gw->crc);
1a5852d81   Al Viro   batman-adv: get r...
528
  	memcpy(&mac[4], &crc, 2);
23721387c   Simon Wunderlich   batman-adv: add b...
529

3b300de32   Sven Eckelmann   batman-adv: Prefi...
530
  	batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
531
  			      BATADV_CLAIM_TYPE_ANNOUNCE);
23721387c   Simon Wunderlich   batman-adv: add b...
532
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
533
534
535
  /**
   * batadv_bla_add_claim - Adds a claim in the claim hash
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
536
537
538
   * @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...
539
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
540
  static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
541
  				 const uint8_t *mac, const unsigned short vid,
bae987747   Marek Lindner   batman-adv: renam...
542
  				 struct batadv_bla_backbone_gw *backbone_gw)
23721387c   Simon Wunderlich   batman-adv: add b...
543
  {
712bbfe46   Marek Lindner   batman-adv: renam...
544
545
  	struct batadv_bla_claim *claim;
  	struct batadv_bla_claim search_claim;
23721387c   Simon Wunderlich   batman-adv: add b...
546
  	int hash_added;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
547
  	ether_addr_copy(search_claim.addr, mac);
23721387c   Simon Wunderlich   batman-adv: add b...
548
  	search_claim.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
549
  	claim = batadv_claim_hash_find(bat_priv, &search_claim);
23721387c   Simon Wunderlich   batman-adv: add b...
550
551
552
553
554
555
  
  	/* 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...
556
  		ether_addr_copy(claim->addr, mac);
23721387c   Simon Wunderlich   batman-adv: add b...
557
558
559
560
561
  		claim->vid = vid;
  		claim->lasttime = jiffies;
  		claim->backbone_gw = backbone_gw;
  
  		atomic_set(&claim->refcount, 2);
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
562
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
563
564
  			   "bla_add_claim(): adding new entry %pM, vid %d to hash ...
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
565
  			   mac, BATADV_PRINT_VID(vid));
807736f6e   Sven Eckelmann   batman-adv: Split...
566
  		hash_added = batadv_hash_add(bat_priv->bla.claim_hash,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
567
568
569
  					     batadv_compare_claim,
  					     batadv_choose_claim, claim,
  					     &claim->hash_entry);
23721387c   Simon Wunderlich   batman-adv: add b...
570
571
572
573
574
575
576
577
578
579
580
  
  		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...
581
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
582
583
  			   "bla_add_claim(): changing ownership for %pM, vid %d
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
584
  			   mac, BATADV_PRINT_VID(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
585

bbb1f90ef   Sven Eckelmann   batman-adv: Don't...
586
  		claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
3b300de32   Sven Eckelmann   batman-adv: Prefi...
587
  		batadv_backbone_gw_free_ref(claim->backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
588
589
590
591
592
593
594
595
596
  	}
  	/* set (new) backbone gw */
  	atomic_inc(&backbone_gw->refcount);
  	claim->backbone_gw = backbone_gw;
  
  	backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
  	backbone_gw->lasttime = jiffies;
  
  claim_free_ref:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
597
  	batadv_claim_free_ref(claim);
23721387c   Simon Wunderlich   batman-adv: add b...
598
599
600
601
602
  }
  
  /* Delete a claim from the claim hash which has the
   * given mac address and vid.
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
603
  static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
604
  				 const uint8_t *mac, const unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
605
  {
712bbfe46   Marek Lindner   batman-adv: renam...
606
  	struct batadv_bla_claim search_claim, *claim;
23721387c   Simon Wunderlich   batman-adv: add b...
607

8fdd01530   Antonio Quartulli   batman-adv: prefe...
608
  	ether_addr_copy(search_claim.addr, mac);
23721387c   Simon Wunderlich   batman-adv: add b...
609
  	search_claim.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
610
  	claim = batadv_claim_hash_find(bat_priv, &search_claim);
23721387c   Simon Wunderlich   batman-adv: add b...
611
612
  	if (!claim)
  		return;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
613
614
  	batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
615
  		   mac, BATADV_PRINT_VID(vid));
23721387c   Simon Wunderlich   batman-adv: add b...
616

807736f6e   Sven Eckelmann   batman-adv: Split...
617
  	batadv_hash_remove(bat_priv->bla.claim_hash, batadv_compare_claim,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
618
619
  			   batadv_choose_claim, claim);
  	batadv_claim_free_ref(claim); /* reference from the hash is gone */
23721387c   Simon Wunderlich   batman-adv: add b...
620
621
622
623
  
  	claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
  
  	/* don't need the reference from hash_find() anymore */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
624
  	batadv_claim_free_ref(claim);
23721387c   Simon Wunderlich   batman-adv: add b...
625
626
627
  }
  
  /* check for ANNOUNCE frame, return 1 if handled */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
628
  static int batadv_handle_announce(struct batadv_priv *bat_priv,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
629
  				  uint8_t *an_addr, uint8_t *backbone_addr,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
630
  				  unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
631
  {
bae987747   Marek Lindner   batman-adv: renam...
632
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
633
  	uint16_t crc;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
634
  	if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
23721387c   Simon Wunderlich   batman-adv: add b...
635
  		return 0;
52aebd6a9   Simon Wunderlich   batman-adv: send ...
636
637
  	backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
  						 false);
23721387c   Simon Wunderlich   batman-adv: add b...
638
639
640
641
642
643
644
  
  	if (unlikely(!backbone_gw))
  		return 1;
  
  
  	/* handle as ANNOUNCE frame */
  	backbone_gw->lasttime = jiffies;
3e2f1a1bb   Al Viro   batman-adv: trivi...
645
  	crc = ntohs(*((__be16 *)(&an_addr[4])));
23721387c   Simon Wunderlich   batman-adv: add b...
646

39c75a51e   Sven Eckelmann   batman-adv: Prefi...
647
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
39a329915   Antonio Quartulli   batman-adv: unify...
648
649
  		   "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
650
  		   BATADV_PRINT_VID(vid), backbone_gw->orig, crc);
23721387c   Simon Wunderlich   batman-adv: add b...
651
652
  
  	if (backbone_gw->crc != crc) {
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
653
  		batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
39a329915   Antonio Quartulli   batman-adv: unify...
654
655
  			   "handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
656
657
  			   backbone_gw->orig,
  			   BATADV_PRINT_VID(backbone_gw->vid),
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
658
  			   backbone_gw->crc, crc);
23721387c   Simon Wunderlich   batman-adv: add b...
659

3b300de32   Sven Eckelmann   batman-adv: Prefi...
660
  		batadv_bla_send_request(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
661
662
663
664
665
  	} 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...
666
  			atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
23721387c   Simon Wunderlich   batman-adv: add b...
667
668
669
  			atomic_set(&backbone_gw->request_sent, 0);
  		}
  	}
3b300de32   Sven Eckelmann   batman-adv: Prefi...
670
  	batadv_backbone_gw_free_ref(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
671
672
673
674
  	return 1;
  }
  
  /* check for REQUEST frame, return 1 if handled */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
675
676
  static int batadv_handle_request(struct batadv_priv *bat_priv,
  				 struct batadv_hard_iface *primary_if,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
677
  				 uint8_t *backbone_addr,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
678
  				 struct ethhdr *ethhdr, unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
679
680
  {
  	/* check for REQUEST frame */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
681
  	if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest))
23721387c   Simon Wunderlich   batman-adv: add b...
682
683
684
685
686
  		return 0;
  
  	/* sanity check, this should not happen on a normal switch,
  	 * we ignore it in this case.
  	 */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
687
  	if (!batadv_compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr))
23721387c   Simon Wunderlich   batman-adv: add b...
688
  		return 1;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
689
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
690
691
  		   "handle_request(): REQUEST vid %d (sent by %pM)...
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
692
  		   BATADV_PRINT_VID(vid), ethhdr->h_source);
23721387c   Simon Wunderlich   batman-adv: add b...
693

3b300de32   Sven Eckelmann   batman-adv: Prefi...
694
  	batadv_bla_answer_request(bat_priv, primary_if, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
695
696
697
698
  	return 1;
  }
  
  /* check for UNCLAIM frame, return 1 if handled */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
699
700
  static int batadv_handle_unclaim(struct batadv_priv *bat_priv,
  				 struct batadv_hard_iface *primary_if,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
701
  				 uint8_t *backbone_addr,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
702
  				 uint8_t *claim_addr, unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
703
  {
bae987747   Marek Lindner   batman-adv: renam...
704
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
705
706
  
  	/* unclaim in any case if it is our own */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
707
708
  	if (primary_if && batadv_compare_eth(backbone_addr,
  					     primary_if->net_dev->dev_addr))
3b300de32   Sven Eckelmann   batman-adv: Prefi...
709
  		batadv_bla_send_claim(bat_priv, claim_addr, vid,
3eb8773e3   Simon Wunderlich   batman-adv: renam...
710
  				      BATADV_CLAIM_TYPE_UNCLAIM);
23721387c   Simon Wunderlich   batman-adv: add b...
711

3b300de32   Sven Eckelmann   batman-adv: Prefi...
712
  	backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
713
714
715
716
717
  
  	if (!backbone_gw)
  		return 1;
  
  	/* this must be an UNCLAIM frame */
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
718
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
719
720
  		   "handle_unclaim(): UNCLAIM %pM on vid %d (sent by %pM)...
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
721
  		   claim_addr, BATADV_PRINT_VID(vid), backbone_gw->orig);
23721387c   Simon Wunderlich   batman-adv: add b...
722

3b300de32   Sven Eckelmann   batman-adv: Prefi...
723
724
  	batadv_bla_del_claim(bat_priv, claim_addr, vid);
  	batadv_backbone_gw_free_ref(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
725
726
727
728
  	return 1;
  }
  
  /* check for CLAIM frame, return 1 if handled */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
729
730
  static int batadv_handle_claim(struct batadv_priv *bat_priv,
  			       struct batadv_hard_iface *primary_if,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
731
  			       uint8_t *backbone_addr, uint8_t *claim_addr,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
732
  			       unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
733
  {
bae987747   Marek Lindner   batman-adv: renam...
734
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
735
736
  
  	/* register the gateway if not yet available, and add the claim. */
52aebd6a9   Simon Wunderlich   batman-adv: send ...
737
738
  	backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
  						 false);
23721387c   Simon Wunderlich   batman-adv: add b...
739
740
741
742
743
  
  	if (unlikely(!backbone_gw))
  		return 1;
  
  	/* this must be a CLAIM frame */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
744
  	batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw);
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
745
  	if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
3b300de32   Sven Eckelmann   batman-adv: Prefi...
746
  		batadv_bla_send_claim(bat_priv, claim_addr, vid,
3eb8773e3   Simon Wunderlich   batman-adv: renam...
747
  				      BATADV_CLAIM_TYPE_CLAIM);
23721387c   Simon Wunderlich   batman-adv: add b...
748
749
  
  	/* TODO: we could call something like tt_local_del() here. */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
750
  	batadv_backbone_gw_free_ref(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
751
752
  	return 1;
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
753
754
755
  /**
   * batadv_check_claim_group
   * @bat_priv: the bat priv with all the soft interface information
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
756
757
758
759
760
761
762
763
764
765
766
767
768
   * @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
   *
   * checks if it is a claim packet and if its on the same group.
   * This function also applies the group ID of the sender
   * if it is in the same mesh.
   *
   * returns:
   *	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...
769
770
  static int batadv_check_claim_group(struct batadv_priv *bat_priv,
  				    struct batadv_hard_iface *primary_if,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
771
772
  				    uint8_t *hw_src, uint8_t *hw_dst,
  				    struct ethhdr *ethhdr)
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
773
774
  {
  	uint8_t *backbone_addr;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
775
  	struct batadv_orig_node *orig_node;
964126901   Sven Eckelmann   batman-adv: Prefi...
776
  	struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
777

964126901   Sven Eckelmann   batman-adv: Prefi...
778
  	bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
807736f6e   Sven Eckelmann   batman-adv: Split...
779
  	bla_dst_own = &bat_priv->bla.claim_dest;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
780
781
782
783
784
785
786
787
788
789
  
  	/* check if it is a claim packet in general */
  	if (memcmp(bla_dst->magic, bla_dst_own->magic,
  		   sizeof(bla_dst->magic)) != 0)
  		return 0;
  
  	/* if announcement packet, use the source,
  	 * otherwise assume it is in the hw_src
  	 */
  	switch (bla_dst->type) {
3eb8773e3   Simon Wunderlich   batman-adv: renam...
790
  	case BATADV_CLAIM_TYPE_CLAIM:
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
791
792
  		backbone_addr = hw_src;
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
793
794
  	case BATADV_CLAIM_TYPE_REQUEST:
  	case BATADV_CLAIM_TYPE_ANNOUNCE:
3eb8773e3   Simon Wunderlich   batman-adv: renam...
795
  	case BATADV_CLAIM_TYPE_UNCLAIM:
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
796
797
798
799
800
801
802
  		backbone_addr = ethhdr->h_source;
  		break;
  	default:
  		return 0;
  	}
  
  	/* don't accept claim frames from ourselves */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
803
  	if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
804
805
806
807
808
809
810
  		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...
811
  	orig_node = batadv_orig_hash_find(bat_priv, backbone_addr);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
812
813
814
815
816
817
818
819
820
  
  	/* 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...
821
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
39a329915   Antonio Quartulli   batman-adv: unify...
822
823
  			   "taking other backbones claim group: %#.4x
  ",
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
824
  			   ntohs(bla_dst->group));
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
825
826
  		bla_dst_own->group = bla_dst->group;
  	}
7d211efc5   Sven Eckelmann   batman-adv: Prefi...
827
  	batadv_orig_node_free_ref(orig_node);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
828
829
830
  
  	return 2;
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
831
832
833
  /**
   * batadv_bla_process_claim
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
834
835
836
837
838
839
840
   * @skb: the frame to be checked
   *
   * Check if this is a claim frame, and process it accordingly.
   *
   * returns 1 if it was a claim frame, otherwise return 0 to
   * tell the callee that it can use the frame on its own.
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
841
842
  static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
  				    struct batadv_hard_iface *primary_if,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
843
  				    struct sk_buff *skb)
23721387c   Simon Wunderlich   batman-adv: add b...
844
  {
c018ad3de   Antonio Quartulli   batman-adv: add t...
845
846
  	struct batadv_bla_claim_dst *bla_dst;
  	uint8_t *hw_src, *hw_dst;
23721387c   Simon Wunderlich   batman-adv: add b...
847
  	struct vlan_ethhdr *vhdr;
c018ad3de   Antonio Quartulli   batman-adv: add t...
848
  	struct ethhdr *ethhdr;
23721387c   Simon Wunderlich   batman-adv: add b...
849
  	struct arphdr *arphdr;
c018ad3de   Antonio Quartulli   batman-adv: add t...
850
  	unsigned short vid;
293e93385   Antonio Quartulli   batman-adv: use h...
851
  	__be16 proto;
23721387c   Simon Wunderlich   batman-adv: add b...
852
  	int headlen;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
853
  	int ret;
23721387c   Simon Wunderlich   batman-adv: add b...
854

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

c018ad3de   Antonio Quartulli   batman-adv: add t...
858
859
860
  	proto = ethhdr->h_proto;
  	headlen = ETH_HLEN;
  	if (vid & BATADV_VLAN_HAS_TAG) {
927c2ed7e   Linus Lüssing   batman-adv: use v...
861
  		vhdr = vlan_eth_hdr(skb);
293e93385   Antonio Quartulli   batman-adv: use h...
862
  		proto = vhdr->h_vlan_encapsulated_proto;
c018ad3de   Antonio Quartulli   batman-adv: add t...
863
  		headlen += VLAN_HLEN;
23721387c   Simon Wunderlich   batman-adv: add b...
864
  	}
293e93385   Antonio Quartulli   batman-adv: use h...
865
  	if (proto != htons(ETH_P_ARP))
23721387c   Simon Wunderlich   batman-adv: add b...
866
867
868
869
870
871
872
873
  		return 0; /* not a claim frame */
  
  	/* this must be a ARP frame. check if it is a claim. */
  
  	if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev))))
  		return 0;
  
  	/* pskb_may_pull() may have modified the pointers, get ethhdr again */
7ed4be952   Antonio Quartulli   batman-adv: use e...
874
  	ethhdr = eth_hdr(skb);
23721387c   Simon Wunderlich   batman-adv: add b...
875
876
877
878
879
  	arphdr = (struct arphdr *)((uint8_t *)ethhdr + headlen);
  
  	/* Check whether the ARP frame carries a valid
  	 * IP information
  	 */
23721387c   Simon Wunderlich   batman-adv: add b...
880
881
882
883
884
885
886
887
888
889
890
  	if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
  		return 0;
  	if (arphdr->ar_pro != htons(ETH_P_IP))
  		return 0;
  	if (arphdr->ar_hln != ETH_ALEN)
  		return 0;
  	if (arphdr->ar_pln != 4)
  		return 0;
  
  	hw_src = (uint8_t *)arphdr + sizeof(struct arphdr);
  	hw_dst = hw_src + ETH_ALEN + 4;
964126901   Sven Eckelmann   batman-adv: Prefi...
891
  	bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
23721387c   Simon Wunderlich   batman-adv: add b...
892
893
  
  	/* check if it is a claim frame. */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
894
895
  	ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst,
  				       ethhdr);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
896
  	if (ret == 1)
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
897
  		batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
898
899
  			   "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
900
901
  			   ethhdr->h_source, BATADV_PRINT_VID(vid), hw_src,
  			   hw_dst);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
902
903
904
  
  	if (ret < 2)
  		return ret;
23721387c   Simon Wunderlich   batman-adv: add b...
905
906
  
  	/* become a backbone gw ourselves on this vlan if not happened yet */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
907
  	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
908
909
910
  
  	/* check for the different types of claim frames ... */
  	switch (bla_dst->type) {
3eb8773e3   Simon Wunderlich   batman-adv: renam...
911
  	case BATADV_CLAIM_TYPE_CLAIM:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
912
913
  		if (batadv_handle_claim(bat_priv, primary_if, hw_src,
  					ethhdr->h_source, vid))
23721387c   Simon Wunderlich   batman-adv: add b...
914
915
  			return 1;
  		break;
3eb8773e3   Simon Wunderlich   batman-adv: renam...
916
  	case BATADV_CLAIM_TYPE_UNCLAIM:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
917
918
  		if (batadv_handle_unclaim(bat_priv, primary_if,
  					  ethhdr->h_source, hw_src, vid))
23721387c   Simon Wunderlich   batman-adv: add b...
919
920
  			return 1;
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
921
  	case BATADV_CLAIM_TYPE_ANNOUNCE:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
922
923
  		if (batadv_handle_announce(bat_priv, hw_src, ethhdr->h_source,
  					   vid))
23721387c   Simon Wunderlich   batman-adv: add b...
924
925
  			return 1;
  		break;
acd34afa8   Sven Eckelmann   batman-adv: Prefi...
926
  	case BATADV_CLAIM_TYPE_REQUEST:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
927
928
  		if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr,
  					  vid))
23721387c   Simon Wunderlich   batman-adv: add b...
929
930
931
  			return 1;
  		break;
  	}
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
932
  	batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
933
934
  		   "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
935
  		   ethhdr->h_source, BATADV_PRINT_VID(vid), hw_src, hw_dst);
23721387c   Simon Wunderlich   batman-adv: add b...
936
937
938
939
940
941
  	return 1;
  }
  
  /* Check when we last heard from other nodes, and remove them in case of
   * a time out, or clean all backbone gws if now is set.
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
942
  static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
23721387c   Simon Wunderlich   batman-adv: add b...
943
  {
bae987747   Marek Lindner   batman-adv: renam...
944
  	struct batadv_bla_backbone_gw *backbone_gw;
b67bfe0d4   Sasha Levin   hlist: drop the n...
945
  	struct hlist_node *node_tmp;
23721387c   Simon Wunderlich   batman-adv: add b...
946
  	struct hlist_head *head;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
947
  	struct batadv_hashtable *hash;
23721387c   Simon Wunderlich   batman-adv: add b...
948
949
  	spinlock_t *list_lock;	/* protects write access to the hash lists */
  	int i;
807736f6e   Sven Eckelmann   batman-adv: Split...
950
  	hash = bat_priv->bla.backbone_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
951
952
953
954
955
956
957
958
  	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...
959
  		hlist_for_each_entry_safe(backbone_gw, node_tmp,
23721387c   Simon Wunderlich   batman-adv: add b...
960
961
962
  					  head, hash_entry) {
  			if (now)
  				goto purge_now;
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
963
  			if (!batadv_has_timed_out(backbone_gw->lasttime,
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
964
  						  BATADV_BLA_BACKBONE_TIMEOUT))
23721387c   Simon Wunderlich   batman-adv: add b...
965
  				continue;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
966
  			batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
967
968
969
  				   "bla_purge_backbone_gw(): backbone gw %pM timed out
  ",
  				   backbone_gw->orig);
23721387c   Simon Wunderlich   batman-adv: add b...
970
971
972
973
  
  purge_now:
  			/* don't wait for the pending request anymore */
  			if (atomic_read(&backbone_gw->request_sent))
807736f6e   Sven Eckelmann   batman-adv: Split...
974
  				atomic_dec(&bat_priv->bla.num_requests);
23721387c   Simon Wunderlich   batman-adv: add b...
975

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

b67bfe0d4   Sasha Levin   hlist: drop the n...
978
  			hlist_del_rcu(&backbone_gw->hash_entry);
3b300de32   Sven Eckelmann   batman-adv: Prefi...
979
  			batadv_backbone_gw_free_ref(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
980
981
982
983
  		}
  		spin_unlock_bh(list_lock);
  	}
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
984
985
986
  /**
   * batadv_bla_purge_claims
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
987
988
989
990
991
992
   * @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...
993
994
995
  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...
996
  {
712bbfe46   Marek Lindner   batman-adv: renam...
997
  	struct batadv_bla_claim *claim;
23721387c   Simon Wunderlich   batman-adv: add b...
998
  	struct hlist_head *head;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
999
  	struct batadv_hashtable *hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1000
  	int i;
807736f6e   Sven Eckelmann   batman-adv: Split...
1001
  	hash = bat_priv->bla.claim_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1002
1003
1004
1005
1006
1007
1008
  	if (!hash)
  		return;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
1009
  		hlist_for_each_entry_rcu(claim, head, hash_entry) {
23721387c   Simon Wunderlich   batman-adv: add b...
1010
1011
  			if (now)
  				goto purge_now;
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1012
1013
  			if (!batadv_compare_eth(claim->backbone_gw->orig,
  						primary_if->net_dev->dev_addr))
23721387c   Simon Wunderlich   batman-adv: add b...
1014
  				continue;
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1015
  			if (!batadv_has_timed_out(claim->lasttime,
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1016
  						  BATADV_BLA_CLAIM_TIMEOUT))
23721387c   Simon Wunderlich   batman-adv: add b...
1017
  				continue;
39c75a51e   Sven Eckelmann   batman-adv: Prefi...
1018
  			batadv_dbg(BATADV_DBG_BLA, bat_priv,
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1019
1020
1021
  				   "bla_purge_claims(): %pM, vid %d, time out
  ",
  				   claim->addr, claim->vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1022
1023
  
  purge_now:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1024
1025
1026
  			batadv_handle_unclaim(bat_priv, primary_if,
  					      claim->backbone_gw->orig,
  					      claim->addr, claim->vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1027
1028
1029
1030
  		}
  		rcu_read_unlock();
  	}
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1031
1032
1033
  /**
   * batadv_bla_update_orig_address
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
1034
1035
1036
1037
   * @primary_if: the new selected primary_if
   * @oldif: the old primary interface, may be NULL
   *
   * Update the backbone gateways when the own orig address changes.
23721387c   Simon Wunderlich   batman-adv: add b...
1038
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1039
1040
1041
  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...
1042
  {
bae987747   Marek Lindner   batman-adv: renam...
1043
  	struct batadv_bla_backbone_gw *backbone_gw;
23721387c   Simon Wunderlich   batman-adv: add b...
1044
  	struct hlist_head *head;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
1045
  	struct batadv_hashtable *hash;
807736f6e   Sven Eckelmann   batman-adv: Split...
1046
  	__be16 group;
23721387c   Simon Wunderlich   batman-adv: add b...
1047
  	int i;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1048
  	/* reset bridge loop avoidance group id */
807736f6e   Sven Eckelmann   batman-adv: Split...
1049
1050
  	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 ...
1051

d5b4c93e6   Simon Wunderlich   batman-adv: Don't...
1052
1053
1054
  	/* 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...
1055
  	if (!oldif) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1056
1057
  		batadv_bla_purge_claims(bat_priv, NULL, 1);
  		batadv_bla_purge_backbone_gw(bat_priv, 1);
23721387c   Simon Wunderlich   batman-adv: add b...
1058
1059
  		return;
  	}
807736f6e   Sven Eckelmann   batman-adv: Split...
1060
  	hash = bat_priv->bla.backbone_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1061
1062
1063
1064
1065
1066
1067
  	if (!hash)
  		return;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
1068
  		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
23721387c   Simon Wunderlich   batman-adv: add b...
1069
  			/* own orig still holds the old value. */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1070
1071
  			if (!batadv_compare_eth(backbone_gw->orig,
  						oldif->net_dev->dev_addr))
23721387c   Simon Wunderlich   batman-adv: add b...
1072
  				continue;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
1073
1074
  			ether_addr_copy(backbone_gw->orig,
  					primary_if->net_dev->dev_addr);
23721387c   Simon Wunderlich   batman-adv: add b...
1075
1076
1077
  			/* send an announce frame so others will ask for our
  			 * claims and update their tables.
  			 */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1078
  			batadv_bla_send_announce(bat_priv, backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
1079
1080
1081
1082
  		}
  		rcu_read_unlock();
  	}
  }
23721387c   Simon Wunderlich   batman-adv: add b...
1083
1084
1085
1086
  /* periodic work to do:
   *  * purge structures when they are too old
   *  * send announcements
   */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1087
  static void batadv_bla_periodic_work(struct work_struct *work)
23721387c   Simon Wunderlich   batman-adv: add b...
1088
  {
bbb1f90ef   Sven Eckelmann   batman-adv: Don't...
1089
  	struct delayed_work *delayed_work;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1090
  	struct batadv_priv *bat_priv;
807736f6e   Sven Eckelmann   batman-adv: Split...
1091
  	struct batadv_priv_bla *priv_bla;
23721387c   Simon Wunderlich   batman-adv: add b...
1092
  	struct hlist_head *head;
bae987747   Marek Lindner   batman-adv: renam...
1093
  	struct batadv_bla_backbone_gw *backbone_gw;
5bf74e9ca   Sven Eckelmann   batman-adv: Prefi...
1094
  	struct batadv_hashtable *hash;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1095
  	struct batadv_hard_iface *primary_if;
23721387c   Simon Wunderlich   batman-adv: add b...
1096
  	int i;
bbb1f90ef   Sven Eckelmann   batman-adv: Don't...
1097
  	delayed_work = container_of(work, struct delayed_work, work);
807736f6e   Sven Eckelmann   batman-adv: Split...
1098
1099
  	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...
1100
  	primary_if = batadv_primary_if_get_selected(bat_priv);
23721387c   Simon Wunderlich   batman-adv: add b...
1101
1102
  	if (!primary_if)
  		goto out;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1103
1104
  	batadv_bla_purge_claims(bat_priv, primary_if, 0);
  	batadv_bla_purge_backbone_gw(bat_priv, 0);
23721387c   Simon Wunderlich   batman-adv: add b...
1105
1106
1107
  
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
  		goto out;
807736f6e   Sven Eckelmann   batman-adv: Split...
1108
  	hash = bat_priv->bla.backbone_hash;
23721387c   Simon Wunderlich   batman-adv: add b...
1109
1110
1111
1112
1113
1114
1115
  	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...
1116
  		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1117
1118
  			if (!batadv_compare_eth(backbone_gw->orig,
  						primary_if->net_dev->dev_addr))
23721387c   Simon Wunderlich   batman-adv: add b...
1119
1120
1121
  				continue;
  
  			backbone_gw->lasttime = jiffies;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1122
  			batadv_bla_send_announce(bat_priv, backbone_gw);
d807f2728   Simon Wunderlich   batman-adv: allow...
1123
1124
1125
1126
1127
  
  			/* 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 ...
1128
1129
1130
  			 * 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...
1131
1132
1133
1134
  			 */
  
  			if (atomic_read(&backbone_gw->request_sent) == 0)
  				continue;
28709878b   Simon Wunderlich   batman-adv: wait ...
1135
1136
  			if (!atomic_dec_and_test(&backbone_gw->wait_periods))
  				continue;
d807f2728   Simon Wunderlich   batman-adv: allow...
1137
1138
  			atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
  			atomic_set(&backbone_gw->request_sent, 0);
23721387c   Simon Wunderlich   batman-adv: add b...
1139
1140
1141
1142
1143
  		}
  		rcu_read_unlock();
  	}
  out:
  	if (primary_if)
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1144
  		batadv_hardif_free_ref(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
1145

724144420   Antonio Quartulli   batman-adv: a del...
1146
1147
  	queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work,
  			   msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH));
23721387c   Simon Wunderlich   batman-adv: add b...
1148
  }
5d52dad27   Sven Eckelmann   batman-adv: Initi...
1149
1150
1151
1152
1153
  /* 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...
1154
1155
  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...
1156

23721387c   Simon Wunderlich   batman-adv: add b...
1157
  /* initialize all bla structures */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1158
  int batadv_bla_init(struct batadv_priv *bat_priv)
23721387c   Simon Wunderlich   batman-adv: add b...
1159
  {
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1160
  	int i;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1161
  	uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1162
  	struct batadv_hard_iface *primary_if;
807736f6e   Sven Eckelmann   batman-adv: Split...
1163
1164
  	uint16_t crc;
  	unsigned long entrytime;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1165

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

38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1170
  	/* setting claim destination address */
807736f6e   Sven Eckelmann   batman-adv: Split...
1171
1172
  	memcpy(&bat_priv->bla.claim_dest.magic, claim_dest, 3);
  	bat_priv->bla.claim_dest.type = 0;
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1173
  	primary_if = batadv_primary_if_get_selected(bat_priv);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1174
  	if (primary_if) {
807736f6e   Sven Eckelmann   batman-adv: Split...
1175
1176
  		crc = crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN);
  		bat_priv->bla.claim_dest.group = htons(crc);
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1177
  		batadv_hardif_free_ref(primary_if);
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1178
  	} else {
807736f6e   Sven Eckelmann   batman-adv: Split...
1179
  		bat_priv->bla.claim_dest.group = 0; /* will be set later */
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1180
  	}
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1181
  	/* initialize the duplicate list */
807736f6e   Sven Eckelmann   batman-adv: Split...
1182
  	entrytime = jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT);
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1183
  	for (i = 0; i < BATADV_DUPLIST_SIZE; i++)
807736f6e   Sven Eckelmann   batman-adv: Split...
1184
1185
  		bat_priv->bla.bcast_duplist[i].entrytime = entrytime;
  	bat_priv->bla.bcast_duplist_curr = 0;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1186

807736f6e   Sven Eckelmann   batman-adv: Split...
1187
  	if (bat_priv->bla.claim_hash)
5346c35eb   Sven Eckelmann   batman-adv: Retur...
1188
  		return 0;
23721387c   Simon Wunderlich   batman-adv: add b...
1189

807736f6e   Sven Eckelmann   batman-adv: Split...
1190
1191
  	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...
1192

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

807736f6e   Sven Eckelmann   batman-adv: Split...
1196
  	batadv_hash_set_lock_class(bat_priv->bla.claim_hash,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1197
  				   &batadv_claim_hash_lock_class_key);
807736f6e   Sven Eckelmann   batman-adv: Split...
1198
  	batadv_hash_set_lock_class(bat_priv->bla.backbone_hash,
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1199
  				   &batadv_backbone_hash_lock_class_key);
5d52dad27   Sven Eckelmann   batman-adv: Initi...
1200

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

724144420   Antonio Quartulli   batman-adv: a del...
1204
1205
1206
1207
  	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...
1208
  	return 0;
23721387c   Simon Wunderlich   batman-adv: add b...
1209
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1210
1211
1212
  /**
   * batadv_bla_check_bcast_duplist
   * @bat_priv: the bat priv with all the soft interface information
004e86fc5   Simon Wunderlich   batman-adv: Fix b...
1213
   * @skb: contains the bcast_packet to be checked
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1214
1215
1216
1217
1218
1219
1220
1221
1222
   *
   * 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.
   *
   * 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.
9cfc7bd60   Sven Eckelmann   batman-adv: Refor...
1223
   */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1224
  int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
004e86fc5   Simon Wunderlich   batman-adv: Fix b...
1225
  				   struct sk_buff *skb)
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1226
  {
004e86fc5   Simon Wunderlich   batman-adv: Fix b...
1227
1228
1229
  	int i, curr, ret = 0;
  	__be32 crc;
  	struct batadv_bcast_packet *bcast_packet;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1230
  	struct batadv_bcast_duplist_entry *entry;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1231

004e86fc5   Simon Wunderlich   batman-adv: Fix b...
1232
  	bcast_packet = (struct batadv_bcast_packet *)skb->data;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1233
1234
  
  	/* calculate the crc ... */
004e86fc5   Simon Wunderlich   batman-adv: Fix b...
1235
  	crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1236

7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1237
  	spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1238
  	for (i = 0; i < BATADV_DUPLIST_SIZE; i++) {
807736f6e   Sven Eckelmann   batman-adv: Split...
1239
1240
1241
  		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...
1242
1243
1244
1245
  
  		/* we can stop searching if the entry is too old ;
  		 * later entries will be even older
  		 */
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1246
1247
  		if (batadv_has_timed_out(entry->entrytime,
  					 BATADV_DUPLIST_TIMEOUT))
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1248
1249
1250
1251
  			break;
  
  		if (entry->crc != crc)
  			continue;
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1252
  		if (batadv_compare_eth(entry->orig, bcast_packet->orig))
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1253
1254
1255
1256
1257
  			continue;
  
  		/* this entry seems to match: same crc, not too old,
  		 * and from another gw. therefore return 1 to forbid it.
  		 */
7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1258
1259
  		ret = 1;
  		goto out;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1260
  	}
7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1261
1262
1263
  	/* not found, add a new entry (overwrite the oldest entry)
  	 * and allow it, its the first occurence.
  	 */
807736f6e   Sven Eckelmann   batman-adv: Split...
1264
  	curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1);
42d0b044b   Sven Eckelmann   batman-adv: Prefi...
1265
  	curr %= BATADV_DUPLIST_SIZE;
807736f6e   Sven Eckelmann   batman-adv: Split...
1266
  	entry = &bat_priv->bla.bcast_duplist[curr];
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1267
1268
  	entry->crc = crc;
  	entry->entrytime = jiffies;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
1269
  	ether_addr_copy(entry->orig, bcast_packet->orig);
807736f6e   Sven Eckelmann   batman-adv: Split...
1270
  	bat_priv->bla.bcast_duplist_curr = curr;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1271

7dac7b76b   Linus Lüssing   batman-adv: Fix p...
1272
1273
1274
1275
  out:
  	spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock);
  
  	return ret;
fe2da6ff2   Simon Wunderlich   batman-adv: add b...
1276
  }
1b371d130   Simon Wunderlich   batman-adv: use c...
1277
1278
1279
  /**
   * batadv_bla_is_backbone_gw_orig
   * @bat_priv: the bat priv with all the soft interface information
20ff9d593   Simon Wunderlich   batman-adv: don't...
1280
   * @orig: originator mac address
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1281
   * @vid: VLAN identifier
20ff9d593   Simon Wunderlich   batman-adv: don't...
1282
   *
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1283
   * Check if the originator is a gateway for the VLAN identified by vid.
20ff9d593   Simon Wunderlich   batman-adv: don't...
1284
   *
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1285
   * Returns true if orig is a backbone for this vid, false otherwise.
20ff9d593   Simon Wunderlich   batman-adv: don't...
1286
   */
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1287
1288
  bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig,
  				    unsigned short vid)
20ff9d593   Simon Wunderlich   batman-adv: don't...
1289
  {
807736f6e   Sven Eckelmann   batman-adv: Split...
1290
  	struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1291
  	struct hlist_head *head;
bae987747   Marek Lindner   batman-adv: renam...
1292
  	struct batadv_bla_backbone_gw *backbone_gw;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1293
1294
1295
  	int i;
  
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1296
  		return false;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1297
1298
  
  	if (!hash)
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1299
  		return false;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1300
1301
1302
1303
1304
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
1305
  		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1306
1307
  			if (batadv_compare_eth(backbone_gw->orig, orig) &&
  			    backbone_gw->vid == vid) {
20ff9d593   Simon Wunderlich   batman-adv: don't...
1308
  				rcu_read_unlock();
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1309
  				return true;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1310
1311
1312
1313
  			}
  		}
  		rcu_read_unlock();
  	}
cfd4f7570   Antonio Quartulli   batman-adv: make ...
1314
  	return false;
20ff9d593   Simon Wunderlich   batman-adv: don't...
1315
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1316
1317
1318
  /**
   * batadv_bla_is_backbone_gw
   * @skb: the frame to be checked
23721387c   Simon Wunderlich   batman-adv: add b...
1319
1320
1321
1322
1323
1324
   * @orig_node: the orig_node of the frame
   * @hdr_size: maximum length of the frame
   *
   * bla_is_backbone_gw inspects the skb for the VLAN ID and returns 1
   * if the orig_node is also a gateway on the soft interface, otherwise it
   * returns 0.
23721387c   Simon Wunderlich   batman-adv: add b...
1325
   */
08adf1512   Sven Eckelmann   batman-adv: Prefi...
1326
  int batadv_bla_is_backbone_gw(struct sk_buff *skb,
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1327
  			      struct batadv_orig_node *orig_node, int hdr_size)
23721387c   Simon Wunderlich   batman-adv: add b...
1328
  {
bae987747   Marek Lindner   batman-adv: renam...
1329
  	struct batadv_bla_backbone_gw *backbone_gw;
c018ad3de   Antonio Quartulli   batman-adv: add t...
1330
  	unsigned short vid;
23721387c   Simon Wunderlich   batman-adv: add b...
1331
1332
1333
1334
1335
  
  	if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
  		return 0;
  
  	/* first, find out the vid. */
0d125074e   Antonio Quartulli   batman-adv: use E...
1336
  	if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
23721387c   Simon Wunderlich   batman-adv: add b...
1337
  		return 0;
c018ad3de   Antonio Quartulli   batman-adv: add t...
1338
  	vid = batadv_get_vid(skb, hdr_size);
23721387c   Simon Wunderlich   batman-adv: add b...
1339
1340
  
  	/* see if this originator is a backbone gw for this VLAN */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1341
1342
  	backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,
  						orig_node->orig, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1343
1344
  	if (!backbone_gw)
  		return 0;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1345
  	batadv_backbone_gw_free_ref(backbone_gw);
23721387c   Simon Wunderlich   batman-adv: add b...
1346
1347
1348
1349
  	return 1;
  }
  
  /* free all bla structures (for softinterface free or module unload) */
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1350
  void batadv_bla_free(struct batadv_priv *bat_priv)
23721387c   Simon Wunderlich   batman-adv: add b...
1351
  {
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1352
  	struct batadv_hard_iface *primary_if;
23721387c   Simon Wunderlich   batman-adv: add b...
1353

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

807736f6e   Sven Eckelmann   batman-adv: Split...
1357
  	if (bat_priv->bla.claim_hash) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1358
  		batadv_bla_purge_claims(bat_priv, primary_if, 1);
807736f6e   Sven Eckelmann   batman-adv: Split...
1359
1360
  		batadv_hash_destroy(bat_priv->bla.claim_hash);
  		bat_priv->bla.claim_hash = NULL;
23721387c   Simon Wunderlich   batman-adv: add b...
1361
  	}
807736f6e   Sven Eckelmann   batman-adv: Split...
1362
  	if (bat_priv->bla.backbone_hash) {
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1363
  		batadv_bla_purge_backbone_gw(bat_priv, 1);
807736f6e   Sven Eckelmann   batman-adv: Split...
1364
1365
  		batadv_hash_destroy(bat_priv->bla.backbone_hash);
  		bat_priv->bla.backbone_hash = NULL;
23721387c   Simon Wunderlich   batman-adv: add b...
1366
1367
  	}
  	if (primary_if)
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1368
  		batadv_hardif_free_ref(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
1369
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1370
1371
1372
  /**
   * batadv_bla_rx
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
1373
1374
   * @skb: the frame to be checked
   * @vid: the VLAN ID of the frame
2d3f6ccc4   Simon Wunderlich   batman-adv: check...
1375
   * @is_bcast: the packet came in a broadcast packet type.
23721387c   Simon Wunderlich   batman-adv: add b...
1376
1377
1378
1379
1380
1381
1382
1383
   *
   * bla_rx avoidance checks if:
   *  * we have to race for a claim
   *  * if the frame is allowed on the LAN
   *
   * in these cases, the skb is further handled by this function and
   * returns 1, otherwise it returns 0 and the caller shall further
   * process the skb.
23721387c   Simon Wunderlich   batman-adv: add b...
1384
   */
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
1385
1386
  int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
  		  unsigned short vid, bool is_bcast)
23721387c   Simon Wunderlich   batman-adv: add b...
1387
1388
  {
  	struct ethhdr *ethhdr;
712bbfe46   Marek Lindner   batman-adv: renam...
1389
  	struct batadv_bla_claim search_claim, *claim = NULL;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1390
  	struct batadv_hard_iface *primary_if;
23721387c   Simon Wunderlich   batman-adv: add b...
1391
  	int ret;
7ed4be952   Antonio Quartulli   batman-adv: use e...
1392
  	ethhdr = eth_hdr(skb);
23721387c   Simon Wunderlich   batman-adv: add b...
1393

e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1394
  	primary_if = batadv_primary_if_get_selected(bat_priv);
23721387c   Simon Wunderlich   batman-adv: add b...
1395
1396
1397
1398
1399
  	if (!primary_if)
  		goto handled;
  
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
  		goto allow;
807736f6e   Sven Eckelmann   batman-adv: Split...
1400
  	if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
23721387c   Simon Wunderlich   batman-adv: add b...
1401
  		/* don't allow broadcasts while requests are in flight */
2d3f6ccc4   Simon Wunderlich   batman-adv: check...
1402
  		if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
23721387c   Simon Wunderlich   batman-adv: add b...
1403
  			goto handled;
8fdd01530   Antonio Quartulli   batman-adv: prefe...
1404
  	ether_addr_copy(search_claim.addr, ethhdr->h_source);
23721387c   Simon Wunderlich   batman-adv: add b...
1405
  	search_claim.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1406
  	claim = batadv_claim_hash_find(bat_priv, &search_claim);
23721387c   Simon Wunderlich   batman-adv: add b...
1407
1408
1409
1410
1411
  
  	if (!claim) {
  		/* possible optimization: race for a claim */
  		/* No claim exists yet, claim it for us!
  		 */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1412
1413
1414
  		batadv_handle_claim(bat_priv, primary_if,
  				    primary_if->net_dev->dev_addr,
  				    ethhdr->h_source, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1415
1416
1417
1418
  		goto allow;
  	}
  
  	/* if it is our own claim ... */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1419
1420
  	if (batadv_compare_eth(claim->backbone_gw->orig,
  			       primary_if->net_dev->dev_addr)) {
23721387c   Simon Wunderlich   batman-adv: add b...
1421
1422
1423
1424
1425
1426
  		/* ... allow it in any case */
  		claim->lasttime = jiffies;
  		goto allow;
  	}
  
  	/* if it is a broadcast ... */
2d3f6ccc4   Simon Wunderlich   batman-adv: check...
1427
1428
1429
1430
1431
1432
1433
  	if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
  		/* ... drop it. the responsible gateway is in charge.
  		 *
  		 * We need to check is_bcast because with the gateway
  		 * feature, broadcasts (like DHCP requests) may be sent
  		 * using a unicast packet type.
  		 */
23721387c   Simon Wunderlich   batman-adv: add b...
1434
1435
1436
1437
1438
1439
  		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...
1440
1441
1442
  		batadv_handle_claim(bat_priv, primary_if,
  				    primary_if->net_dev->dev_addr,
  				    ethhdr->h_source, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1443
1444
1445
  		goto allow;
  	}
  allow:
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1446
  	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1447
1448
1449
1450
1451
1452
1453
1454
1455
  	ret = 0;
  	goto out;
  
  handled:
  	kfree_skb(skb);
  	ret = 1;
  
  out:
  	if (primary_if)
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1456
  		batadv_hardif_free_ref(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
1457
  	if (claim)
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1458
  		batadv_claim_free_ref(claim);
23721387c   Simon Wunderlich   batman-adv: add b...
1459
1460
  	return ret;
  }
2c53040f0   Ben Hutchings   net: Fix (nearly-...
1461
1462
1463
  /**
   * batadv_bla_tx
   * @bat_priv: the bat priv with all the soft interface information
23721387c   Simon Wunderlich   batman-adv: add b...
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
   * @skb: the frame to be checked
   * @vid: the VLAN ID of the frame
   *
   * bla_tx checks if:
   *  * a claim was received which has to be processed
   *  * the frame is allowed on the mesh
   *
   * in these cases, the skb is further handled by this function and
   * returns 1, otherwise it returns 0 and the caller shall further
   * process the skb.
9d2c9488c   Linus Lüssing   batman-adv: fix p...
1474
1475
   *
   * This call might reallocate skb data.
23721387c   Simon Wunderlich   batman-adv: add b...
1476
   */
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
1477
1478
  int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
  		  unsigned short vid)
23721387c   Simon Wunderlich   batman-adv: add b...
1479
1480
  {
  	struct ethhdr *ethhdr;
712bbfe46   Marek Lindner   batman-adv: renam...
1481
  	struct batadv_bla_claim search_claim, *claim = NULL;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1482
  	struct batadv_hard_iface *primary_if;
23721387c   Simon Wunderlich   batman-adv: add b...
1483
  	int ret = 0;
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1484
  	primary_if = batadv_primary_if_get_selected(bat_priv);
23721387c   Simon Wunderlich   batman-adv: add b...
1485
1486
1487
1488
1489
  	if (!primary_if)
  		goto out;
  
  	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
  		goto allow;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1490
  	if (batadv_bla_process_claim(bat_priv, primary_if, skb))
23721387c   Simon Wunderlich   batman-adv: add b...
1491
  		goto handled;
7ed4be952   Antonio Quartulli   batman-adv: use e...
1492
  	ethhdr = eth_hdr(skb);
23721387c   Simon Wunderlich   batman-adv: add b...
1493

807736f6e   Sven Eckelmann   batman-adv: Split...
1494
  	if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
23721387c   Simon Wunderlich   batman-adv: add b...
1495
1496
1497
  		/* 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...
1498
  	ether_addr_copy(search_claim.addr, ethhdr->h_source);
23721387c   Simon Wunderlich   batman-adv: add b...
1499
  	search_claim.vid = vid;
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1500
  	claim = batadv_claim_hash_find(bat_priv, &search_claim);
23721387c   Simon Wunderlich   batman-adv: add b...
1501
1502
1503
1504
1505
1506
  
  	/* if no claim exists, allow it. */
  	if (!claim)
  		goto allow;
  
  	/* check if we are responsible. */
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1507
1508
  	if (batadv_compare_eth(claim->backbone_gw->orig,
  			       primary_if->net_dev->dev_addr)) {
23721387c   Simon Wunderlich   batman-adv: add b...
1509
1510
1511
  		/* if yes, the client has roamed and we have
  		 * to unclaim it.
  		 */
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1512
1513
1514
  		batadv_handle_unclaim(bat_priv, primary_if,
  				      primary_if->net_dev->dev_addr,
  				      ethhdr->h_source, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
  		goto allow;
  	}
  
  	/* 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...
1531
  	batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
23721387c   Simon Wunderlich   batman-adv: add b...
1532
1533
1534
1535
1536
1537
  	ret = 0;
  	goto out;
  handled:
  	ret = 1;
  out:
  	if (primary_if)
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1538
  		batadv_hardif_free_ref(primary_if);
23721387c   Simon Wunderlich   batman-adv: add b...
1539
  	if (claim)
3b300de32   Sven Eckelmann   batman-adv: Prefi...
1540
  		batadv_claim_free_ref(claim);
23721387c   Simon Wunderlich   batman-adv: add b...
1541
1542
  	return ret;
  }
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
1543

08adf1512   Sven Eckelmann   batman-adv: Prefi...
1544
  int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
1545
1546
  {
  	struct net_device *net_dev = (struct net_device *)seq->private;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1547
  	struct batadv_priv *bat_priv = netdev_priv(net_dev);
807736f6e   Sven Eckelmann   batman-adv: Split...
1548
  	struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
712bbfe46   Marek Lindner   batman-adv: renam...
1549
  	struct batadv_bla_claim *claim;
56303d34a   Sven Eckelmann   batman-adv: Prefi...
1550
  	struct batadv_hard_iface *primary_if;
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
1551
1552
1553
  	struct hlist_head *head;
  	uint32_t i;
  	bool is_own;
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1554
  	uint8_t *primary_addr;
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
1555

30da63a6a   Marek Lindner   batman-adv: conso...
1556
1557
  	primary_if = batadv_seq_print_text_primary_if_get(seq);
  	if (!primary_if)
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
1558
  		goto out;
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
1559

1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1560
  	primary_addr = primary_if->net_dev->dev_addr;
38ef3d1d9   Simon Wunderlich   batman-adv: form ...
1561
  	seq_printf(seq,
39a329915   Antonio Quartulli   batman-adv: unify...
1562
1563
  		   "Claims announced for the mesh %s (orig %pM, group id %#.4x)
  ",
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1564
  		   net_dev->name, primary_addr,
807736f6e   Sven Eckelmann   batman-adv: Split...
1565
  		   ntohs(bat_priv->bla.claim_dest.group));
39a329915   Antonio Quartulli   batman-adv: unify...
1566
1567
  	seq_printf(seq, "   %-17s    %-5s    %-17s [o] (%-6s)
  ",
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
1568
1569
1570
1571
1572
  		   "Client", "VID", "Originator", "CRC");
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
1573
  		hlist_for_each_entry_rcu(claim, head, hash_entry) {
1eda58bfc   Sven Eckelmann   batman-adv: Prefi...
1574
1575
  			is_own = batadv_compare_eth(claim->backbone_gw->orig,
  						    primary_addr);
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
1576
1577
  			seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
1578
  				   claim->addr, BATADV_PRINT_VID(claim->vid),
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
1579
1580
1581
1582
1583
1584
1585
1586
  				   claim->backbone_gw->orig,
  				   (is_own ? 'x' : ' '),
  				   claim->backbone_gw->crc);
  		}
  		rcu_read_unlock();
  	}
  out:
  	if (primary_if)
e5d89254b   Sven Eckelmann   batman-adv: Prefi...
1587
  		batadv_hardif_free_ref(primary_if);
30da63a6a   Marek Lindner   batman-adv: conso...
1588
  	return 0;
9bf8e4d42   Simon Wunderlich   batman-adv: expor...
1589
  }
536a23f11   Simon Wunderlich   batman-adv: Add t...
1590
1591
1592
1593
1594
  
  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...
1595
  	struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
bae987747   Marek Lindner   batman-adv: renam...
1596
  	struct batadv_bla_backbone_gw *backbone_gw;
536a23f11   Simon Wunderlich   batman-adv: Add t...
1597
  	struct batadv_hard_iface *primary_if;
536a23f11   Simon Wunderlich   batman-adv: Add t...
1598
1599
1600
1601
  	struct hlist_head *head;
  	int secs, msecs;
  	uint32_t i;
  	bool is_own;
536a23f11   Simon Wunderlich   batman-adv: Add t...
1602
  	uint8_t *primary_addr;
30da63a6a   Marek Lindner   batman-adv: conso...
1603
1604
  	primary_if = batadv_seq_print_text_primary_if_get(seq);
  	if (!primary_if)
536a23f11   Simon Wunderlich   batman-adv: Add t...
1605
  		goto out;
536a23f11   Simon Wunderlich   batman-adv: Add t...
1606
1607
1608
  
  	primary_addr = primary_if->net_dev->dev_addr;
  	seq_printf(seq,
39a329915   Antonio Quartulli   batman-adv: unify...
1609
1610
  		   "Backbones announced for the mesh %s (orig %pM, group id %#.4x)
  ",
536a23f11   Simon Wunderlich   batman-adv: Add t...
1611
  		   net_dev->name, primary_addr,
807736f6e   Sven Eckelmann   batman-adv: Split...
1612
  		   ntohs(bat_priv->bla.claim_dest.group));
39a329915   Antonio Quartulli   batman-adv: unify...
1613
1614
  	seq_printf(seq, "   %-17s    %-5s %-9s (%-6s)
  ",
536a23f11   Simon Wunderlich   batman-adv: Add t...
1615
1616
1617
1618
1619
  		   "Originator", "VID", "last seen", "CRC");
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
b67bfe0d4   Sasha Levin   hlist: drop the n...
1620
  		hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
536a23f11   Simon Wunderlich   batman-adv: Add t...
1621
1622
1623
1624
1625
1626
1627
1628
1629
  			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;
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
1630
1631
  			seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)
  ",
5f80df670   Antonio Quartulli   batman-adv: print...
1632
1633
  				   backbone_gw->orig,
  				   BATADV_PRINT_VID(backbone_gw->vid), secs,
eb2deb6b3   Antonio Quartulli   batman-adv: chang...
1634
  				   msecs, backbone_gw->crc);
536a23f11   Simon Wunderlich   batman-adv: Add t...
1635
1636
1637
1638
1639
1640
  		}
  		rcu_read_unlock();
  	}
  out:
  	if (primary_if)
  		batadv_hardif_free_ref(primary_if);
30da63a6a   Marek Lindner   batman-adv: conso...
1641
  	return 0;
536a23f11   Simon Wunderlich   batman-adv: Add t...
1642
  }