blob: 8f9059f15ebb9f6776358bf48e242fd44e7a41a8 [file] [log] [blame]
Sven Eckelmann9f6446c2015-04-23 13:16:35 +02001/* Copyright (C) 2011-2015 B.A.T.M.A.N. contributors:
Simon Wunderlich23721382012-01-22 20:00:19 +01002 *
3 * Simon Wunderlich
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
Antonio Quartulliebf38fb2013-11-03 20:40:48 +010015 * along with this program; if not, see <http://www.gnu.org/licenses/>.
Simon Wunderlich23721382012-01-22 20:00:19 +010016 */
17
Simon Wunderlich23721382012-01-22 20:00:19 +010018#include "bridge_loop_avoidance.h"
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020019#include "main.h"
Simon Wunderlich23721382012-01-22 20:00:19 +010020
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020021#include <linux/atomic.h>
22#include <linux/byteorder/generic.h>
23#include <linux/compiler.h>
Simon Wunderlich23721382012-01-22 20:00:19 +010024#include <linux/crc16.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020025#include <linux/errno.h>
26#include <linux/etherdevice.h>
27#include <linux/fs.h>
Simon Wunderlich23721382012-01-22 20:00:19 +010028#include <linux/if_arp.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020029#include <linux/if_ether.h>
Simon Wunderlich23721382012-01-22 20:00:19 +010030#include <linux/if_vlan.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020031#include <linux/jhash.h>
32#include <linux/jiffies.h>
33#include <linux/kernel.h>
34#include <linux/list.h>
35#include <linux/lockdep.h>
36#include <linux/netdevice.h>
37#include <linux/rculist.h>
38#include <linux/rcupdate.h>
39#include <linux/seq_file.h>
40#include <linux/skbuff.h>
41#include <linux/slab.h>
42#include <linux/spinlock.h>
43#include <linux/stddef.h>
44#include <linux/string.h>
45#include <linux/workqueue.h>
46#include <net/arp.h>
47
48#include "hard-interface.h"
49#include "hash.h"
50#include "originator.h"
51#include "packet.h"
52#include "translation-table.h"
Simon Wunderlich23721382012-01-22 20:00:19 +010053
Sven Eckelmann6b5e9712015-05-26 18:34:26 +020054static const u8 batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05};
Simon Wunderlich23721382012-01-22 20:00:19 +010055
Sven Eckelmann3b300de2012-05-12 18:33:53 +020056static void batadv_bla_periodic_work(struct work_struct *work);
Marek Lindnerbae98772012-12-25 17:03:24 +080057static void
58batadv_bla_send_announce(struct batadv_priv *bat_priv,
59 struct batadv_bla_backbone_gw *backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +010060
61/* return the index of the claim */
Sven Eckelmann6b5e9712015-05-26 18:34:26 +020062static inline u32 batadv_choose_claim(const void *data, u32 size)
Simon Wunderlich23721382012-01-22 20:00:19 +010063{
Marek Lindner712bbfe42012-12-25 17:03:25 +080064 struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +020065 u32 hash = 0;
Simon Wunderlich23721382012-01-22 20:00:19 +010066
Sven Eckelmann36fd61c2015-03-01 09:46:18 +010067 hash = jhash(&claim->addr, sizeof(claim->addr), hash);
68 hash = jhash(&claim->vid, sizeof(claim->vid), hash);
Simon Wunderlich23721382012-01-22 20:00:19 +010069
70 return hash % size;
71}
72
73/* return the index of the backbone gateway */
Sven Eckelmann6b5e9712015-05-26 18:34:26 +020074static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
Simon Wunderlich23721382012-01-22 20:00:19 +010075{
Marek Lindner712bbfe42012-12-25 17:03:25 +080076 const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +020077 u32 hash = 0;
Simon Wunderlich23721382012-01-22 20:00:19 +010078
Sven Eckelmann36fd61c2015-03-01 09:46:18 +010079 hash = jhash(&claim->addr, sizeof(claim->addr), hash);
80 hash = jhash(&claim->vid, sizeof(claim->vid), hash);
Simon Wunderlich23721382012-01-22 20:00:19 +010081
82 return hash % size;
83}
84
Simon Wunderlich23721382012-01-22 20:00:19 +010085/* compares address and vid of two backbone gws */
Sven Eckelmann3b300de2012-05-12 18:33:53 +020086static int batadv_compare_backbone_gw(const struct hlist_node *node,
87 const void *data2)
Simon Wunderlich23721382012-01-22 20:00:19 +010088{
Marek Lindnerbae98772012-12-25 17:03:24 +080089 const void *data1 = container_of(node, struct batadv_bla_backbone_gw,
Simon Wunderlich23721382012-01-22 20:00:19 +010090 hash_entry);
Marek Lindnerbae98772012-12-25 17:03:24 +080091 const struct batadv_bla_backbone_gw *gw1 = data1, *gw2 = data2;
Simon Wunderlich23721382012-01-22 20:00:19 +010092
Simon Wunderlichc76d1522012-10-15 22:38:04 +020093 if (!batadv_compare_eth(gw1->orig, gw2->orig))
94 return 0;
95
96 if (gw1->vid != gw2->vid)
97 return 0;
98
99 return 1;
Simon Wunderlich23721382012-01-22 20:00:19 +0100100}
101
102/* compares address and vid of two claims */
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200103static int batadv_compare_claim(const struct hlist_node *node,
104 const void *data2)
Simon Wunderlich23721382012-01-22 20:00:19 +0100105{
Marek Lindner712bbfe42012-12-25 17:03:25 +0800106 const void *data1 = container_of(node, struct batadv_bla_claim,
Simon Wunderlich23721382012-01-22 20:00:19 +0100107 hash_entry);
Marek Lindner712bbfe42012-12-25 17:03:25 +0800108 const struct batadv_bla_claim *cl1 = data1, *cl2 = data2;
Simon Wunderlich23721382012-01-22 20:00:19 +0100109
Simon Wunderlichc76d1522012-10-15 22:38:04 +0200110 if (!batadv_compare_eth(cl1->addr, cl2->addr))
111 return 0;
112
113 if (cl1->vid != cl2->vid)
114 return 0;
115
116 return 1;
Simon Wunderlich23721382012-01-22 20:00:19 +0100117}
118
119/* free a backbone gw */
Marek Lindnerbae98772012-12-25 17:03:24 +0800120static void
121batadv_backbone_gw_free_ref(struct batadv_bla_backbone_gw *backbone_gw)
Simon Wunderlich23721382012-01-22 20:00:19 +0100122{
123 if (atomic_dec_and_test(&backbone_gw->refcount))
124 kfree_rcu(backbone_gw, rcu);
125}
126
127/* finally deinitialize the claim */
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200128static void batadv_claim_free_rcu(struct rcu_head *rcu)
Simon Wunderlich23721382012-01-22 20:00:19 +0100129{
Marek Lindner712bbfe42012-12-25 17:03:25 +0800130 struct batadv_bla_claim *claim;
Simon Wunderlich23721382012-01-22 20:00:19 +0100131
Marek Lindner712bbfe42012-12-25 17:03:25 +0800132 claim = container_of(rcu, struct batadv_bla_claim, rcu);
Simon Wunderlich23721382012-01-22 20:00:19 +0100133
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200134 batadv_backbone_gw_free_ref(claim->backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +0100135 kfree(claim);
136}
137
138/* free a claim, call claim_free_rcu if its the last reference */
Marek Lindner712bbfe42012-12-25 17:03:25 +0800139static void batadv_claim_free_ref(struct batadv_bla_claim *claim)
Simon Wunderlich23721382012-01-22 20:00:19 +0100140{
141 if (atomic_dec_and_test(&claim->refcount))
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200142 call_rcu(&claim->rcu, batadv_claim_free_rcu);
Simon Wunderlich23721382012-01-22 20:00:19 +0100143}
144
Simon Wunderlich1b371d12014-01-15 21:17:54 +0100145/**
146 * batadv_claim_hash_find
147 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich23721382012-01-22 20:00:19 +0100148 * @data: search data (may be local/static data)
149 *
150 * looks for a claim in the hash, and returns it if found
151 * or NULL otherwise.
152 */
Marek Lindner712bbfe42012-12-25 17:03:25 +0800153static struct batadv_bla_claim
154*batadv_claim_hash_find(struct batadv_priv *bat_priv,
155 struct batadv_bla_claim *data)
Simon Wunderlich23721382012-01-22 20:00:19 +0100156{
Sven Eckelmann807736f2012-07-15 22:26:51 +0200157 struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
Simon Wunderlich23721382012-01-22 20:00:19 +0100158 struct hlist_head *head;
Marek Lindner712bbfe42012-12-25 17:03:25 +0800159 struct batadv_bla_claim *claim;
160 struct batadv_bla_claim *claim_tmp = NULL;
Simon Wunderlich23721382012-01-22 20:00:19 +0100161 int index;
162
163 if (!hash)
164 return NULL;
165
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200166 index = batadv_choose_claim(data, hash->size);
Simon Wunderlich23721382012-01-22 20:00:19 +0100167 head = &hash->table[index];
168
169 rcu_read_lock();
Sasha Levinb67bfe02013-02-27 17:06:00 -0800170 hlist_for_each_entry_rcu(claim, head, hash_entry) {
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200171 if (!batadv_compare_claim(&claim->hash_entry, data))
Simon Wunderlich23721382012-01-22 20:00:19 +0100172 continue;
173
174 if (!atomic_inc_not_zero(&claim->refcount))
175 continue;
176
177 claim_tmp = claim;
178 break;
179 }
180 rcu_read_unlock();
181
182 return claim_tmp;
183}
184
Ben Hutchings2c530402012-07-10 10:55:09 +0000185/**
186 * batadv_backbone_hash_find - looks for a claim in the hash
187 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich23721382012-01-22 20:00:19 +0100188 * @addr: the address of the originator
189 * @vid: the VLAN ID
190 *
Ben Hutchings2c530402012-07-10 10:55:09 +0000191 * Returns claim if found or NULL otherwise.
Simon Wunderlich23721382012-01-22 20:00:19 +0100192 */
Marek Lindnerbae98772012-12-25 17:03:24 +0800193static struct batadv_bla_backbone_gw *
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200194batadv_backbone_hash_find(struct batadv_priv *bat_priv, u8 *addr,
195 unsigned short vid)
Simon Wunderlich23721382012-01-22 20:00:19 +0100196{
Sven Eckelmann807736f2012-07-15 22:26:51 +0200197 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
Simon Wunderlich23721382012-01-22 20:00:19 +0100198 struct hlist_head *head;
Marek Lindnerbae98772012-12-25 17:03:24 +0800199 struct batadv_bla_backbone_gw search_entry, *backbone_gw;
200 struct batadv_bla_backbone_gw *backbone_gw_tmp = NULL;
Simon Wunderlich23721382012-01-22 20:00:19 +0100201 int index;
202
203 if (!hash)
204 return NULL;
205
Antonio Quartulli8fdd0152014-01-22 00:42:11 +0100206 ether_addr_copy(search_entry.orig, addr);
Simon Wunderlich23721382012-01-22 20:00:19 +0100207 search_entry.vid = vid;
208
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200209 index = batadv_choose_backbone_gw(&search_entry, hash->size);
Simon Wunderlich23721382012-01-22 20:00:19 +0100210 head = &hash->table[index];
211
212 rcu_read_lock();
Sasha Levinb67bfe02013-02-27 17:06:00 -0800213 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200214 if (!batadv_compare_backbone_gw(&backbone_gw->hash_entry,
215 &search_entry))
Simon Wunderlich23721382012-01-22 20:00:19 +0100216 continue;
217
218 if (!atomic_inc_not_zero(&backbone_gw->refcount))
219 continue;
220
221 backbone_gw_tmp = backbone_gw;
222 break;
223 }
224 rcu_read_unlock();
225
226 return backbone_gw_tmp;
227}
228
229/* delete all claims for a backbone */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200230static void
Marek Lindnerbae98772012-12-25 17:03:24 +0800231batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
Simon Wunderlich23721382012-01-22 20:00:19 +0100232{
Sven Eckelmann5bf74e92012-06-05 22:31:28 +0200233 struct batadv_hashtable *hash;
Sasha Levinb67bfe02013-02-27 17:06:00 -0800234 struct hlist_node *node_tmp;
Simon Wunderlich23721382012-01-22 20:00:19 +0100235 struct hlist_head *head;
Marek Lindner712bbfe42012-12-25 17:03:25 +0800236 struct batadv_bla_claim *claim;
Simon Wunderlich23721382012-01-22 20:00:19 +0100237 int i;
238 spinlock_t *list_lock; /* protects write access to the hash lists */
239
Sven Eckelmann807736f2012-07-15 22:26:51 +0200240 hash = backbone_gw->bat_priv->bla.claim_hash;
Simon Wunderlich23721382012-01-22 20:00:19 +0100241 if (!hash)
242 return;
243
244 for (i = 0; i < hash->size; i++) {
245 head = &hash->table[i];
246 list_lock = &hash->list_locks[i];
247
248 spin_lock_bh(list_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800249 hlist_for_each_entry_safe(claim, node_tmp,
Simon Wunderlich23721382012-01-22 20:00:19 +0100250 head, hash_entry) {
Simon Wunderlich23721382012-01-22 20:00:19 +0100251 if (claim->backbone_gw != backbone_gw)
252 continue;
253
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200254 batadv_claim_free_ref(claim);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800255 hlist_del_rcu(&claim->hash_entry);
Simon Wunderlich23721382012-01-22 20:00:19 +0100256 }
257 spin_unlock_bh(list_lock);
258 }
259
Antonio Quartulli3f687852014-11-02 11:29:56 +0100260 /* all claims gone, initialize CRC */
Sven Eckelmann3964f722012-06-03 22:19:10 +0200261 backbone_gw->crc = BATADV_BLA_CRC_INIT;
Simon Wunderlich23721382012-01-22 20:00:19 +0100262}
263
Ben Hutchings2c530402012-07-10 10:55:09 +0000264/**
265 * batadv_bla_send_claim - sends a claim frame according to the provided info
266 * @bat_priv: the bat priv with all the soft interface information
Martin Hundebølle3357182014-07-15 09:41:06 +0200267 * @mac: the mac address to be announced within the claim
Simon Wunderlich23721382012-01-22 20:00:19 +0100268 * @vid: the VLAN ID
269 * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...)
Simon Wunderlich23721382012-01-22 20:00:19 +0100270 */
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200271static void batadv_bla_send_claim(struct batadv_priv *bat_priv, u8 *mac,
Antonio Quartullieb2deb62013-04-19 18:07:00 +0200272 unsigned short vid, int claimtype)
Simon Wunderlich23721382012-01-22 20:00:19 +0100273{
274 struct sk_buff *skb;
275 struct ethhdr *ethhdr;
Sven Eckelmann56303d32012-06-05 22:31:31 +0200276 struct batadv_hard_iface *primary_if;
Simon Wunderlich23721382012-01-22 20:00:19 +0100277 struct net_device *soft_iface;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200278 u8 *hw_src;
Sven Eckelmann96412692012-06-05 22:31:30 +0200279 struct batadv_bla_claim_dst local_claim_dest;
Al Viro3e2f1a12012-04-22 07:47:50 +0100280 __be32 zeroip = 0;
Simon Wunderlich23721382012-01-22 20:00:19 +0100281
Sven Eckelmanne5d89252012-05-12 13:48:54 +0200282 primary_if = batadv_primary_if_get_selected(bat_priv);
Simon Wunderlich23721382012-01-22 20:00:19 +0100283 if (!primary_if)
284 return;
285
Sven Eckelmann807736f2012-07-15 22:26:51 +0200286 memcpy(&local_claim_dest, &bat_priv->bla.claim_dest,
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100287 sizeof(local_claim_dest));
Simon Wunderlich23721382012-01-22 20:00:19 +0100288 local_claim_dest.type = claimtype;
289
290 soft_iface = primary_if->soft_iface;
291
292 skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
293 /* IP DST: 0.0.0.0 */
294 zeroip,
295 primary_if->soft_iface,
296 /* IP SRC: 0.0.0.0 */
297 zeroip,
298 /* Ethernet DST: Broadcast */
299 NULL,
300 /* Ethernet SRC/HW SRC: originator mac */
301 primary_if->net_dev->dev_addr,
Simon Wunderlich99e966f2012-06-23 12:34:17 +0200302 /* HW DST: FF:43:05:XX:YY:YY
Simon Wunderlich23721382012-01-22 20:00:19 +0100303 * with XX = claim type
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100304 * and YY:YY = group id
Simon Wunderlich23721382012-01-22 20:00:19 +0100305 */
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200306 (u8 *)&local_claim_dest);
Simon Wunderlich23721382012-01-22 20:00:19 +0100307
308 if (!skb)
309 goto out;
310
311 ethhdr = (struct ethhdr *)skb->data;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200312 hw_src = (u8 *)ethhdr + ETH_HLEN + sizeof(struct arphdr);
Simon Wunderlich23721382012-01-22 20:00:19 +0100313
314 /* now we pretend that the client would have sent this ... */
315 switch (claimtype) {
Simon Wunderlich3eb87732012-06-23 12:34:18 +0200316 case BATADV_CLAIM_TYPE_CLAIM:
Simon Wunderlich23721382012-01-22 20:00:19 +0100317 /* normal claim frame
318 * set Ethernet SRC to the clients mac
319 */
Antonio Quartulli8fdd0152014-01-22 00:42:11 +0100320 ether_addr_copy(ethhdr->h_source, mac);
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200321 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200322 "bla_send_claim(): CLAIM %pM on vid %d\n", mac,
323 BATADV_PRINT_VID(vid));
Simon Wunderlich23721382012-01-22 20:00:19 +0100324 break;
Simon Wunderlich3eb87732012-06-23 12:34:18 +0200325 case BATADV_CLAIM_TYPE_UNCLAIM:
Simon Wunderlich23721382012-01-22 20:00:19 +0100326 /* unclaim frame
327 * set HW SRC to the clients mac
328 */
Antonio Quartulli8fdd0152014-01-22 00:42:11 +0100329 ether_addr_copy(hw_src, mac);
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200330 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200331 "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac,
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200332 BATADV_PRINT_VID(vid));
Simon Wunderlich23721382012-01-22 20:00:19 +0100333 break;
Sven Eckelmannacd34af2012-06-03 22:19:21 +0200334 case BATADV_CLAIM_TYPE_ANNOUNCE:
Simon Wunderlich23721382012-01-22 20:00:19 +0100335 /* announcement frame
336 * set HW SRC to the special mac containg the crc
337 */
Antonio Quartulli8fdd0152014-01-22 00:42:11 +0100338 ether_addr_copy(hw_src, mac);
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200339 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200340 "bla_send_claim(): ANNOUNCE of %pM on vid %d\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200341 ethhdr->h_source, BATADV_PRINT_VID(vid));
Simon Wunderlich23721382012-01-22 20:00:19 +0100342 break;
Sven Eckelmannacd34af2012-06-03 22:19:21 +0200343 case BATADV_CLAIM_TYPE_REQUEST:
Simon Wunderlich23721382012-01-22 20:00:19 +0100344 /* request frame
Simon Wunderlich99e966f2012-06-23 12:34:17 +0200345 * set HW SRC and header destination to the receiving backbone
346 * gws mac
Simon Wunderlich23721382012-01-22 20:00:19 +0100347 */
Antonio Quartulli8fdd0152014-01-22 00:42:11 +0100348 ether_addr_copy(hw_src, mac);
349 ether_addr_copy(ethhdr->h_dest, mac);
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200350 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Antonio Quartullieb2deb62013-04-19 18:07:00 +0200351 "bla_send_claim(): REQUEST of %pM to %pM on vid %d\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200352 ethhdr->h_source, ethhdr->h_dest,
353 BATADV_PRINT_VID(vid));
Simon Wunderlich23721382012-01-22 20:00:19 +0100354 break;
Simon Wunderlich23721382012-01-22 20:00:19 +0100355 }
356
Antonio Quartullieb2deb62013-04-19 18:07:00 +0200357 if (vid & BATADV_VLAN_HAS_TAG)
358 skb = vlan_insert_tag(skb, htons(ETH_P_8021Q),
359 vid & VLAN_VID_MASK);
Simon Wunderlich23721382012-01-22 20:00:19 +0100360
361 skb_reset_mac_header(skb);
362 skb->protocol = eth_type_trans(skb, soft_iface);
Marek Lindner1c9b0552012-06-23 11:47:53 +0200363 batadv_inc_counter(bat_priv, BATADV_CNT_RX);
364 batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
365 skb->len + ETH_HLEN);
Simon Wunderlich23721382012-01-22 20:00:19 +0100366 soft_iface->last_rx = jiffies;
367
368 netif_rx(skb);
369out:
370 if (primary_if)
Sven Eckelmanne5d89252012-05-12 13:48:54 +0200371 batadv_hardif_free_ref(primary_if);
Simon Wunderlich23721382012-01-22 20:00:19 +0100372}
373
Ben Hutchings2c530402012-07-10 10:55:09 +0000374/**
375 * batadv_bla_get_backbone_gw
376 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich23721382012-01-22 20:00:19 +0100377 * @orig: the mac address of the originator
378 * @vid: the VLAN ID
Martin Hundebølle3357182014-07-15 09:41:06 +0200379 * @own_backbone: set if the requested backbone is local
Simon Wunderlich23721382012-01-22 20:00:19 +0100380 *
381 * searches for the backbone gw or creates a new one if it could not
382 * be found.
383 */
Marek Lindnerbae98772012-12-25 17:03:24 +0800384static struct batadv_bla_backbone_gw *
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200385batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, u8 *orig,
Antonio Quartullieb2deb62013-04-19 18:07:00 +0200386 unsigned short vid, bool own_backbone)
Simon Wunderlich23721382012-01-22 20:00:19 +0100387{
Marek Lindnerbae98772012-12-25 17:03:24 +0800388 struct batadv_bla_backbone_gw *entry;
Sven Eckelmann56303d32012-06-05 22:31:31 +0200389 struct batadv_orig_node *orig_node;
Simon Wunderlich23721382012-01-22 20:00:19 +0100390 int hash_added;
391
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200392 entry = batadv_backbone_hash_find(bat_priv, orig, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +0100393
394 if (entry)
395 return entry;
396
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200397 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200398 "bla_get_backbone_gw(): not found (%pM, %d), creating new entry\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200399 orig, BATADV_PRINT_VID(vid));
Simon Wunderlich23721382012-01-22 20:00:19 +0100400
401 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
402 if (!entry)
403 return NULL;
404
405 entry->vid = vid;
406 entry->lasttime = jiffies;
Sven Eckelmann3964f722012-06-03 22:19:10 +0200407 entry->crc = BATADV_BLA_CRC_INIT;
Simon Wunderlich23721382012-01-22 20:00:19 +0100408 entry->bat_priv = bat_priv;
409 atomic_set(&entry->request_sent, 0);
Simon Wunderlich28709872012-09-13 18:18:46 +0200410 atomic_set(&entry->wait_periods, 0);
Antonio Quartulli8fdd0152014-01-22 00:42:11 +0100411 ether_addr_copy(entry->orig, orig);
Simon Wunderlich23721382012-01-22 20:00:19 +0100412
413 /* one for the hash, one for returning */
414 atomic_set(&entry->refcount, 2);
415
Sven Eckelmann807736f2012-07-15 22:26:51 +0200416 hash_added = batadv_hash_add(bat_priv->bla.backbone_hash,
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200417 batadv_compare_backbone_gw,
418 batadv_choose_backbone_gw, entry,
419 &entry->hash_entry);
Simon Wunderlich23721382012-01-22 20:00:19 +0100420
421 if (unlikely(hash_added != 0)) {
422 /* hash failed, free the structure */
423 kfree(entry);
424 return NULL;
425 }
426
Antonio Quartulli95fb1302013-08-07 18:28:55 +0200427 /* this is a gateway now, remove any TT entry on this VLAN */
Sven Eckelmannda641192012-05-12 13:48:56 +0200428 orig_node = batadv_orig_hash_find(bat_priv, orig);
Simon Wunderlich20ff9d52012-01-22 20:00:23 +0100429 if (orig_node) {
Antonio Quartulli95fb1302013-08-07 18:28:55 +0200430 batadv_tt_global_del_orig(bat_priv, orig_node, vid,
Sven Eckelmann08c36d32012-05-12 02:09:39 +0200431 "became a backbone gateway");
Sven Eckelmann7d211ef2012-05-12 02:09:34 +0200432 batadv_orig_node_free_ref(orig_node);
Simon Wunderlich20ff9d52012-01-22 20:00:23 +0100433 }
Simon Wunderlich52aebd62012-09-08 18:02:53 +0200434
Simon Wunderlichd807f272012-09-09 22:27:57 +0200435 if (own_backbone) {
Simon Wunderlich52aebd62012-09-08 18:02:53 +0200436 batadv_bla_send_announce(bat_priv, entry);
437
Simon Wunderlichd807f272012-09-09 22:27:57 +0200438 /* this will be decreased in the worker thread */
439 atomic_inc(&entry->request_sent);
Simon Wunderlich28709872012-09-13 18:18:46 +0200440 atomic_set(&entry->wait_periods, BATADV_BLA_WAIT_PERIODS);
Simon Wunderlichd807f272012-09-09 22:27:57 +0200441 atomic_inc(&bat_priv->bla.num_requests);
442 }
443
Simon Wunderlich23721382012-01-22 20:00:19 +0100444 return entry;
445}
446
447/* update or add the own backbone gw to make sure we announce
448 * where we receive other backbone gws
449 */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200450static void
451batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,
452 struct batadv_hard_iface *primary_if,
Antonio Quartullieb2deb62013-04-19 18:07:00 +0200453 unsigned short vid)
Simon Wunderlich23721382012-01-22 20:00:19 +0100454{
Marek Lindnerbae98772012-12-25 17:03:24 +0800455 struct batadv_bla_backbone_gw *backbone_gw;
Simon Wunderlich23721382012-01-22 20:00:19 +0100456
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200457 backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
458 primary_if->net_dev->dev_addr,
Simon Wunderlich52aebd62012-09-08 18:02:53 +0200459 vid, true);
Simon Wunderlich23721382012-01-22 20:00:19 +0100460 if (unlikely(!backbone_gw))
461 return;
462
463 backbone_gw->lasttime = jiffies;
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200464 batadv_backbone_gw_free_ref(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +0100465}
466
Simon Wunderlich1b371d12014-01-15 21:17:54 +0100467/**
468 * batadv_bla_answer_request - answer a bla request by sending own claims
469 * @bat_priv: the bat priv with all the soft interface information
Martin Hundebølle3357182014-07-15 09:41:06 +0200470 * @primary_if: interface where the request came on
Simon Wunderlich23721382012-01-22 20:00:19 +0100471 * @vid: the vid where the request came on
472 *
473 * Repeat all of our own claims, and finally send an ANNOUNCE frame
474 * to allow the requester another check if the CRC is correct now.
475 */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200476static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
477 struct batadv_hard_iface *primary_if,
Antonio Quartullieb2deb62013-04-19 18:07:00 +0200478 unsigned short vid)
Simon Wunderlich23721382012-01-22 20:00:19 +0100479{
Simon Wunderlich23721382012-01-22 20:00:19 +0100480 struct hlist_head *head;
Sven Eckelmann5bf74e92012-06-05 22:31:28 +0200481 struct batadv_hashtable *hash;
Marek Lindner712bbfe42012-12-25 17:03:25 +0800482 struct batadv_bla_claim *claim;
Marek Lindnerbae98772012-12-25 17:03:24 +0800483 struct batadv_bla_backbone_gw *backbone_gw;
Simon Wunderlich23721382012-01-22 20:00:19 +0100484 int i;
485
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200486 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200487 "bla_answer_request(): received a claim request, send all of our own claims again\n");
Simon Wunderlich23721382012-01-22 20:00:19 +0100488
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200489 backbone_gw = batadv_backbone_hash_find(bat_priv,
490 primary_if->net_dev->dev_addr,
491 vid);
Simon Wunderlich23721382012-01-22 20:00:19 +0100492 if (!backbone_gw)
493 return;
494
Sven Eckelmann807736f2012-07-15 22:26:51 +0200495 hash = bat_priv->bla.claim_hash;
Simon Wunderlich23721382012-01-22 20:00:19 +0100496 for (i = 0; i < hash->size; i++) {
497 head = &hash->table[i];
498
499 rcu_read_lock();
Sasha Levinb67bfe02013-02-27 17:06:00 -0800500 hlist_for_each_entry_rcu(claim, head, hash_entry) {
Simon Wunderlich23721382012-01-22 20:00:19 +0100501 /* only own claims are interesting */
502 if (claim->backbone_gw != backbone_gw)
503 continue;
504
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200505 batadv_bla_send_claim(bat_priv, claim->addr, claim->vid,
Simon Wunderlich3eb87732012-06-23 12:34:18 +0200506 BATADV_CLAIM_TYPE_CLAIM);
Simon Wunderlich23721382012-01-22 20:00:19 +0100507 }
508 rcu_read_unlock();
509 }
510
511 /* finally, send an announcement frame */
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200512 batadv_bla_send_announce(bat_priv, backbone_gw);
513 batadv_backbone_gw_free_ref(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +0100514}
515
Simon Wunderlich1b371d12014-01-15 21:17:54 +0100516/**
517 * batadv_bla_send_request - send a request to repeat claims
518 * @backbone_gw: the backbone gateway from whom we are out of sync
Simon Wunderlich23721382012-01-22 20:00:19 +0100519 *
520 * When the crc is wrong, ask the backbone gateway for a full table update.
521 * After the request, it will repeat all of his own claims and finally
522 * send an announcement claim with which we can check again.
523 */
Marek Lindnerbae98772012-12-25 17:03:24 +0800524static void batadv_bla_send_request(struct batadv_bla_backbone_gw *backbone_gw)
Simon Wunderlich23721382012-01-22 20:00:19 +0100525{
526 /* first, remove all old entries */
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200527 batadv_bla_del_backbone_claims(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +0100528
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200529 batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
530 "Sending REQUEST to %pM\n", backbone_gw->orig);
Simon Wunderlich23721382012-01-22 20:00:19 +0100531
532 /* send request */
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200533 batadv_bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig,
Sven Eckelmannacd34af2012-06-03 22:19:21 +0200534 backbone_gw->vid, BATADV_CLAIM_TYPE_REQUEST);
Simon Wunderlich23721382012-01-22 20:00:19 +0100535
536 /* no local broadcasts should be sent or received, for now. */
537 if (!atomic_read(&backbone_gw->request_sent)) {
Sven Eckelmann807736f2012-07-15 22:26:51 +0200538 atomic_inc(&backbone_gw->bat_priv->bla.num_requests);
Simon Wunderlich23721382012-01-22 20:00:19 +0100539 atomic_set(&backbone_gw->request_sent, 1);
540 }
541}
542
Simon Wunderlich1b371d12014-01-15 21:17:54 +0100543/**
544 * batadv_bla_send_announce
545 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich23721382012-01-22 20:00:19 +0100546 * @backbone_gw: our backbone gateway which should be announced
547 *
548 * This function sends an announcement. It is called from multiple
549 * places.
550 */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200551static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
Marek Lindnerbae98772012-12-25 17:03:24 +0800552 struct batadv_bla_backbone_gw *backbone_gw)
Simon Wunderlich23721382012-01-22 20:00:19 +0100553{
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200554 u8 mac[ETH_ALEN];
Al Viro3e2f1a12012-04-22 07:47:50 +0100555 __be16 crc;
Simon Wunderlich23721382012-01-22 20:00:19 +0100556
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200557 memcpy(mac, batadv_announce_mac, 4);
Simon Wunderlich23721382012-01-22 20:00:19 +0100558 crc = htons(backbone_gw->crc);
Al Viro1a5852d2012-04-22 07:50:29 +0100559 memcpy(&mac[4], &crc, 2);
Simon Wunderlich23721382012-01-22 20:00:19 +0100560
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200561 batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
Sven Eckelmannacd34af2012-06-03 22:19:21 +0200562 BATADV_CLAIM_TYPE_ANNOUNCE);
Simon Wunderlich23721382012-01-22 20:00:19 +0100563}
564
Ben Hutchings2c530402012-07-10 10:55:09 +0000565/**
566 * batadv_bla_add_claim - Adds a claim in the claim hash
567 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich23721382012-01-22 20:00:19 +0100568 * @mac: the mac address of the claim
569 * @vid: the VLAN ID of the frame
570 * @backbone_gw: the backbone gateway which claims it
Simon Wunderlich23721382012-01-22 20:00:19 +0100571 */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200572static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200573 const u8 *mac, const unsigned short vid,
Marek Lindnerbae98772012-12-25 17:03:24 +0800574 struct batadv_bla_backbone_gw *backbone_gw)
Simon Wunderlich23721382012-01-22 20:00:19 +0100575{
Marek Lindner712bbfe42012-12-25 17:03:25 +0800576 struct batadv_bla_claim *claim;
577 struct batadv_bla_claim search_claim;
Simon Wunderlich23721382012-01-22 20:00:19 +0100578 int hash_added;
579
Antonio Quartulli8fdd0152014-01-22 00:42:11 +0100580 ether_addr_copy(search_claim.addr, mac);
Simon Wunderlich23721382012-01-22 20:00:19 +0100581 search_claim.vid = vid;
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200582 claim = batadv_claim_hash_find(bat_priv, &search_claim);
Simon Wunderlich23721382012-01-22 20:00:19 +0100583
584 /* create a new claim entry if it does not exist yet. */
585 if (!claim) {
586 claim = kzalloc(sizeof(*claim), GFP_ATOMIC);
587 if (!claim)
588 return;
589
Antonio Quartulli8fdd0152014-01-22 00:42:11 +0100590 ether_addr_copy(claim->addr, mac);
Simon Wunderlich23721382012-01-22 20:00:19 +0100591 claim->vid = vid;
592 claim->lasttime = jiffies;
593 claim->backbone_gw = backbone_gw;
594
595 atomic_set(&claim->refcount, 2);
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200596 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200597 "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200598 mac, BATADV_PRINT_VID(vid));
Sven Eckelmann807736f2012-07-15 22:26:51 +0200599 hash_added = batadv_hash_add(bat_priv->bla.claim_hash,
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200600 batadv_compare_claim,
601 batadv_choose_claim, claim,
602 &claim->hash_entry);
Simon Wunderlich23721382012-01-22 20:00:19 +0100603
604 if (unlikely(hash_added != 0)) {
605 /* only local changes happened. */
606 kfree(claim);
607 return;
608 }
609 } else {
610 claim->lasttime = jiffies;
611 if (claim->backbone_gw == backbone_gw)
612 /* no need to register a new backbone */
613 goto claim_free_ref;
614
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200615 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200616 "bla_add_claim(): changing ownership for %pM, vid %d\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200617 mac, BATADV_PRINT_VID(vid));
Simon Wunderlich23721382012-01-22 20:00:19 +0100618
Sven Eckelmannbbb1f902012-07-08 17:13:15 +0200619 claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200620 batadv_backbone_gw_free_ref(claim->backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +0100621 }
622 /* set (new) backbone gw */
623 atomic_inc(&backbone_gw->refcount);
624 claim->backbone_gw = backbone_gw;
625
626 backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
627 backbone_gw->lasttime = jiffies;
628
629claim_free_ref:
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200630 batadv_claim_free_ref(claim);
Simon Wunderlich23721382012-01-22 20:00:19 +0100631}
632
633/* Delete a claim from the claim hash which has the
634 * given mac address and vid.
635 */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200636static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200637 const u8 *mac, const unsigned short vid)
Simon Wunderlich23721382012-01-22 20:00:19 +0100638{
Marek Lindner712bbfe42012-12-25 17:03:25 +0800639 struct batadv_bla_claim search_claim, *claim;
Simon Wunderlich23721382012-01-22 20:00:19 +0100640
Antonio Quartulli8fdd0152014-01-22 00:42:11 +0100641 ether_addr_copy(search_claim.addr, mac);
Simon Wunderlich23721382012-01-22 20:00:19 +0100642 search_claim.vid = vid;
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200643 claim = batadv_claim_hash_find(bat_priv, &search_claim);
Simon Wunderlich23721382012-01-22 20:00:19 +0100644 if (!claim)
645 return;
646
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200647 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200648 mac, BATADV_PRINT_VID(vid));
Simon Wunderlich23721382012-01-22 20:00:19 +0100649
Sven Eckelmann807736f2012-07-15 22:26:51 +0200650 batadv_hash_remove(bat_priv->bla.claim_hash, batadv_compare_claim,
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200651 batadv_choose_claim, claim);
652 batadv_claim_free_ref(claim); /* reference from the hash is gone */
Simon Wunderlich23721382012-01-22 20:00:19 +0100653
654 claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
655
656 /* don't need the reference from hash_find() anymore */
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200657 batadv_claim_free_ref(claim);
Simon Wunderlich23721382012-01-22 20:00:19 +0100658}
659
660/* check for ANNOUNCE frame, return 1 if handled */
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200661static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr,
662 u8 *backbone_addr, unsigned short vid)
Simon Wunderlich23721382012-01-22 20:00:19 +0100663{
Marek Lindnerbae98772012-12-25 17:03:24 +0800664 struct batadv_bla_backbone_gw *backbone_gw;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200665 u16 crc;
Simon Wunderlich23721382012-01-22 20:00:19 +0100666
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200667 if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
Simon Wunderlich23721382012-01-22 20:00:19 +0100668 return 0;
669
Simon Wunderlich52aebd62012-09-08 18:02:53 +0200670 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
671 false);
Simon Wunderlich23721382012-01-22 20:00:19 +0100672
673 if (unlikely(!backbone_gw))
674 return 1;
675
Simon Wunderlich23721382012-01-22 20:00:19 +0100676 /* handle as ANNOUNCE frame */
677 backbone_gw->lasttime = jiffies;
Al Viro3e2f1a12012-04-22 07:47:50 +0100678 crc = ntohs(*((__be16 *)(&an_addr[4])));
Simon Wunderlich23721382012-01-22 20:00:19 +0100679
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200680 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Antonio Quartulli39a32992012-11-19 09:01:43 +0100681 "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200682 BATADV_PRINT_VID(vid), backbone_gw->orig, crc);
Simon Wunderlich23721382012-01-22 20:00:19 +0100683
684 if (backbone_gw->crc != crc) {
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200685 batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
Antonio Quartulli39a32992012-11-19 09:01:43 +0100686 "handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200687 backbone_gw->orig,
688 BATADV_PRINT_VID(backbone_gw->vid),
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200689 backbone_gw->crc, crc);
Simon Wunderlich23721382012-01-22 20:00:19 +0100690
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200691 batadv_bla_send_request(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +0100692 } else {
693 /* if we have sent a request and the crc was OK,
694 * we can allow traffic again.
695 */
696 if (atomic_read(&backbone_gw->request_sent)) {
Sven Eckelmann807736f2012-07-15 22:26:51 +0200697 atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
Simon Wunderlich23721382012-01-22 20:00:19 +0100698 atomic_set(&backbone_gw->request_sent, 0);
699 }
700 }
701
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200702 batadv_backbone_gw_free_ref(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +0100703 return 1;
704}
705
706/* check for REQUEST frame, return 1 if handled */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200707static int batadv_handle_request(struct batadv_priv *bat_priv,
708 struct batadv_hard_iface *primary_if,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200709 u8 *backbone_addr, struct ethhdr *ethhdr,
710 unsigned short vid)
Simon Wunderlich23721382012-01-22 20:00:19 +0100711{
712 /* check for REQUEST frame */
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200713 if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest))
Simon Wunderlich23721382012-01-22 20:00:19 +0100714 return 0;
715
716 /* sanity check, this should not happen on a normal switch,
717 * we ignore it in this case.
718 */
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200719 if (!batadv_compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr))
Simon Wunderlich23721382012-01-22 20:00:19 +0100720 return 1;
721
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200722 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200723 "handle_request(): REQUEST vid %d (sent by %pM)...\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200724 BATADV_PRINT_VID(vid), ethhdr->h_source);
Simon Wunderlich23721382012-01-22 20:00:19 +0100725
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200726 batadv_bla_answer_request(bat_priv, primary_if, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +0100727 return 1;
728}
729
730/* check for UNCLAIM frame, return 1 if handled */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200731static int batadv_handle_unclaim(struct batadv_priv *bat_priv,
732 struct batadv_hard_iface *primary_if,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200733 u8 *backbone_addr, u8 *claim_addr,
734 unsigned short vid)
Simon Wunderlich23721382012-01-22 20:00:19 +0100735{
Marek Lindnerbae98772012-12-25 17:03:24 +0800736 struct batadv_bla_backbone_gw *backbone_gw;
Simon Wunderlich23721382012-01-22 20:00:19 +0100737
738 /* unclaim in any case if it is our own */
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200739 if (primary_if && batadv_compare_eth(backbone_addr,
740 primary_if->net_dev->dev_addr))
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200741 batadv_bla_send_claim(bat_priv, claim_addr, vid,
Simon Wunderlich3eb87732012-06-23 12:34:18 +0200742 BATADV_CLAIM_TYPE_UNCLAIM);
Simon Wunderlich23721382012-01-22 20:00:19 +0100743
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200744 backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +0100745
746 if (!backbone_gw)
747 return 1;
748
749 /* this must be an UNCLAIM frame */
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200750 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200751 "handle_unclaim(): UNCLAIM %pM on vid %d (sent by %pM)...\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200752 claim_addr, BATADV_PRINT_VID(vid), backbone_gw->orig);
Simon Wunderlich23721382012-01-22 20:00:19 +0100753
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200754 batadv_bla_del_claim(bat_priv, claim_addr, vid);
755 batadv_backbone_gw_free_ref(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +0100756 return 1;
757}
758
759/* check for CLAIM frame, return 1 if handled */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200760static int batadv_handle_claim(struct batadv_priv *bat_priv,
761 struct batadv_hard_iface *primary_if,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200762 u8 *backbone_addr, u8 *claim_addr,
Antonio Quartullieb2deb62013-04-19 18:07:00 +0200763 unsigned short vid)
Simon Wunderlich23721382012-01-22 20:00:19 +0100764{
Marek Lindnerbae98772012-12-25 17:03:24 +0800765 struct batadv_bla_backbone_gw *backbone_gw;
Simon Wunderlich23721382012-01-22 20:00:19 +0100766
767 /* register the gateway if not yet available, and add the claim. */
768
Simon Wunderlich52aebd62012-09-08 18:02:53 +0200769 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
770 false);
Simon Wunderlich23721382012-01-22 20:00:19 +0100771
772 if (unlikely(!backbone_gw))
773 return 1;
774
775 /* this must be a CLAIM frame */
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200776 batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw);
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200777 if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200778 batadv_bla_send_claim(bat_priv, claim_addr, vid,
Simon Wunderlich3eb87732012-06-23 12:34:18 +0200779 BATADV_CLAIM_TYPE_CLAIM);
Simon Wunderlich23721382012-01-22 20:00:19 +0100780
781 /* TODO: we could call something like tt_local_del() here. */
782
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200783 batadv_backbone_gw_free_ref(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +0100784 return 1;
785}
786
Ben Hutchings2c530402012-07-10 10:55:09 +0000787/**
788 * batadv_check_claim_group
789 * @bat_priv: the bat priv with all the soft interface information
Martin Hundebølle3357182014-07-15 09:41:06 +0200790 * @primary_if: the primary interface of this batman interface
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100791 * @hw_src: the Hardware source in the ARP Header
792 * @hw_dst: the Hardware destination in the ARP Header
793 * @ethhdr: pointer to the Ethernet header of the claim frame
794 *
795 * checks if it is a claim packet and if its on the same group.
796 * This function also applies the group ID of the sender
797 * if it is in the same mesh.
798 *
799 * returns:
800 * 2 - if it is a claim packet and on the same group
801 * 1 - if is a claim packet from another group
802 * 0 - if it is not a claim packet
803 */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200804static int batadv_check_claim_group(struct batadv_priv *bat_priv,
805 struct batadv_hard_iface *primary_if,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200806 u8 *hw_src, u8 *hw_dst,
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200807 struct ethhdr *ethhdr)
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100808{
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200809 u8 *backbone_addr;
Sven Eckelmann56303d32012-06-05 22:31:31 +0200810 struct batadv_orig_node *orig_node;
Sven Eckelmann96412692012-06-05 22:31:30 +0200811 struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100812
Sven Eckelmann96412692012-06-05 22:31:30 +0200813 bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
Sven Eckelmann807736f2012-07-15 22:26:51 +0200814 bla_dst_own = &bat_priv->bla.claim_dest;
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100815
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100816 /* if announcement packet, use the source,
817 * otherwise assume it is in the hw_src
818 */
819 switch (bla_dst->type) {
Simon Wunderlich3eb87732012-06-23 12:34:18 +0200820 case BATADV_CLAIM_TYPE_CLAIM:
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100821 backbone_addr = hw_src;
822 break;
Sven Eckelmannacd34af2012-06-03 22:19:21 +0200823 case BATADV_CLAIM_TYPE_REQUEST:
824 case BATADV_CLAIM_TYPE_ANNOUNCE:
Simon Wunderlich3eb87732012-06-23 12:34:18 +0200825 case BATADV_CLAIM_TYPE_UNCLAIM:
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100826 backbone_addr = ethhdr->h_source;
827 break;
828 default:
829 return 0;
830 }
831
832 /* don't accept claim frames from ourselves */
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200833 if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100834 return 0;
835
836 /* if its already the same group, it is fine. */
837 if (bla_dst->group == bla_dst_own->group)
838 return 2;
839
840 /* lets see if this originator is in our mesh */
Sven Eckelmannda641192012-05-12 13:48:56 +0200841 orig_node = batadv_orig_hash_find(bat_priv, backbone_addr);
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100842
843 /* dont accept claims from gateways which are not in
844 * the same mesh or group.
845 */
846 if (!orig_node)
847 return 1;
848
849 /* if our mesh friends mac is bigger, use it for ourselves. */
850 if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) {
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200851 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Antonio Quartulli39a32992012-11-19 09:01:43 +0100852 "taking other backbones claim group: %#.4x\n",
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200853 ntohs(bla_dst->group));
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100854 bla_dst_own->group = bla_dst->group;
855 }
856
Sven Eckelmann7d211ef2012-05-12 02:09:34 +0200857 batadv_orig_node_free_ref(orig_node);
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100858
859 return 2;
860}
861
Simon Wunderlich1b371d12014-01-15 21:17:54 +0100862/**
863 * batadv_bla_process_claim
864 * @bat_priv: the bat priv with all the soft interface information
Martin Hundebølle3357182014-07-15 09:41:06 +0200865 * @primary_if: the primary hard interface of this batman soft interface
Simon Wunderlich23721382012-01-22 20:00:19 +0100866 * @skb: the frame to be checked
867 *
868 * Check if this is a claim frame, and process it accordingly.
869 *
870 * returns 1 if it was a claim frame, otherwise return 0 to
871 * tell the callee that it can use the frame on its own.
872 */
Sven Eckelmann56303d32012-06-05 22:31:31 +0200873static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
874 struct batadv_hard_iface *primary_if,
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200875 struct sk_buff *skb)
Simon Wunderlich23721382012-01-22 20:00:19 +0100876{
Simon Wunderlichd46b6bf2014-06-23 15:55:36 +0200877 struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200878 u8 *hw_src, *hw_dst;
Simon Wunderlichd46b6bf2014-06-23 15:55:36 +0200879 struct vlan_hdr *vhdr, vhdr_buf;
Antonio Quartullic018ad32013-06-04 12:11:39 +0200880 struct ethhdr *ethhdr;
881 struct arphdr *arphdr;
882 unsigned short vid;
Simon Wunderlichd46b6bf2014-06-23 15:55:36 +0200883 int vlan_depth = 0;
Antonio Quartulli293e9332013-05-19 12:55:16 +0200884 __be16 proto;
Simon Wunderlich23721382012-01-22 20:00:19 +0100885 int headlen;
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100886 int ret;
Simon Wunderlich23721382012-01-22 20:00:19 +0100887
Antonio Quartullic018ad32013-06-04 12:11:39 +0200888 vid = batadv_get_vid(skb, 0);
Antonio Quartulli7ed4be92013-04-08 15:08:18 +0200889 ethhdr = eth_hdr(skb);
Simon Wunderlich23721382012-01-22 20:00:19 +0100890
Antonio Quartullic018ad32013-06-04 12:11:39 +0200891 proto = ethhdr->h_proto;
892 headlen = ETH_HLEN;
893 if (vid & BATADV_VLAN_HAS_TAG) {
Simon Wunderlichd46b6bf2014-06-23 15:55:36 +0200894 /* Traverse the VLAN/Ethertypes.
895 *
896 * At this point it is known that the first protocol is a VLAN
897 * header, so start checking at the encapsulated protocol.
898 *
899 * The depth of the VLAN headers is recorded to drop BLA claim
900 * frames encapsulated into multiple VLAN headers (QinQ).
901 */
902 do {
903 vhdr = skb_header_pointer(skb, headlen, VLAN_HLEN,
904 &vhdr_buf);
905 if (!vhdr)
906 return 0;
907
908 proto = vhdr->h_vlan_encapsulated_proto;
909 headlen += VLAN_HLEN;
910 vlan_depth++;
911 } while (proto == htons(ETH_P_8021Q));
Simon Wunderlich23721382012-01-22 20:00:19 +0100912 }
913
Antonio Quartulli293e9332013-05-19 12:55:16 +0200914 if (proto != htons(ETH_P_ARP))
Simon Wunderlich23721382012-01-22 20:00:19 +0100915 return 0; /* not a claim frame */
916
917 /* this must be a ARP frame. check if it is a claim. */
918
919 if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev))))
920 return 0;
921
922 /* pskb_may_pull() may have modified the pointers, get ethhdr again */
Antonio Quartulli7ed4be92013-04-08 15:08:18 +0200923 ethhdr = eth_hdr(skb);
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200924 arphdr = (struct arphdr *)((u8 *)ethhdr + headlen);
Simon Wunderlich23721382012-01-22 20:00:19 +0100925
926 /* Check whether the ARP frame carries a valid
927 * IP information
928 */
Simon Wunderlich23721382012-01-22 20:00:19 +0100929 if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
930 return 0;
931 if (arphdr->ar_pro != htons(ETH_P_IP))
932 return 0;
933 if (arphdr->ar_hln != ETH_ALEN)
934 return 0;
935 if (arphdr->ar_pln != 4)
936 return 0;
937
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200938 hw_src = (u8 *)arphdr + sizeof(struct arphdr);
Simon Wunderlich23721382012-01-22 20:00:19 +0100939 hw_dst = hw_src + ETH_ALEN + 4;
Sven Eckelmann96412692012-06-05 22:31:30 +0200940 bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
Simon Wunderlichd46b6bf2014-06-23 15:55:36 +0200941 bla_dst_own = &bat_priv->bla.claim_dest;
942
943 /* check if it is a claim frame in general */
944 if (memcmp(bla_dst->magic, bla_dst_own->magic,
945 sizeof(bla_dst->magic)) != 0)
946 return 0;
947
948 /* check if there is a claim frame encapsulated deeper in (QinQ) and
949 * drop that, as this is not supported by BLA but should also not be
950 * sent via the mesh.
951 */
952 if (vlan_depth > 1)
953 return 1;
Simon Wunderlich23721382012-01-22 20:00:19 +0100954
955 /* check if it is a claim frame. */
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200956 ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst,
957 ethhdr);
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100958 if (ret == 1)
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200959 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200960 "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200961 ethhdr->h_source, BATADV_PRINT_VID(vid), hw_src,
962 hw_dst);
Simon Wunderlich38ef3d12012-01-22 20:00:26 +0100963
964 if (ret < 2)
965 return ret;
Simon Wunderlich23721382012-01-22 20:00:19 +0100966
967 /* become a backbone gw ourselves on this vlan if not happened yet */
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200968 batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +0100969
970 /* check for the different types of claim frames ... */
971 switch (bla_dst->type) {
Simon Wunderlich3eb87732012-06-23 12:34:18 +0200972 case BATADV_CLAIM_TYPE_CLAIM:
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200973 if (batadv_handle_claim(bat_priv, primary_if, hw_src,
974 ethhdr->h_source, vid))
Simon Wunderlich23721382012-01-22 20:00:19 +0100975 return 1;
976 break;
Simon Wunderlich3eb87732012-06-23 12:34:18 +0200977 case BATADV_CLAIM_TYPE_UNCLAIM:
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200978 if (batadv_handle_unclaim(bat_priv, primary_if,
979 ethhdr->h_source, hw_src, vid))
Simon Wunderlich23721382012-01-22 20:00:19 +0100980 return 1;
981 break;
982
Sven Eckelmannacd34af2012-06-03 22:19:21 +0200983 case BATADV_CLAIM_TYPE_ANNOUNCE:
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200984 if (batadv_handle_announce(bat_priv, hw_src, ethhdr->h_source,
985 vid))
Simon Wunderlich23721382012-01-22 20:00:19 +0100986 return 1;
987 break;
Sven Eckelmannacd34af2012-06-03 22:19:21 +0200988 case BATADV_CLAIM_TYPE_REQUEST:
Sven Eckelmann3b300de2012-05-12 18:33:53 +0200989 if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr,
990 vid))
Simon Wunderlich23721382012-01-22 20:00:19 +0100991 return 1;
992 break;
993 }
994
Sven Eckelmann39c75a52012-06-03 22:19:22 +0200995 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +0200996 "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +0200997 ethhdr->h_source, BATADV_PRINT_VID(vid), hw_src, hw_dst);
Simon Wunderlich23721382012-01-22 20:00:19 +0100998 return 1;
999}
1000
1001/* Check when we last heard from other nodes, and remove them in case of
1002 * a time out, or clean all backbone gws if now is set.
1003 */
Sven Eckelmann56303d32012-06-05 22:31:31 +02001004static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
Simon Wunderlich23721382012-01-22 20:00:19 +01001005{
Marek Lindnerbae98772012-12-25 17:03:24 +08001006 struct batadv_bla_backbone_gw *backbone_gw;
Sasha Levinb67bfe02013-02-27 17:06:00 -08001007 struct hlist_node *node_tmp;
Simon Wunderlich23721382012-01-22 20:00:19 +01001008 struct hlist_head *head;
Sven Eckelmann5bf74e92012-06-05 22:31:28 +02001009 struct batadv_hashtable *hash;
Simon Wunderlich23721382012-01-22 20:00:19 +01001010 spinlock_t *list_lock; /* protects write access to the hash lists */
1011 int i;
1012
Sven Eckelmann807736f2012-07-15 22:26:51 +02001013 hash = bat_priv->bla.backbone_hash;
Simon Wunderlich23721382012-01-22 20:00:19 +01001014 if (!hash)
1015 return;
1016
1017 for (i = 0; i < hash->size; i++) {
1018 head = &hash->table[i];
1019 list_lock = &hash->list_locks[i];
1020
1021 spin_lock_bh(list_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -08001022 hlist_for_each_entry_safe(backbone_gw, node_tmp,
Simon Wunderlich23721382012-01-22 20:00:19 +01001023 head, hash_entry) {
1024 if (now)
1025 goto purge_now;
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001026 if (!batadv_has_timed_out(backbone_gw->lasttime,
Sven Eckelmann42d0b042012-06-03 22:19:17 +02001027 BATADV_BLA_BACKBONE_TIMEOUT))
Simon Wunderlich23721382012-01-22 20:00:19 +01001028 continue;
1029
Sven Eckelmann39c75a52012-06-03 22:19:22 +02001030 batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001031 "bla_purge_backbone_gw(): backbone gw %pM timed out\n",
1032 backbone_gw->orig);
Simon Wunderlich23721382012-01-22 20:00:19 +01001033
1034purge_now:
1035 /* don't wait for the pending request anymore */
1036 if (atomic_read(&backbone_gw->request_sent))
Sven Eckelmann807736f2012-07-15 22:26:51 +02001037 atomic_dec(&bat_priv->bla.num_requests);
Simon Wunderlich23721382012-01-22 20:00:19 +01001038
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001039 batadv_bla_del_backbone_claims(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +01001040
Sasha Levinb67bfe02013-02-27 17:06:00 -08001041 hlist_del_rcu(&backbone_gw->hash_entry);
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001042 batadv_backbone_gw_free_ref(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +01001043 }
1044 spin_unlock_bh(list_lock);
1045 }
1046}
1047
Ben Hutchings2c530402012-07-10 10:55:09 +00001048/**
1049 * batadv_bla_purge_claims
1050 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich23721382012-01-22 20:00:19 +01001051 * @primary_if: the selected primary interface, may be NULL if now is set
1052 * @now: whether the whole hash shall be wiped now
1053 *
1054 * Check when we heard last time from our own claims, and remove them in case of
1055 * a time out, or clean all claims if now is set
1056 */
Sven Eckelmann56303d32012-06-05 22:31:31 +02001057static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
1058 struct batadv_hard_iface *primary_if,
1059 int now)
Simon Wunderlich23721382012-01-22 20:00:19 +01001060{
Marek Lindner712bbfe42012-12-25 17:03:25 +08001061 struct batadv_bla_claim *claim;
Simon Wunderlich23721382012-01-22 20:00:19 +01001062 struct hlist_head *head;
Sven Eckelmann5bf74e92012-06-05 22:31:28 +02001063 struct batadv_hashtable *hash;
Simon Wunderlich23721382012-01-22 20:00:19 +01001064 int i;
1065
Sven Eckelmann807736f2012-07-15 22:26:51 +02001066 hash = bat_priv->bla.claim_hash;
Simon Wunderlich23721382012-01-22 20:00:19 +01001067 if (!hash)
1068 return;
1069
1070 for (i = 0; i < hash->size; i++) {
1071 head = &hash->table[i];
1072
1073 rcu_read_lock();
Sasha Levinb67bfe02013-02-27 17:06:00 -08001074 hlist_for_each_entry_rcu(claim, head, hash_entry) {
Simon Wunderlich23721382012-01-22 20:00:19 +01001075 if (now)
1076 goto purge_now;
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001077 if (!batadv_compare_eth(claim->backbone_gw->orig,
1078 primary_if->net_dev->dev_addr))
Simon Wunderlich23721382012-01-22 20:00:19 +01001079 continue;
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001080 if (!batadv_has_timed_out(claim->lasttime,
Sven Eckelmann42d0b042012-06-03 22:19:17 +02001081 BATADV_BLA_CLAIM_TIMEOUT))
Simon Wunderlich23721382012-01-22 20:00:19 +01001082 continue;
1083
Sven Eckelmann39c75a52012-06-03 22:19:22 +02001084 batadv_dbg(BATADV_DBG_BLA, bat_priv,
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001085 "bla_purge_claims(): %pM, vid %d, time out\n",
1086 claim->addr, claim->vid);
Simon Wunderlich23721382012-01-22 20:00:19 +01001087
1088purge_now:
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001089 batadv_handle_unclaim(bat_priv, primary_if,
1090 claim->backbone_gw->orig,
1091 claim->addr, claim->vid);
Simon Wunderlich23721382012-01-22 20:00:19 +01001092 }
1093 rcu_read_unlock();
1094 }
1095}
1096
Ben Hutchings2c530402012-07-10 10:55:09 +00001097/**
1098 * batadv_bla_update_orig_address
1099 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich23721382012-01-22 20:00:19 +01001100 * @primary_if: the new selected primary_if
1101 * @oldif: the old primary interface, may be NULL
1102 *
1103 * Update the backbone gateways when the own orig address changes.
Simon Wunderlich23721382012-01-22 20:00:19 +01001104 */
Sven Eckelmann56303d32012-06-05 22:31:31 +02001105void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
1106 struct batadv_hard_iface *primary_if,
1107 struct batadv_hard_iface *oldif)
Simon Wunderlich23721382012-01-22 20:00:19 +01001108{
Marek Lindnerbae98772012-12-25 17:03:24 +08001109 struct batadv_bla_backbone_gw *backbone_gw;
Simon Wunderlich23721382012-01-22 20:00:19 +01001110 struct hlist_head *head;
Sven Eckelmann5bf74e92012-06-05 22:31:28 +02001111 struct batadv_hashtable *hash;
Sven Eckelmann807736f2012-07-15 22:26:51 +02001112 __be16 group;
Simon Wunderlich23721382012-01-22 20:00:19 +01001113 int i;
1114
Simon Wunderlich38ef3d12012-01-22 20:00:26 +01001115 /* reset bridge loop avoidance group id */
Sven Eckelmann807736f2012-07-15 22:26:51 +02001116 group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN));
1117 bat_priv->bla.claim_dest.group = group;
Simon Wunderlich38ef3d12012-01-22 20:00:26 +01001118
Simon Wunderlichd5b4c932013-06-07 16:52:05 +02001119 /* purge everything when bridge loop avoidance is turned off */
1120 if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1121 oldif = NULL;
1122
Simon Wunderlich23721382012-01-22 20:00:19 +01001123 if (!oldif) {
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001124 batadv_bla_purge_claims(bat_priv, NULL, 1);
1125 batadv_bla_purge_backbone_gw(bat_priv, 1);
Simon Wunderlich23721382012-01-22 20:00:19 +01001126 return;
1127 }
1128
Sven Eckelmann807736f2012-07-15 22:26:51 +02001129 hash = bat_priv->bla.backbone_hash;
Simon Wunderlich23721382012-01-22 20:00:19 +01001130 if (!hash)
1131 return;
1132
1133 for (i = 0; i < hash->size; i++) {
1134 head = &hash->table[i];
1135
1136 rcu_read_lock();
Sasha Levinb67bfe02013-02-27 17:06:00 -08001137 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
Simon Wunderlich23721382012-01-22 20:00:19 +01001138 /* own orig still holds the old value. */
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001139 if (!batadv_compare_eth(backbone_gw->orig,
1140 oldif->net_dev->dev_addr))
Simon Wunderlich23721382012-01-22 20:00:19 +01001141 continue;
1142
Antonio Quartulli8fdd0152014-01-22 00:42:11 +01001143 ether_addr_copy(backbone_gw->orig,
1144 primary_if->net_dev->dev_addr);
Simon Wunderlich23721382012-01-22 20:00:19 +01001145 /* send an announce frame so others will ask for our
1146 * claims and update their tables.
1147 */
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001148 batadv_bla_send_announce(bat_priv, backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +01001149 }
1150 rcu_read_unlock();
1151 }
1152}
1153
Simon Wunderlich23721382012-01-22 20:00:19 +01001154/* periodic work to do:
1155 * * purge structures when they are too old
1156 * * send announcements
1157 */
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001158static void batadv_bla_periodic_work(struct work_struct *work)
Simon Wunderlich23721382012-01-22 20:00:19 +01001159{
Sven Eckelmannbbb1f902012-07-08 17:13:15 +02001160 struct delayed_work *delayed_work;
Sven Eckelmann56303d32012-06-05 22:31:31 +02001161 struct batadv_priv *bat_priv;
Sven Eckelmann807736f2012-07-15 22:26:51 +02001162 struct batadv_priv_bla *priv_bla;
Simon Wunderlich23721382012-01-22 20:00:19 +01001163 struct hlist_head *head;
Marek Lindnerbae98772012-12-25 17:03:24 +08001164 struct batadv_bla_backbone_gw *backbone_gw;
Sven Eckelmann5bf74e92012-06-05 22:31:28 +02001165 struct batadv_hashtable *hash;
Sven Eckelmann56303d32012-06-05 22:31:31 +02001166 struct batadv_hard_iface *primary_if;
Simon Wunderlich23721382012-01-22 20:00:19 +01001167 int i;
1168
Sven Eckelmannbbb1f902012-07-08 17:13:15 +02001169 delayed_work = container_of(work, struct delayed_work, work);
Sven Eckelmann807736f2012-07-15 22:26:51 +02001170 priv_bla = container_of(delayed_work, struct batadv_priv_bla, work);
1171 bat_priv = container_of(priv_bla, struct batadv_priv, bla);
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001172 primary_if = batadv_primary_if_get_selected(bat_priv);
Simon Wunderlich23721382012-01-22 20:00:19 +01001173 if (!primary_if)
1174 goto out;
1175
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001176 batadv_bla_purge_claims(bat_priv, primary_if, 0);
1177 batadv_bla_purge_backbone_gw(bat_priv, 0);
Simon Wunderlich23721382012-01-22 20:00:19 +01001178
1179 if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1180 goto out;
1181
Sven Eckelmann807736f2012-07-15 22:26:51 +02001182 hash = bat_priv->bla.backbone_hash;
Simon Wunderlich23721382012-01-22 20:00:19 +01001183 if (!hash)
1184 goto out;
1185
1186 for (i = 0; i < hash->size; i++) {
1187 head = &hash->table[i];
1188
1189 rcu_read_lock();
Sasha Levinb67bfe02013-02-27 17:06:00 -08001190 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001191 if (!batadv_compare_eth(backbone_gw->orig,
1192 primary_if->net_dev->dev_addr))
Simon Wunderlich23721382012-01-22 20:00:19 +01001193 continue;
1194
1195 backbone_gw->lasttime = jiffies;
1196
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001197 batadv_bla_send_announce(bat_priv, backbone_gw);
Simon Wunderlichd807f272012-09-09 22:27:57 +02001198
1199 /* request_sent is only set after creation to avoid
1200 * problems when we are not yet known as backbone gw
1201 * in the backbone.
1202 *
Simon Wunderlich28709872012-09-13 18:18:46 +02001203 * We can reset this now after we waited some periods
1204 * to give bridge forward delays and bla group forming
1205 * some grace time.
Simon Wunderlichd807f272012-09-09 22:27:57 +02001206 */
1207
1208 if (atomic_read(&backbone_gw->request_sent) == 0)
1209 continue;
1210
Simon Wunderlich28709872012-09-13 18:18:46 +02001211 if (!atomic_dec_and_test(&backbone_gw->wait_periods))
1212 continue;
1213
Simon Wunderlichd807f272012-09-09 22:27:57 +02001214 atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
1215 atomic_set(&backbone_gw->request_sent, 0);
Simon Wunderlich23721382012-01-22 20:00:19 +01001216 }
1217 rcu_read_unlock();
1218 }
1219out:
1220 if (primary_if)
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001221 batadv_hardif_free_ref(primary_if);
Simon Wunderlich23721382012-01-22 20:00:19 +01001222
Antonio Quartulli72414442012-12-25 13:14:37 +01001223 queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work,
1224 msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH));
Simon Wunderlich23721382012-01-22 20:00:19 +01001225}
1226
Sven Eckelmann5d52dad2012-03-29 12:38:20 +02001227/* The hash for claim and backbone hash receive the same key because they
1228 * are getting initialized by hash_new with the same key. Reinitializing
1229 * them with to different keys to allow nested locking without generating
1230 * lockdep warnings
1231 */
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001232static struct lock_class_key batadv_claim_hash_lock_class_key;
1233static struct lock_class_key batadv_backbone_hash_lock_class_key;
Sven Eckelmann5d52dad2012-03-29 12:38:20 +02001234
Simon Wunderlich23721382012-01-22 20:00:19 +01001235/* initialize all bla structures */
Sven Eckelmann56303d32012-06-05 22:31:31 +02001236int batadv_bla_init(struct batadv_priv *bat_priv)
Simon Wunderlich23721382012-01-22 20:00:19 +01001237{
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001238 int i;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001239 u8 claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
Sven Eckelmann56303d32012-06-05 22:31:31 +02001240 struct batadv_hard_iface *primary_if;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001241 u16 crc;
Sven Eckelmann807736f2012-07-15 22:26:51 +02001242 unsigned long entrytime;
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001243
Linus Lüssing7dac7b72012-10-17 14:53:05 +02001244 spin_lock_init(&bat_priv->bla.bcast_duplist_lock);
1245
Sven Eckelmann39c75a52012-06-03 22:19:22 +02001246 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n");
Simon Wunderlich23721382012-01-22 20:00:19 +01001247
Simon Wunderlich38ef3d12012-01-22 20:00:26 +01001248 /* setting claim destination address */
Sven Eckelmann807736f2012-07-15 22:26:51 +02001249 memcpy(&bat_priv->bla.claim_dest.magic, claim_dest, 3);
1250 bat_priv->bla.claim_dest.type = 0;
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001251 primary_if = batadv_primary_if_get_selected(bat_priv);
Simon Wunderlich38ef3d12012-01-22 20:00:26 +01001252 if (primary_if) {
Sven Eckelmann807736f2012-07-15 22:26:51 +02001253 crc = crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN);
1254 bat_priv->bla.claim_dest.group = htons(crc);
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001255 batadv_hardif_free_ref(primary_if);
Simon Wunderlich38ef3d12012-01-22 20:00:26 +01001256 } else {
Sven Eckelmann807736f2012-07-15 22:26:51 +02001257 bat_priv->bla.claim_dest.group = 0; /* will be set later */
Simon Wunderlich38ef3d12012-01-22 20:00:26 +01001258 }
1259
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001260 /* initialize the duplicate list */
Sven Eckelmann807736f2012-07-15 22:26:51 +02001261 entrytime = jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT);
Sven Eckelmann42d0b042012-06-03 22:19:17 +02001262 for (i = 0; i < BATADV_DUPLIST_SIZE; i++)
Sven Eckelmann807736f2012-07-15 22:26:51 +02001263 bat_priv->bla.bcast_duplist[i].entrytime = entrytime;
1264 bat_priv->bla.bcast_duplist_curr = 0;
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001265
Sven Eckelmann807736f2012-07-15 22:26:51 +02001266 if (bat_priv->bla.claim_hash)
Sven Eckelmann5346c352012-05-05 13:27:28 +02001267 return 0;
Simon Wunderlich23721382012-01-22 20:00:19 +01001268
Sven Eckelmann807736f2012-07-15 22:26:51 +02001269 bat_priv->bla.claim_hash = batadv_hash_new(128);
1270 bat_priv->bla.backbone_hash = batadv_hash_new(32);
Simon Wunderlich23721382012-01-22 20:00:19 +01001271
Sven Eckelmann807736f2012-07-15 22:26:51 +02001272 if (!bat_priv->bla.claim_hash || !bat_priv->bla.backbone_hash)
Sven Eckelmann5346c352012-05-05 13:27:28 +02001273 return -ENOMEM;
Simon Wunderlich23721382012-01-22 20:00:19 +01001274
Sven Eckelmann807736f2012-07-15 22:26:51 +02001275 batadv_hash_set_lock_class(bat_priv->bla.claim_hash,
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001276 &batadv_claim_hash_lock_class_key);
Sven Eckelmann807736f2012-07-15 22:26:51 +02001277 batadv_hash_set_lock_class(bat_priv->bla.backbone_hash,
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001278 &batadv_backbone_hash_lock_class_key);
Sven Eckelmann5d52dad2012-03-29 12:38:20 +02001279
Sven Eckelmann39c75a52012-06-03 22:19:22 +02001280 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hashes initialized\n");
Simon Wunderlich23721382012-01-22 20:00:19 +01001281
Antonio Quartulli72414442012-12-25 13:14:37 +01001282 INIT_DELAYED_WORK(&bat_priv->bla.work, batadv_bla_periodic_work);
1283
1284 queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work,
1285 msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH));
Sven Eckelmann5346c352012-05-05 13:27:28 +02001286 return 0;
Simon Wunderlich23721382012-01-22 20:00:19 +01001287}
1288
Ben Hutchings2c530402012-07-10 10:55:09 +00001289/**
1290 * batadv_bla_check_bcast_duplist
1291 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich004e86f2012-10-18 13:47:42 +02001292 * @skb: contains the bcast_packet to be checked
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001293 *
1294 * check if it is on our broadcast list. Another gateway might
1295 * have sent the same packet because it is connected to the same backbone,
1296 * so we have to remove this duplicate.
1297 *
1298 * This is performed by checking the CRC, which will tell us
1299 * with a good chance that it is the same packet. If it is furthermore
1300 * sent by another host, drop it. We allow equal packets from
1301 * the same host however as this might be intended.
Sven Eckelmann9cfc7bd2012-05-12 02:09:43 +02001302 */
Sven Eckelmann56303d32012-06-05 22:31:31 +02001303int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
Simon Wunderlich004e86f2012-10-18 13:47:42 +02001304 struct sk_buff *skb)
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001305{
Simon Wunderlich004e86f2012-10-18 13:47:42 +02001306 int i, curr, ret = 0;
1307 __be32 crc;
1308 struct batadv_bcast_packet *bcast_packet;
Sven Eckelmann56303d32012-06-05 22:31:31 +02001309 struct batadv_bcast_duplist_entry *entry;
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001310
Simon Wunderlich004e86f2012-10-18 13:47:42 +02001311 bcast_packet = (struct batadv_bcast_packet *)skb->data;
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001312
1313 /* calculate the crc ... */
Simon Wunderlich004e86f2012-10-18 13:47:42 +02001314 crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001315
Linus Lüssing7dac7b72012-10-17 14:53:05 +02001316 spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
1317
Sven Eckelmann42d0b042012-06-03 22:19:17 +02001318 for (i = 0; i < BATADV_DUPLIST_SIZE; i++) {
Sven Eckelmann807736f2012-07-15 22:26:51 +02001319 curr = (bat_priv->bla.bcast_duplist_curr + i);
1320 curr %= BATADV_DUPLIST_SIZE;
1321 entry = &bat_priv->bla.bcast_duplist[curr];
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001322
1323 /* we can stop searching if the entry is too old ;
1324 * later entries will be even older
1325 */
Sven Eckelmann42d0b042012-06-03 22:19:17 +02001326 if (batadv_has_timed_out(entry->entrytime,
1327 BATADV_DUPLIST_TIMEOUT))
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001328 break;
1329
1330 if (entry->crc != crc)
1331 continue;
1332
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001333 if (batadv_compare_eth(entry->orig, bcast_packet->orig))
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001334 continue;
1335
1336 /* this entry seems to match: same crc, not too old,
1337 * and from another gw. therefore return 1 to forbid it.
1338 */
Linus Lüssing7dac7b72012-10-17 14:53:05 +02001339 ret = 1;
1340 goto out;
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001341 }
Linus Lüssing7dac7b72012-10-17 14:53:05 +02001342 /* not found, add a new entry (overwrite the oldest entry)
Antonio Quartulli3f687852014-11-02 11:29:56 +01001343 * and allow it, its the first occurrence.
Linus Lüssing7dac7b72012-10-17 14:53:05 +02001344 */
Sven Eckelmann807736f2012-07-15 22:26:51 +02001345 curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1);
Sven Eckelmann42d0b042012-06-03 22:19:17 +02001346 curr %= BATADV_DUPLIST_SIZE;
Sven Eckelmann807736f2012-07-15 22:26:51 +02001347 entry = &bat_priv->bla.bcast_duplist[curr];
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001348 entry->crc = crc;
1349 entry->entrytime = jiffies;
Antonio Quartulli8fdd0152014-01-22 00:42:11 +01001350 ether_addr_copy(entry->orig, bcast_packet->orig);
Sven Eckelmann807736f2012-07-15 22:26:51 +02001351 bat_priv->bla.bcast_duplist_curr = curr;
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001352
Linus Lüssing7dac7b72012-10-17 14:53:05 +02001353out:
1354 spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock);
1355
1356 return ret;
Simon Wunderlichfe2da6f2012-01-22 20:00:24 +01001357}
1358
Simon Wunderlich1b371d12014-01-15 21:17:54 +01001359/**
1360 * batadv_bla_is_backbone_gw_orig
1361 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001362 * @orig: originator mac address
Antonio Quartullicfd4f752013-08-07 18:28:56 +02001363 * @vid: VLAN identifier
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001364 *
Antonio Quartullicfd4f752013-08-07 18:28:56 +02001365 * Check if the originator is a gateway for the VLAN identified by vid.
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001366 *
Antonio Quartullicfd4f752013-08-07 18:28:56 +02001367 * Returns true if orig is a backbone for this vid, false otherwise.
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001368 */
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001369bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig,
Antonio Quartullicfd4f752013-08-07 18:28:56 +02001370 unsigned short vid)
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001371{
Sven Eckelmann807736f2012-07-15 22:26:51 +02001372 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001373 struct hlist_head *head;
Marek Lindnerbae98772012-12-25 17:03:24 +08001374 struct batadv_bla_backbone_gw *backbone_gw;
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001375 int i;
1376
1377 if (!atomic_read(&bat_priv->bridge_loop_avoidance))
Antonio Quartullicfd4f752013-08-07 18:28:56 +02001378 return false;
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001379
1380 if (!hash)
Antonio Quartullicfd4f752013-08-07 18:28:56 +02001381 return false;
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001382
1383 for (i = 0; i < hash->size; i++) {
1384 head = &hash->table[i];
1385
1386 rcu_read_lock();
Sasha Levinb67bfe02013-02-27 17:06:00 -08001387 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
Antonio Quartullicfd4f752013-08-07 18:28:56 +02001388 if (batadv_compare_eth(backbone_gw->orig, orig) &&
1389 backbone_gw->vid == vid) {
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001390 rcu_read_unlock();
Antonio Quartullicfd4f752013-08-07 18:28:56 +02001391 return true;
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001392 }
1393 }
1394 rcu_read_unlock();
1395 }
1396
Antonio Quartullicfd4f752013-08-07 18:28:56 +02001397 return false;
Simon Wunderlich20ff9d52012-01-22 20:00:23 +01001398}
1399
Ben Hutchings2c530402012-07-10 10:55:09 +00001400/**
1401 * batadv_bla_is_backbone_gw
1402 * @skb: the frame to be checked
Simon Wunderlich23721382012-01-22 20:00:19 +01001403 * @orig_node: the orig_node of the frame
1404 * @hdr_size: maximum length of the frame
1405 *
1406 * bla_is_backbone_gw inspects the skb for the VLAN ID and returns 1
1407 * if the orig_node is also a gateway on the soft interface, otherwise it
1408 * returns 0.
Simon Wunderlich23721382012-01-22 20:00:19 +01001409 */
Sven Eckelmann08adf152012-05-12 13:38:47 +02001410int batadv_bla_is_backbone_gw(struct sk_buff *skb,
Sven Eckelmann56303d32012-06-05 22:31:31 +02001411 struct batadv_orig_node *orig_node, int hdr_size)
Simon Wunderlich23721382012-01-22 20:00:19 +01001412{
Marek Lindnerbae98772012-12-25 17:03:24 +08001413 struct batadv_bla_backbone_gw *backbone_gw;
Antonio Quartullic018ad32013-06-04 12:11:39 +02001414 unsigned short vid;
Simon Wunderlich23721382012-01-22 20:00:19 +01001415
1416 if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
1417 return 0;
1418
1419 /* first, find out the vid. */
Antonio Quartulli0d125072012-02-18 11:27:34 +01001420 if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
Simon Wunderlich23721382012-01-22 20:00:19 +01001421 return 0;
1422
Antonio Quartullic018ad32013-06-04 12:11:39 +02001423 vid = batadv_get_vid(skb, hdr_size);
Simon Wunderlich23721382012-01-22 20:00:19 +01001424
1425 /* see if this originator is a backbone gw for this VLAN */
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001426 backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,
1427 orig_node->orig, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +01001428 if (!backbone_gw)
1429 return 0;
1430
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001431 batadv_backbone_gw_free_ref(backbone_gw);
Simon Wunderlich23721382012-01-22 20:00:19 +01001432 return 1;
1433}
1434
1435/* free all bla structures (for softinterface free or module unload) */
Sven Eckelmann56303d32012-06-05 22:31:31 +02001436void batadv_bla_free(struct batadv_priv *bat_priv)
Simon Wunderlich23721382012-01-22 20:00:19 +01001437{
Sven Eckelmann56303d32012-06-05 22:31:31 +02001438 struct batadv_hard_iface *primary_if;
Simon Wunderlich23721382012-01-22 20:00:19 +01001439
Sven Eckelmann807736f2012-07-15 22:26:51 +02001440 cancel_delayed_work_sync(&bat_priv->bla.work);
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001441 primary_if = batadv_primary_if_get_selected(bat_priv);
Simon Wunderlich23721382012-01-22 20:00:19 +01001442
Sven Eckelmann807736f2012-07-15 22:26:51 +02001443 if (bat_priv->bla.claim_hash) {
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001444 batadv_bla_purge_claims(bat_priv, primary_if, 1);
Sven Eckelmann807736f2012-07-15 22:26:51 +02001445 batadv_hash_destroy(bat_priv->bla.claim_hash);
1446 bat_priv->bla.claim_hash = NULL;
Simon Wunderlich23721382012-01-22 20:00:19 +01001447 }
Sven Eckelmann807736f2012-07-15 22:26:51 +02001448 if (bat_priv->bla.backbone_hash) {
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001449 batadv_bla_purge_backbone_gw(bat_priv, 1);
Sven Eckelmann807736f2012-07-15 22:26:51 +02001450 batadv_hash_destroy(bat_priv->bla.backbone_hash);
1451 bat_priv->bla.backbone_hash = NULL;
Simon Wunderlich23721382012-01-22 20:00:19 +01001452 }
1453 if (primary_if)
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001454 batadv_hardif_free_ref(primary_if);
Simon Wunderlich23721382012-01-22 20:00:19 +01001455}
1456
Ben Hutchings2c530402012-07-10 10:55:09 +00001457/**
1458 * batadv_bla_rx
1459 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich23721382012-01-22 20:00:19 +01001460 * @skb: the frame to be checked
1461 * @vid: the VLAN ID of the frame
Simon Wunderlich2d3f6cc2012-07-04 20:38:19 +02001462 * @is_bcast: the packet came in a broadcast packet type.
Simon Wunderlich23721382012-01-22 20:00:19 +01001463 *
1464 * bla_rx avoidance checks if:
1465 * * we have to race for a claim
1466 * * if the frame is allowed on the LAN
1467 *
1468 * in these cases, the skb is further handled by this function and
1469 * returns 1, otherwise it returns 0 and the caller shall further
1470 * process the skb.
Simon Wunderlich23721382012-01-22 20:00:19 +01001471 */
Antonio Quartullieb2deb62013-04-19 18:07:00 +02001472int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
1473 unsigned short vid, bool is_bcast)
Simon Wunderlich23721382012-01-22 20:00:19 +01001474{
1475 struct ethhdr *ethhdr;
Marek Lindner712bbfe42012-12-25 17:03:25 +08001476 struct batadv_bla_claim search_claim, *claim = NULL;
Sven Eckelmann56303d32012-06-05 22:31:31 +02001477 struct batadv_hard_iface *primary_if;
Simon Wunderlich23721382012-01-22 20:00:19 +01001478 int ret;
1479
Antonio Quartulli7ed4be92013-04-08 15:08:18 +02001480 ethhdr = eth_hdr(skb);
Simon Wunderlich23721382012-01-22 20:00:19 +01001481
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001482 primary_if = batadv_primary_if_get_selected(bat_priv);
Simon Wunderlich23721382012-01-22 20:00:19 +01001483 if (!primary_if)
1484 goto handled;
1485
1486 if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1487 goto allow;
1488
Sven Eckelmann807736f2012-07-15 22:26:51 +02001489 if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
Simon Wunderlich23721382012-01-22 20:00:19 +01001490 /* don't allow broadcasts while requests are in flight */
Simon Wunderlich2d3f6cc2012-07-04 20:38:19 +02001491 if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
Simon Wunderlich23721382012-01-22 20:00:19 +01001492 goto handled;
1493
Antonio Quartulli8fdd0152014-01-22 00:42:11 +01001494 ether_addr_copy(search_claim.addr, ethhdr->h_source);
Simon Wunderlich23721382012-01-22 20:00:19 +01001495 search_claim.vid = vid;
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001496 claim = batadv_claim_hash_find(bat_priv, &search_claim);
Simon Wunderlich23721382012-01-22 20:00:19 +01001497
1498 if (!claim) {
1499 /* possible optimization: race for a claim */
1500 /* No claim exists yet, claim it for us!
1501 */
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001502 batadv_handle_claim(bat_priv, primary_if,
1503 primary_if->net_dev->dev_addr,
1504 ethhdr->h_source, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +01001505 goto allow;
1506 }
1507
1508 /* if it is our own claim ... */
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001509 if (batadv_compare_eth(claim->backbone_gw->orig,
1510 primary_if->net_dev->dev_addr)) {
Simon Wunderlich23721382012-01-22 20:00:19 +01001511 /* ... allow it in any case */
1512 claim->lasttime = jiffies;
1513 goto allow;
1514 }
1515
1516 /* if it is a broadcast ... */
Simon Wunderlich2d3f6cc2012-07-04 20:38:19 +02001517 if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
1518 /* ... drop it. the responsible gateway is in charge.
1519 *
1520 * We need to check is_bcast because with the gateway
1521 * feature, broadcasts (like DHCP requests) may be sent
1522 * using a unicast packet type.
1523 */
Simon Wunderlich23721382012-01-22 20:00:19 +01001524 goto handled;
1525 } else {
1526 /* seems the client considers us as its best gateway.
1527 * send a claim and update the claim table
1528 * immediately.
1529 */
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001530 batadv_handle_claim(bat_priv, primary_if,
1531 primary_if->net_dev->dev_addr,
1532 ethhdr->h_source, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +01001533 goto allow;
1534 }
1535allow:
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001536 batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +01001537 ret = 0;
1538 goto out;
1539
1540handled:
1541 kfree_skb(skb);
1542 ret = 1;
1543
1544out:
1545 if (primary_if)
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001546 batadv_hardif_free_ref(primary_if);
Simon Wunderlich23721382012-01-22 20:00:19 +01001547 if (claim)
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001548 batadv_claim_free_ref(claim);
Simon Wunderlich23721382012-01-22 20:00:19 +01001549 return ret;
1550}
1551
Ben Hutchings2c530402012-07-10 10:55:09 +00001552/**
1553 * batadv_bla_tx
1554 * @bat_priv: the bat priv with all the soft interface information
Simon Wunderlich23721382012-01-22 20:00:19 +01001555 * @skb: the frame to be checked
1556 * @vid: the VLAN ID of the frame
1557 *
1558 * bla_tx checks if:
1559 * * a claim was received which has to be processed
1560 * * the frame is allowed on the mesh
1561 *
1562 * in these cases, the skb is further handled by this function and
1563 * returns 1, otherwise it returns 0 and the caller shall further
1564 * process the skb.
Linus Lüssing9d2c9482013-08-06 20:21:15 +02001565 *
1566 * This call might reallocate skb data.
Simon Wunderlich23721382012-01-22 20:00:19 +01001567 */
Antonio Quartullieb2deb62013-04-19 18:07:00 +02001568int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
1569 unsigned short vid)
Simon Wunderlich23721382012-01-22 20:00:19 +01001570{
1571 struct ethhdr *ethhdr;
Marek Lindner712bbfe42012-12-25 17:03:25 +08001572 struct batadv_bla_claim search_claim, *claim = NULL;
Sven Eckelmann56303d32012-06-05 22:31:31 +02001573 struct batadv_hard_iface *primary_if;
Simon Wunderlich23721382012-01-22 20:00:19 +01001574 int ret = 0;
1575
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001576 primary_if = batadv_primary_if_get_selected(bat_priv);
Simon Wunderlich23721382012-01-22 20:00:19 +01001577 if (!primary_if)
1578 goto out;
1579
1580 if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1581 goto allow;
1582
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001583 if (batadv_bla_process_claim(bat_priv, primary_if, skb))
Simon Wunderlich23721382012-01-22 20:00:19 +01001584 goto handled;
1585
Antonio Quartulli7ed4be92013-04-08 15:08:18 +02001586 ethhdr = eth_hdr(skb);
Simon Wunderlich23721382012-01-22 20:00:19 +01001587
Sven Eckelmann807736f2012-07-15 22:26:51 +02001588 if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
Simon Wunderlich23721382012-01-22 20:00:19 +01001589 /* don't allow broadcasts while requests are in flight */
1590 if (is_multicast_ether_addr(ethhdr->h_dest))
1591 goto handled;
1592
Antonio Quartulli8fdd0152014-01-22 00:42:11 +01001593 ether_addr_copy(search_claim.addr, ethhdr->h_source);
Simon Wunderlich23721382012-01-22 20:00:19 +01001594 search_claim.vid = vid;
1595
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001596 claim = batadv_claim_hash_find(bat_priv, &search_claim);
Simon Wunderlich23721382012-01-22 20:00:19 +01001597
1598 /* if no claim exists, allow it. */
1599 if (!claim)
1600 goto allow;
1601
1602 /* check if we are responsible. */
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001603 if (batadv_compare_eth(claim->backbone_gw->orig,
1604 primary_if->net_dev->dev_addr)) {
Simon Wunderlich23721382012-01-22 20:00:19 +01001605 /* if yes, the client has roamed and we have
1606 * to unclaim it.
1607 */
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001608 batadv_handle_unclaim(bat_priv, primary_if,
1609 primary_if->net_dev->dev_addr,
1610 ethhdr->h_source, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +01001611 goto allow;
1612 }
1613
1614 /* check if it is a multicast/broadcast frame */
1615 if (is_multicast_ether_addr(ethhdr->h_dest)) {
1616 /* drop it. the responsible gateway has forwarded it into
1617 * the backbone network.
1618 */
1619 goto handled;
1620 } else {
1621 /* we must allow it. at least if we are
1622 * responsible for the DESTINATION.
1623 */
1624 goto allow;
1625 }
1626allow:
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001627 batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
Simon Wunderlich23721382012-01-22 20:00:19 +01001628 ret = 0;
1629 goto out;
1630handled:
1631 ret = 1;
1632out:
1633 if (primary_if)
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001634 batadv_hardif_free_ref(primary_if);
Simon Wunderlich23721382012-01-22 20:00:19 +01001635 if (claim)
Sven Eckelmann3b300de2012-05-12 18:33:53 +02001636 batadv_claim_free_ref(claim);
Simon Wunderlich23721382012-01-22 20:00:19 +01001637 return ret;
1638}
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001639
Sven Eckelmann08adf152012-05-12 13:38:47 +02001640int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001641{
1642 struct net_device *net_dev = (struct net_device *)seq->private;
Sven Eckelmann56303d32012-06-05 22:31:31 +02001643 struct batadv_priv *bat_priv = netdev_priv(net_dev);
Sven Eckelmann807736f2012-07-15 22:26:51 +02001644 struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
Marek Lindner712bbfe42012-12-25 17:03:25 +08001645 struct batadv_bla_claim *claim;
Sven Eckelmann56303d32012-06-05 22:31:31 +02001646 struct batadv_hard_iface *primary_if;
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001647 struct hlist_head *head;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001648 u32 i;
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001649 bool is_own;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001650 u8 *primary_addr;
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001651
Marek Lindner30da63a2012-08-03 17:15:46 +02001652 primary_if = batadv_seq_print_text_primary_if_get(seq);
1653 if (!primary_if)
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001654 goto out;
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001655
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001656 primary_addr = primary_if->net_dev->dev_addr;
Simon Wunderlich38ef3d12012-01-22 20:00:26 +01001657 seq_printf(seq,
Antonio Quartulli39a32992012-11-19 09:01:43 +01001658 "Claims announced for the mesh %s (orig %pM, group id %#.4x)\n",
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001659 net_dev->name, primary_addr,
Sven Eckelmann807736f2012-07-15 22:26:51 +02001660 ntohs(bat_priv->bla.claim_dest.group));
Antonio Quartulli39a32992012-11-19 09:01:43 +01001661 seq_printf(seq, " %-17s %-5s %-17s [o] (%-6s)\n",
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001662 "Client", "VID", "Originator", "CRC");
1663 for (i = 0; i < hash->size; i++) {
1664 head = &hash->table[i];
1665
1666 rcu_read_lock();
Sasha Levinb67bfe02013-02-27 17:06:00 -08001667 hlist_for_each_entry_rcu(claim, head, hash_entry) {
Sven Eckelmann1eda58b2012-05-12 13:48:58 +02001668 is_own = batadv_compare_eth(claim->backbone_gw->orig,
1669 primary_addr);
Antonio Quartullieb2deb62013-04-19 18:07:00 +02001670 seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +02001671 claim->addr, BATADV_PRINT_VID(claim->vid),
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001672 claim->backbone_gw->orig,
1673 (is_own ? 'x' : ' '),
1674 claim->backbone_gw->crc);
1675 }
1676 rcu_read_unlock();
1677 }
1678out:
1679 if (primary_if)
Sven Eckelmanne5d89252012-05-12 13:48:54 +02001680 batadv_hardif_free_ref(primary_if);
Marek Lindner30da63a2012-08-03 17:15:46 +02001681 return 0;
Simon Wunderlich9bf8e4d2012-01-22 20:00:21 +01001682}
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001683
1684int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
1685{
1686 struct net_device *net_dev = (struct net_device *)seq->private;
1687 struct batadv_priv *bat_priv = netdev_priv(net_dev);
Sven Eckelmann807736f2012-07-15 22:26:51 +02001688 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
Marek Lindnerbae98772012-12-25 17:03:24 +08001689 struct batadv_bla_backbone_gw *backbone_gw;
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001690 struct batadv_hard_iface *primary_if;
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001691 struct hlist_head *head;
1692 int secs, msecs;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001693 u32 i;
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001694 bool is_own;
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001695 u8 *primary_addr;
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001696
Marek Lindner30da63a2012-08-03 17:15:46 +02001697 primary_if = batadv_seq_print_text_primary_if_get(seq);
1698 if (!primary_if)
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001699 goto out;
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001700
1701 primary_addr = primary_if->net_dev->dev_addr;
1702 seq_printf(seq,
Antonio Quartulli39a32992012-11-19 09:01:43 +01001703 "Backbones announced for the mesh %s (orig %pM, group id %#.4x)\n",
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001704 net_dev->name, primary_addr,
Sven Eckelmann807736f2012-07-15 22:26:51 +02001705 ntohs(bat_priv->bla.claim_dest.group));
Antonio Quartulli39a32992012-11-19 09:01:43 +01001706 seq_printf(seq, " %-17s %-5s %-9s (%-6s)\n",
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001707 "Originator", "VID", "last seen", "CRC");
1708 for (i = 0; i < hash->size; i++) {
1709 head = &hash->table[i];
1710
1711 rcu_read_lock();
Sasha Levinb67bfe02013-02-27 17:06:00 -08001712 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001713 msecs = jiffies_to_msecs(jiffies -
1714 backbone_gw->lasttime);
1715 secs = msecs / 1000;
1716 msecs = msecs % 1000;
1717
1718 is_own = batadv_compare_eth(backbone_gw->orig,
1719 primary_addr);
1720 if (is_own)
1721 continue;
1722
Antonio Quartullieb2deb62013-04-19 18:07:00 +02001723 seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)\n",
Antonio Quartulli5f80df62013-04-19 18:07:01 +02001724 backbone_gw->orig,
1725 BATADV_PRINT_VID(backbone_gw->vid), secs,
Antonio Quartullieb2deb62013-04-19 18:07:00 +02001726 msecs, backbone_gw->crc);
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001727 }
1728 rcu_read_unlock();
1729 }
1730out:
1731 if (primary_if)
1732 batadv_hardif_free_ref(primary_if);
Marek Lindner30da63a2012-08-03 17:15:46 +02001733 return 0;
Simon Wunderlich536a23f2012-06-18 18:39:26 +02001734}