1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) B.A.T.M.A.N. contributors:
3 *
4 * Marek Lindner, Simon Wunderlich
5 */
6
7 #include "originator.h"
8 #include "main.h"
9
10 #include <linux/container_of.h>
11 #include <linux/err.h>
12 #include <linux/errno.h>
13 #include <linux/etherdevice.h>
14 #include <linux/gfp.h>
15 #include <linux/if_vlan.h>
16 #include <linux/jiffies.h>
17 #include <linux/kref.h>
18 #include <linux/list.h>
19 #include <linux/lockdep.h>
20 #include <linux/netdevice.h>
21 #include <linux/netlink.h>
22 #include <linux/rculist.h>
23 #include <linux/rcupdate.h>
24 #include <linux/skbuff.h>
25 #include <linux/slab.h>
26 #include <linux/spinlock.h>
27 #include <linux/stddef.h>
28 #include <linux/workqueue.h>
29 #include <uapi/linux/batadv_packet.h>
30
31 #include "distributed-arp-table.h"
32 #include "fragmentation.h"
33 #include "gateway_client.h"
34 #include "hard-interface.h"
35 #include "hash.h"
36 #include "log.h"
37 #include "multicast.h"
38 #include "netlink.h"
39 #include "routing.h"
40 #include "translation-table.h"
41
42 /* hash class keys */
43 static struct lock_class_key batadv_orig_hash_lock_class_key;
44
45 /**
46 * batadv_orig_hash_find() - Find and return originator from orig_hash
47 * @bat_priv: the bat priv with all the mesh interface information
48 * @data: mac address of the originator
49 *
50 * Return: orig_node (with increased refcnt), NULL on errors
51 */
52 struct batadv_orig_node *
batadv_orig_hash_find(struct batadv_priv * bat_priv,const void * data)53 batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data)
54 {
55 struct batadv_hashtable *hash = bat_priv->orig_hash;
56 struct batadv_orig_node *orig_node_tmp = NULL;
57 struct batadv_orig_node *orig_node;
58 struct hlist_head *head;
59 int index;
60
61 if (!hash)
62 return NULL;
63
64 index = batadv_choose_orig(data, hash->size);
65 head = &hash->table[index];
66
67 rcu_read_lock();
68 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
69 if (!batadv_compare_eth(orig_node, data))
70 continue;
71
72 if (!kref_get_unless_zero(&orig_node->refcount))
73 continue;
74
75 orig_node_tmp = orig_node;
76 break;
77 }
78 rcu_read_unlock();
79
80 return orig_node_tmp;
81 }
82
83 static void batadv_purge_orig(struct work_struct *work);
84
85 /**
86 * batadv_compare_orig() - comparing function used in the originator hash table
87 * @node: node in the local table
88 * @data2: second object to compare the node to
89 *
90 * Return: true if they are the same originator
91 */
batadv_compare_orig(const struct hlist_node * node,const void * data2)92 bool batadv_compare_orig(const struct hlist_node *node, const void *data2)
93 {
94 const void *data1 = container_of(node, struct batadv_orig_node,
95 hash_entry);
96
97 return batadv_compare_eth(data1, data2);
98 }
99
100 /**
101 * batadv_orig_node_vlan_get() - get an orig_node_vlan object
102 * @orig_node: the originator serving the VLAN
103 * @vid: the VLAN identifier
104 *
105 * Return: the vlan object identified by vid and belonging to orig_node or NULL
106 * if it does not exist.
107 */
108 struct batadv_orig_node_vlan *
batadv_orig_node_vlan_get(struct batadv_orig_node * orig_node,unsigned short vid)109 batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
110 unsigned short vid)
111 {
112 struct batadv_orig_node_vlan *vlan = NULL;
113 struct batadv_orig_node_vlan *tmp;
114
115 rcu_read_lock();
116 hlist_for_each_entry_rcu(tmp, &orig_node->vlan_list, list) {
117 if (tmp->vid != vid)
118 continue;
119
120 if (!kref_get_unless_zero(&tmp->refcount))
121 continue;
122
123 vlan = tmp;
124
125 break;
126 }
127 rcu_read_unlock();
128
129 return vlan;
130 }
131
132 /**
133 * batadv_vlan_id_valid() - check if vlan id is in valid batman-adv encoding
134 * @vid: the VLAN identifier
135 *
136 * Return: true when either no vlan is set or if VLAN is in correct range,
137 * false otherwise
138 */
batadv_vlan_id_valid(unsigned short vid)139 static bool batadv_vlan_id_valid(unsigned short vid)
140 {
141 unsigned short non_vlan = vid & ~(BATADV_VLAN_HAS_TAG | VLAN_VID_MASK);
142
143 if (vid == 0)
144 return true;
145
146 if (!(vid & BATADV_VLAN_HAS_TAG))
147 return false;
148
149 if (non_vlan)
150 return false;
151
152 return true;
153 }
154
155 /**
156 * batadv_orig_node_vlan_new() - search and possibly create an orig_node_vlan
157 * object
158 * @orig_node: the originator serving the VLAN
159 * @vid: the VLAN identifier
160 *
161 * Return: NULL in case of failure or the vlan object identified by vid and
162 * belonging to orig_node otherwise. The object is created and added to the list
163 * if it does not exist.
164 *
165 * The object is returned with refcounter increased by 1.
166 */
167 struct batadv_orig_node_vlan *
batadv_orig_node_vlan_new(struct batadv_orig_node * orig_node,unsigned short vid)168 batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
169 unsigned short vid)
170 {
171 struct batadv_orig_node_vlan *vlan;
172
173 if (!batadv_vlan_id_valid(vid))
174 return NULL;
175
176 spin_lock_bh(&orig_node->vlan_list_lock);
177
178 /* first look if an object for this vid already exists */
179 vlan = batadv_orig_node_vlan_get(orig_node, vid);
180 if (vlan)
181 goto out;
182
183 vlan = kzalloc_obj(*vlan, GFP_ATOMIC);
184 if (!vlan)
185 goto out;
186
187 kref_init(&vlan->refcount);
188 vlan->vid = vid;
189
190 kref_get(&vlan->refcount);
191 hlist_add_head_rcu(&vlan->list, &orig_node->vlan_list);
192
193 out:
194 spin_unlock_bh(&orig_node->vlan_list_lock);
195
196 return vlan;
197 }
198
199 /**
200 * batadv_orig_node_vlan_release() - release originator-vlan object from lists
201 * and queue for free after rcu grace period
202 * @ref: kref pointer of the originator-vlan object
203 */
batadv_orig_node_vlan_release(struct kref * ref)204 void batadv_orig_node_vlan_release(struct kref *ref)
205 {
206 struct batadv_orig_node_vlan *orig_vlan;
207
208 orig_vlan = container_of(ref, struct batadv_orig_node_vlan, refcount);
209
210 kfree_rcu(orig_vlan, rcu);
211 }
212
213 /**
214 * batadv_originator_init() - Initialize all originator structures
215 * @bat_priv: the bat priv with all the mesh interface information
216 *
217 * Return: 0 on success or negative error number in case of failure
218 */
batadv_originator_init(struct batadv_priv * bat_priv)219 int batadv_originator_init(struct batadv_priv *bat_priv)
220 {
221 if (bat_priv->orig_hash)
222 return 0;
223
224 bat_priv->orig_hash = batadv_hash_new(1024);
225
226 if (!bat_priv->orig_hash)
227 goto err;
228
229 batadv_hash_set_lock_class(bat_priv->orig_hash,
230 &batadv_orig_hash_lock_class_key);
231
232 INIT_DELAYED_WORK(&bat_priv->orig_work, batadv_purge_orig);
233 queue_delayed_work(batadv_event_workqueue,
234 &bat_priv->orig_work,
235 msecs_to_jiffies(BATADV_ORIG_WORK_PERIOD));
236
237 return 0;
238
239 err:
240 return -ENOMEM;
241 }
242
243 /**
244 * batadv_neigh_ifinfo_release() - release neigh_ifinfo from lists and queue for
245 * free after rcu grace period
246 * @ref: kref pointer of the neigh_ifinfo
247 */
batadv_neigh_ifinfo_release(struct kref * ref)248 void batadv_neigh_ifinfo_release(struct kref *ref)
249 {
250 struct batadv_neigh_ifinfo *neigh_ifinfo;
251
252 neigh_ifinfo = container_of(ref, struct batadv_neigh_ifinfo, refcount);
253
254 if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
255 batadv_hardif_put(neigh_ifinfo->if_outgoing);
256
257 kfree_rcu(neigh_ifinfo, rcu);
258 }
259
260 /**
261 * batadv_hardif_neigh_release() - release hardif neigh node from lists and
262 * queue for free after rcu grace period
263 * @ref: kref pointer of the neigh_node
264 */
batadv_hardif_neigh_release(struct kref * ref)265 void batadv_hardif_neigh_release(struct kref *ref)
266 {
267 struct batadv_hardif_neigh_node *hardif_neigh;
268
269 hardif_neigh = container_of(ref, struct batadv_hardif_neigh_node,
270 refcount);
271
272 spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
273 hlist_del_init_rcu(&hardif_neigh->list);
274 spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
275
276 batadv_hardif_put(hardif_neigh->if_incoming);
277 kfree_rcu(hardif_neigh, rcu);
278 }
279
280 /**
281 * batadv_neigh_node_release() - release neigh_node from lists and queue for
282 * free after rcu grace period
283 * @ref: kref pointer of the neigh_node
284 */
batadv_neigh_node_release(struct kref * ref)285 void batadv_neigh_node_release(struct kref *ref)
286 {
287 struct batadv_neigh_ifinfo *neigh_ifinfo;
288 struct batadv_neigh_node *neigh_node;
289 struct hlist_node *node_tmp;
290
291 neigh_node = container_of(ref, struct batadv_neigh_node, refcount);
292
293 hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
294 &neigh_node->ifinfo_list, list) {
295 batadv_neigh_ifinfo_put(neigh_ifinfo);
296 }
297
298 batadv_hardif_neigh_put(neigh_node->hardif_neigh);
299
300 batadv_hardif_put(neigh_node->if_incoming);
301
302 kfree_rcu(neigh_node, rcu);
303 }
304
305 /**
306 * batadv_orig_router_get() - router to the originator depending on iface
307 * @orig_node: the orig node for the router
308 * @if_outgoing: the interface where the payload packet has been received or
309 * the OGM should be sent to
310 *
311 * Return: the neighbor which should be the router for this orig_node/iface.
312 *
313 * The object is returned with refcounter increased by 1.
314 */
315 struct batadv_neigh_node *
batadv_orig_router_get(struct batadv_orig_node * orig_node,const struct batadv_hard_iface * if_outgoing)316 batadv_orig_router_get(struct batadv_orig_node *orig_node,
317 const struct batadv_hard_iface *if_outgoing)
318 {
319 struct batadv_neigh_node *router = NULL;
320 struct batadv_orig_ifinfo *orig_ifinfo;
321
322 rcu_read_lock();
323 hlist_for_each_entry_rcu(orig_ifinfo, &orig_node->ifinfo_list, list) {
324 if (orig_ifinfo->if_outgoing != if_outgoing)
325 continue;
326
327 router = rcu_dereference(orig_ifinfo->router);
328 break;
329 }
330
331 if (router && !kref_get_unless_zero(&router->refcount))
332 router = NULL;
333
334 rcu_read_unlock();
335 return router;
336 }
337
338 /**
339 * batadv_orig_to_router() - get next hop neighbor to an orig address
340 * @bat_priv: the bat priv with all the mesh interface information
341 * @orig_addr: the originator MAC address to search the best next hop router for
342 * @if_outgoing: the interface where the payload packet has been received or
343 * the OGM should be sent to
344 *
345 * Return: A neighbor node which is the best router towards the given originator
346 * address.
347 */
348 struct batadv_neigh_node *
batadv_orig_to_router(struct batadv_priv * bat_priv,u8 * orig_addr,struct batadv_hard_iface * if_outgoing)349 batadv_orig_to_router(struct batadv_priv *bat_priv, u8 *orig_addr,
350 struct batadv_hard_iface *if_outgoing)
351 {
352 struct batadv_neigh_node *neigh_node;
353 struct batadv_orig_node *orig_node;
354
355 orig_node = batadv_orig_hash_find(bat_priv, orig_addr);
356 if (!orig_node)
357 return NULL;
358
359 neigh_node = batadv_find_router(bat_priv, orig_node, if_outgoing);
360 batadv_orig_node_put(orig_node);
361
362 return neigh_node;
363 }
364
365 /**
366 * batadv_orig_ifinfo_get() - find the ifinfo from an orig_node
367 * @orig_node: the orig node to be queried
368 * @if_outgoing: the interface for which the ifinfo should be acquired
369 *
370 * Return: the requested orig_ifinfo or NULL if not found.
371 *
372 * The object is returned with refcounter increased by 1.
373 */
374 struct batadv_orig_ifinfo *
batadv_orig_ifinfo_get(struct batadv_orig_node * orig_node,struct batadv_hard_iface * if_outgoing)375 batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
376 struct batadv_hard_iface *if_outgoing)
377 {
378 struct batadv_orig_ifinfo *orig_ifinfo = NULL;
379 struct batadv_orig_ifinfo *tmp;
380
381 rcu_read_lock();
382 hlist_for_each_entry_rcu(tmp, &orig_node->ifinfo_list,
383 list) {
384 if (tmp->if_outgoing != if_outgoing)
385 continue;
386
387 if (!kref_get_unless_zero(&tmp->refcount))
388 continue;
389
390 orig_ifinfo = tmp;
391 break;
392 }
393 rcu_read_unlock();
394
395 return orig_ifinfo;
396 }
397
398 /**
399 * batadv_orig_ifinfo_new() - search and possibly create an orig_ifinfo object
400 * @orig_node: the orig node to be queried
401 * @if_outgoing: the interface for which the ifinfo should be acquired
402 *
403 * Return: NULL in case of failure or the orig_ifinfo object for the if_outgoing
404 * interface otherwise. The object is created and added to the list
405 * if it does not exist.
406 *
407 * The object is returned with refcounter increased by 1.
408 */
409 struct batadv_orig_ifinfo *
batadv_orig_ifinfo_new(struct batadv_orig_node * orig_node,struct batadv_hard_iface * if_outgoing)410 batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node,
411 struct batadv_hard_iface *if_outgoing)
412 {
413 struct batadv_orig_ifinfo *orig_ifinfo;
414 unsigned long reset_time;
415
416 spin_lock_bh(&orig_node->neigh_list_lock);
417
418 orig_ifinfo = batadv_orig_ifinfo_get(orig_node, if_outgoing);
419 if (orig_ifinfo)
420 goto out;
421
422 orig_ifinfo = kzalloc_obj(*orig_ifinfo, GFP_ATOMIC);
423 if (!orig_ifinfo)
424 goto out;
425
426 if (if_outgoing != BATADV_IF_DEFAULT)
427 kref_get(&if_outgoing->refcount);
428
429 reset_time = jiffies - 1;
430 reset_time -= msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
431 orig_ifinfo->batman_seqno_reset = reset_time;
432 orig_ifinfo->if_outgoing = if_outgoing;
433 INIT_HLIST_NODE(&orig_ifinfo->list);
434 kref_init(&orig_ifinfo->refcount);
435
436 kref_get(&orig_ifinfo->refcount);
437 hlist_add_head_rcu(&orig_ifinfo->list,
438 &orig_node->ifinfo_list);
439 out:
440 spin_unlock_bh(&orig_node->neigh_list_lock);
441 return orig_ifinfo;
442 }
443
444 /**
445 * batadv_neigh_ifinfo_get() - find the ifinfo from a neigh_node
446 * @neigh: the neigh node to be queried
447 * @if_outgoing: the interface for which the ifinfo should be acquired
448 *
449 * The object is returned with refcounter increased by 1.
450 *
451 * Return: the requested neigh_ifinfo or NULL if not found
452 */
453 struct batadv_neigh_ifinfo *
batadv_neigh_ifinfo_get(struct batadv_neigh_node * neigh,struct batadv_hard_iface * if_outgoing)454 batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
455 struct batadv_hard_iface *if_outgoing)
456 {
457 struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
458 struct batadv_neigh_ifinfo *tmp_neigh_ifinfo;
459
460 rcu_read_lock();
461 hlist_for_each_entry_rcu(tmp_neigh_ifinfo, &neigh->ifinfo_list,
462 list) {
463 if (tmp_neigh_ifinfo->if_outgoing != if_outgoing)
464 continue;
465
466 if (!kref_get_unless_zero(&tmp_neigh_ifinfo->refcount))
467 continue;
468
469 neigh_ifinfo = tmp_neigh_ifinfo;
470 break;
471 }
472 rcu_read_unlock();
473
474 return neigh_ifinfo;
475 }
476
477 /**
478 * batadv_neigh_ifinfo_new() - search and possibly create a neigh_ifinfo object
479 * @neigh: the neigh node to be queried
480 * @if_outgoing: the interface for which the ifinfo should be acquired
481 *
482 * Return: NULL in case of failure or the neigh_ifinfo object for the
483 * if_outgoing interface otherwise. The object is created and added to the list
484 * if it does not exist.
485 *
486 * The object is returned with refcounter increased by 1.
487 */
488 struct batadv_neigh_ifinfo *
batadv_neigh_ifinfo_new(struct batadv_neigh_node * neigh,struct batadv_hard_iface * if_outgoing)489 batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh,
490 struct batadv_hard_iface *if_outgoing)
491 {
492 struct batadv_neigh_ifinfo *neigh_ifinfo;
493
494 spin_lock_bh(&neigh->ifinfo_lock);
495
496 neigh_ifinfo = batadv_neigh_ifinfo_get(neigh, if_outgoing);
497 if (neigh_ifinfo)
498 goto out;
499
500 neigh_ifinfo = kzalloc_obj(*neigh_ifinfo, GFP_ATOMIC);
501 if (!neigh_ifinfo)
502 goto out;
503
504 if (if_outgoing)
505 kref_get(&if_outgoing->refcount);
506
507 INIT_HLIST_NODE(&neigh_ifinfo->list);
508 kref_init(&neigh_ifinfo->refcount);
509 neigh_ifinfo->if_outgoing = if_outgoing;
510
511 kref_get(&neigh_ifinfo->refcount);
512 hlist_add_head_rcu(&neigh_ifinfo->list, &neigh->ifinfo_list);
513
514 out:
515 spin_unlock_bh(&neigh->ifinfo_lock);
516
517 return neigh_ifinfo;
518 }
519
520 /**
521 * batadv_neigh_node_get() - retrieve a neighbour from the list
522 * @orig_node: originator which the neighbour belongs to
523 * @hard_iface: the interface where this neighbour is connected to
524 * @addr: the address of the neighbour
525 *
526 * Looks for and possibly returns a neighbour belonging to this originator list
527 * which is connected through the provided hard interface.
528 *
529 * Return: neighbor when found. Otherwise NULL
530 */
531 static struct batadv_neigh_node *
batadv_neigh_node_get(const struct batadv_orig_node * orig_node,const struct batadv_hard_iface * hard_iface,const u8 * addr)532 batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
533 const struct batadv_hard_iface *hard_iface,
534 const u8 *addr)
535 {
536 struct batadv_neigh_node *tmp_neigh_node;
537 struct batadv_neigh_node *res = NULL;
538
539 rcu_read_lock();
540 hlist_for_each_entry_rcu(tmp_neigh_node, &orig_node->neigh_list, list) {
541 if (!batadv_compare_eth(tmp_neigh_node->addr, addr))
542 continue;
543
544 if (tmp_neigh_node->if_incoming != hard_iface)
545 continue;
546
547 if (!kref_get_unless_zero(&tmp_neigh_node->refcount))
548 continue;
549
550 res = tmp_neigh_node;
551 break;
552 }
553 rcu_read_unlock();
554
555 return res;
556 }
557
558 /**
559 * batadv_hardif_neigh_create() - create a hardif neighbour node
560 * @hard_iface: the interface this neighbour is connected to
561 * @neigh_addr: the interface address of the neighbour to retrieve
562 * @orig_node: originator object representing the neighbour
563 *
564 * Return: the hardif neighbour node if found or created or NULL otherwise.
565 */
566 static struct batadv_hardif_neigh_node *
batadv_hardif_neigh_create(struct batadv_hard_iface * hard_iface,const u8 * neigh_addr,struct batadv_orig_node * orig_node)567 batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface,
568 const u8 *neigh_addr,
569 struct batadv_orig_node *orig_node)
570 {
571 struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
572 struct batadv_hardif_neigh_node *hardif_neigh;
573
574 spin_lock_bh(&hard_iface->neigh_list_lock);
575
576 /* check if neighbor hasn't been added in the meantime */
577 hardif_neigh = batadv_hardif_neigh_get(hard_iface, neigh_addr);
578 if (hardif_neigh)
579 goto out;
580
581 hardif_neigh = kzalloc_obj(*hardif_neigh, GFP_ATOMIC);
582 if (!hardif_neigh)
583 goto out;
584
585 kref_get(&hard_iface->refcount);
586 INIT_HLIST_NODE(&hardif_neigh->list);
587 ether_addr_copy(hardif_neigh->addr, neigh_addr);
588 ether_addr_copy(hardif_neigh->orig, orig_node->orig);
589 hardif_neigh->if_incoming = hard_iface;
590 hardif_neigh->last_seen = jiffies;
591
592 kref_init(&hardif_neigh->refcount);
593
594 if (bat_priv->algo_ops->neigh.hardif_init)
595 bat_priv->algo_ops->neigh.hardif_init(hardif_neigh);
596
597 hlist_add_head_rcu(&hardif_neigh->list, &hard_iface->neigh_list);
598
599 out:
600 spin_unlock_bh(&hard_iface->neigh_list_lock);
601 return hardif_neigh;
602 }
603
604 /**
605 * batadv_hardif_neigh_get_or_create() - retrieve or create a hardif neighbour
606 * node
607 * @hard_iface: the interface this neighbour is connected to
608 * @neigh_addr: the interface address of the neighbour to retrieve
609 * @orig_node: originator object representing the neighbour
610 *
611 * Return: the hardif neighbour node if found or created or NULL otherwise.
612 */
613 static struct batadv_hardif_neigh_node *
batadv_hardif_neigh_get_or_create(struct batadv_hard_iface * hard_iface,const u8 * neigh_addr,struct batadv_orig_node * orig_node)614 batadv_hardif_neigh_get_or_create(struct batadv_hard_iface *hard_iface,
615 const u8 *neigh_addr,
616 struct batadv_orig_node *orig_node)
617 {
618 struct batadv_hardif_neigh_node *hardif_neigh;
619
620 /* first check without locking to avoid the overhead */
621 hardif_neigh = batadv_hardif_neigh_get(hard_iface, neigh_addr);
622 if (hardif_neigh)
623 return hardif_neigh;
624
625 return batadv_hardif_neigh_create(hard_iface, neigh_addr, orig_node);
626 }
627
628 /**
629 * batadv_hardif_neigh_get() - retrieve a hardif neighbour from the list
630 * @hard_iface: the interface where this neighbour is connected to
631 * @neigh_addr: the address of the neighbour
632 *
633 * Looks for and possibly returns a neighbour belonging to this hard interface.
634 *
635 * Return: neighbor when found. Otherwise NULL
636 */
637 struct batadv_hardif_neigh_node *
batadv_hardif_neigh_get(const struct batadv_hard_iface * hard_iface,const u8 * neigh_addr)638 batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
639 const u8 *neigh_addr)
640 {
641 struct batadv_hardif_neigh_node *hardif_neigh = NULL;
642 struct batadv_hardif_neigh_node *tmp_hardif_neigh;
643
644 rcu_read_lock();
645 hlist_for_each_entry_rcu(tmp_hardif_neigh,
646 &hard_iface->neigh_list, list) {
647 if (!batadv_compare_eth(tmp_hardif_neigh->addr, neigh_addr))
648 continue;
649
650 if (!kref_get_unless_zero(&tmp_hardif_neigh->refcount))
651 continue;
652
653 hardif_neigh = tmp_hardif_neigh;
654 break;
655 }
656 rcu_read_unlock();
657
658 return hardif_neigh;
659 }
660
661 /**
662 * batadv_neigh_node_create() - create a neigh node object
663 * @orig_node: originator object representing the neighbour
664 * @hard_iface: the interface where the neighbour is connected to
665 * @neigh_addr: the mac address of the neighbour interface
666 *
667 * Allocates a new neigh_node object and initialises all the generic fields.
668 *
669 * Return: the neighbour node if found or created or NULL otherwise.
670 */
671 static struct batadv_neigh_node *
batadv_neigh_node_create(struct batadv_orig_node * orig_node,struct batadv_hard_iface * hard_iface,const u8 * neigh_addr)672 batadv_neigh_node_create(struct batadv_orig_node *orig_node,
673 struct batadv_hard_iface *hard_iface,
674 const u8 *neigh_addr)
675 {
676 struct batadv_hardif_neigh_node *hardif_neigh = NULL;
677 struct batadv_neigh_node *neigh_node;
678
679 spin_lock_bh(&orig_node->neigh_list_lock);
680
681 neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr);
682 if (neigh_node)
683 goto out;
684
685 hardif_neigh = batadv_hardif_neigh_get_or_create(hard_iface,
686 neigh_addr, orig_node);
687 if (!hardif_neigh)
688 goto out;
689
690 neigh_node = kzalloc_obj(*neigh_node, GFP_ATOMIC);
691 if (!neigh_node)
692 goto out;
693
694 INIT_HLIST_NODE(&neigh_node->list);
695 INIT_HLIST_HEAD(&neigh_node->ifinfo_list);
696 spin_lock_init(&neigh_node->ifinfo_lock);
697
698 kref_get(&hard_iface->refcount);
699 ether_addr_copy(neigh_node->addr, neigh_addr);
700 neigh_node->if_incoming = hard_iface;
701 neigh_node->last_seen = jiffies;
702
703 #ifdef CONFIG_BATMAN_ADV_BATMAN_V
704 ACCESS_PRIVATE(neigh_node, orig_node_id) = orig_node;
705 #endif
706
707 /* increment unique neighbor refcount */
708 kref_get(&hardif_neigh->refcount);
709 neigh_node->hardif_neigh = hardif_neigh;
710
711 /* extra reference for return */
712 kref_init(&neigh_node->refcount);
713
714 kref_get(&neigh_node->refcount);
715 hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
716
717 batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv,
718 "Creating new neighbor %pM for orig_node %pM on interface %s\n",
719 neigh_addr, orig_node->orig, hard_iface->net_dev->name);
720
721 out:
722 spin_unlock_bh(&orig_node->neigh_list_lock);
723
724 batadv_hardif_neigh_put(hardif_neigh);
725 return neigh_node;
726 }
727
728 /**
729 * batadv_neigh_node_get_or_create() - retrieve or create a neigh node object
730 * @orig_node: originator object representing the neighbour
731 * @hard_iface: the interface where the neighbour is connected to
732 * @neigh_addr: the mac address of the neighbour interface
733 *
734 * Return: the neighbour node if found or created or NULL otherwise.
735 */
736 struct batadv_neigh_node *
batadv_neigh_node_get_or_create(struct batadv_orig_node * orig_node,struct batadv_hard_iface * hard_iface,const u8 * neigh_addr)737 batadv_neigh_node_get_or_create(struct batadv_orig_node *orig_node,
738 struct batadv_hard_iface *hard_iface,
739 const u8 *neigh_addr)
740 {
741 struct batadv_neigh_node *neigh_node;
742
743 /* first check without locking to avoid the overhead */
744 neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr);
745 if (neigh_node)
746 return neigh_node;
747
748 return batadv_neigh_node_create(orig_node, hard_iface, neigh_addr);
749 }
750
751 /**
752 * batadv_hardif_neigh_dump() - Dump to netlink the neighbor infos for a
753 * specific outgoing interface
754 * @msg: message to dump into
755 * @cb: parameters for the dump
756 *
757 * Return: 0 or error value
758 */
batadv_hardif_neigh_dump(struct sk_buff * msg,struct netlink_callback * cb)759 int batadv_hardif_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb)
760 {
761 struct batadv_hard_iface *primary_if;
762 struct batadv_hard_iface *hard_iface;
763 struct net_device *mesh_iface;
764 struct batadv_priv *bat_priv;
765 int ret;
766
767 mesh_iface = batadv_netlink_get_meshif(cb);
768 if (IS_ERR(mesh_iface))
769 return PTR_ERR(mesh_iface);
770
771 bat_priv = netdev_priv(mesh_iface);
772
773 primary_if = batadv_primary_if_get_selected(bat_priv);
774 if (!primary_if) {
775 ret = -ENOENT;
776 goto out_put_mesh_iface;
777 }
778
779 if (primary_if->if_status != BATADV_IF_ACTIVE) {
780 ret = -ENOENT;
781 goto out_put_primary_if;
782 }
783
784 hard_iface = batadv_netlink_get_hardif(bat_priv, cb);
785 if (IS_ERR(hard_iface) && PTR_ERR(hard_iface) != -ENONET) {
786 ret = PTR_ERR(hard_iface);
787 goto out_put_primary_if;
788 } else if (IS_ERR(hard_iface)) {
789 /* => PTR_ERR(hard_iface) == -ENONET
790 * => no hard-iface given, ok
791 */
792 hard_iface = BATADV_IF_DEFAULT;
793 }
794
795 if (!bat_priv->algo_ops->neigh.dump) {
796 ret = -EOPNOTSUPP;
797 goto out_put_hard_iface;
798 }
799
800 bat_priv->algo_ops->neigh.dump(msg, cb, bat_priv, hard_iface);
801
802 ret = msg->len;
803
804 out_put_hard_iface:
805 batadv_hardif_put(hard_iface);
806 out_put_primary_if:
807 batadv_hardif_put(primary_if);
808 out_put_mesh_iface:
809 dev_put(mesh_iface);
810
811 return ret;
812 }
813
814 /**
815 * batadv_orig_ifinfo_release() - release orig_ifinfo from lists and queue for
816 * free after rcu grace period
817 * @ref: kref pointer of the orig_ifinfo
818 */
batadv_orig_ifinfo_release(struct kref * ref)819 void batadv_orig_ifinfo_release(struct kref *ref)
820 {
821 struct batadv_orig_ifinfo *orig_ifinfo;
822 struct batadv_neigh_node *router;
823
824 orig_ifinfo = container_of(ref, struct batadv_orig_ifinfo, refcount);
825
826 if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
827 batadv_hardif_put(orig_ifinfo->if_outgoing);
828
829 /* this is the last reference to this object */
830 router = rcu_dereference_protected(orig_ifinfo->router, true);
831 batadv_neigh_node_put(router);
832
833 kfree_rcu(orig_ifinfo, rcu);
834 }
835
836 /**
837 * batadv_orig_node_free_rcu() - free the orig_node
838 * @rcu: rcu pointer of the orig_node
839 */
batadv_orig_node_free_rcu(struct rcu_head * rcu)840 static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
841 {
842 struct batadv_orig_node *orig_node;
843
844 orig_node = container_of(rcu, struct batadv_orig_node, rcu);
845
846 batadv_frag_purge_orig(orig_node, NULL);
847
848 kfree(orig_node->tt_buff);
849 kfree(orig_node);
850 }
851
852 /**
853 * batadv_orig_node_release() - release orig_node from lists and queue for
854 * free after rcu grace period
855 * @ref: kref pointer of the orig_node
856 */
batadv_orig_node_release(struct kref * ref)857 void batadv_orig_node_release(struct kref *ref)
858 {
859 struct batadv_orig_ifinfo *last_candidate;
860 struct batadv_orig_ifinfo *orig_ifinfo;
861 struct batadv_neigh_node *neigh_node;
862 struct batadv_orig_node *orig_node;
863 struct batadv_orig_node_vlan *vlan;
864 struct hlist_node *node_tmp;
865
866 orig_node = container_of(ref, struct batadv_orig_node, refcount);
867
868 spin_lock_bh(&orig_node->neigh_list_lock);
869
870 /* for all neighbors towards this originator ... */
871 hlist_for_each_entry_safe(neigh_node, node_tmp,
872 &orig_node->neigh_list, list) {
873 hlist_del_rcu(&neigh_node->list);
874 batadv_neigh_node_put(neigh_node);
875 }
876
877 hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
878 &orig_node->ifinfo_list, list) {
879 hlist_del_rcu(&orig_ifinfo->list);
880 batadv_orig_ifinfo_put(orig_ifinfo);
881 }
882
883 last_candidate = orig_node->last_bonding_candidate;
884 orig_node->last_bonding_candidate = NULL;
885 spin_unlock_bh(&orig_node->neigh_list_lock);
886
887 batadv_orig_ifinfo_put(last_candidate);
888
889 spin_lock_bh(&orig_node->vlan_list_lock);
890 hlist_for_each_entry_safe(vlan, node_tmp, &orig_node->vlan_list, list) {
891 hlist_del_rcu(&vlan->list);
892 batadv_orig_node_vlan_put(vlan);
893 }
894 spin_unlock_bh(&orig_node->vlan_list_lock);
895
896 batadv_mcast_purge_orig(orig_node);
897
898 call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
899 }
900
901 /**
902 * batadv_originator_free() - Free all originator structures
903 * @bat_priv: the bat priv with all the mesh interface information
904 */
batadv_originator_free(struct batadv_priv * bat_priv)905 void batadv_originator_free(struct batadv_priv *bat_priv)
906 {
907 spinlock_t *list_lock; /* spinlock to protect write access */
908 struct batadv_hashtable *hash = bat_priv->orig_hash;
909 struct batadv_orig_node *orig_node;
910 struct hlist_node *node_tmp;
911 struct hlist_head *head;
912 u32 i;
913
914 if (!hash)
915 return;
916
917 disable_delayed_work_sync(&bat_priv->orig_work);
918
919 bat_priv->orig_hash = NULL;
920
921 for (i = 0; i < hash->size; i++) {
922 head = &hash->table[i];
923 list_lock = &hash->list_locks[i];
924
925 spin_lock_bh(list_lock);
926 hlist_for_each_entry_safe(orig_node, node_tmp,
927 head, hash_entry) {
928 hlist_del_rcu(&orig_node->hash_entry);
929 batadv_orig_node_put(orig_node);
930 }
931 spin_unlock_bh(list_lock);
932 }
933
934 batadv_hash_destroy(hash);
935 }
936
937 /**
938 * batadv_orig_node_new() - creates a new orig_node
939 * @bat_priv: the bat priv with all the mesh interface information
940 * @addr: the mac address of the originator
941 *
942 * Creates a new originator object and initialises all the generic fields.
943 * The new object is not added to the originator list.
944 *
945 * Return: the newly created object or NULL on failure.
946 */
batadv_orig_node_new(struct batadv_priv * bat_priv,const u8 * addr)947 struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
948 const u8 *addr)
949 {
950 struct batadv_orig_node *orig_node;
951 struct batadv_orig_node_vlan *vlan;
952 unsigned long reset_time;
953 int i;
954
955 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
956 "Creating new originator: %pM\n", addr);
957
958 orig_node = kzalloc_obj(*orig_node, GFP_ATOMIC);
959 if (!orig_node)
960 return NULL;
961
962 INIT_HLIST_HEAD(&orig_node->neigh_list);
963 INIT_HLIST_HEAD(&orig_node->vlan_list);
964 INIT_HLIST_HEAD(&orig_node->ifinfo_list);
965 spin_lock_init(&orig_node->bcast_seqno_lock);
966 spin_lock_init(&orig_node->neigh_list_lock);
967 spin_lock_init(&orig_node->tt_buff_lock);
968 spin_lock_init(&orig_node->tt_lock);
969 spin_lock_init(&orig_node->vlan_list_lock);
970
971 /* extra reference for return */
972 kref_init(&orig_node->refcount);
973
974 orig_node->bat_priv = bat_priv;
975 ether_addr_copy(orig_node->orig, addr);
976 batadv_dat_init_orig_node_addr(orig_node);
977 WRITE_ONCE(orig_node->last_ttvn, 0);
978 orig_node->tt_buff = NULL;
979 orig_node->tt_buff_len = 0;
980 orig_node->last_seen = jiffies;
981 reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
982 orig_node->bcast_seqno_reset = reset_time;
983
984 #ifdef CONFIG_BATMAN_ADV_MCAST
985 orig_node->mcast_flags = BATADV_MCAST_WANT_NO_RTR4;
986 orig_node->mcast_flags |= BATADV_MCAST_WANT_NO_RTR6;
987 orig_node->mcast_flags |= BATADV_MCAST_HAVE_MC_PTYPE_CAPA;
988 INIT_HLIST_NODE(&orig_node->mcast_want_all_unsnoopables_node);
989 INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv4_node);
990 INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv6_node);
991 spin_lock_init(&orig_node->mcast_handler_lock);
992 #endif
993
994 /* create a vlan object for the "untagged" LAN */
995 vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS);
996 if (!vlan)
997 goto free_orig_node;
998 /* batadv_orig_node_vlan_new() increases the refcounter.
999 * Immediately release vlan since it is not needed anymore in this
1000 * context
1001 */
1002 batadv_orig_node_vlan_put(vlan);
1003
1004 for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
1005 INIT_HLIST_HEAD(&orig_node->fragments[i].fragment_list);
1006 spin_lock_init(&orig_node->fragments[i].lock);
1007 orig_node->fragments[i].size = 0;
1008 }
1009
1010 return orig_node;
1011 free_orig_node:
1012 kfree(orig_node);
1013 return NULL;
1014 }
1015
1016 /**
1017 * batadv_purge_neigh_ifinfo() - purge obsolete ifinfo entries from neighbor
1018 * @bat_priv: the bat priv with all the mesh interface information
1019 * @neigh: orig node which is to be checked
1020 */
1021 static void
batadv_purge_neigh_ifinfo(struct batadv_priv * bat_priv,struct batadv_neigh_node * neigh)1022 batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv,
1023 struct batadv_neigh_node *neigh)
1024 {
1025 struct batadv_neigh_ifinfo *neigh_ifinfo;
1026 struct batadv_hard_iface *if_outgoing;
1027 struct hlist_node *node_tmp;
1028
1029 spin_lock_bh(&neigh->ifinfo_lock);
1030
1031 /* for all ifinfo objects for this neighinator */
1032 hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
1033 &neigh->ifinfo_list, list) {
1034 if_outgoing = neigh_ifinfo->if_outgoing;
1035
1036 /* always keep the default interface */
1037 if (if_outgoing == BATADV_IF_DEFAULT)
1038 continue;
1039
1040 /* don't purge if the interface is not (going) down */
1041 if (if_outgoing->if_status != BATADV_IF_INACTIVE &&
1042 if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED)
1043 continue;
1044
1045 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1046 "neighbor/ifinfo purge: neighbor %pM, iface: %s\n",
1047 neigh->addr, if_outgoing->net_dev->name);
1048
1049 hlist_del_rcu(&neigh_ifinfo->list);
1050 batadv_neigh_ifinfo_put(neigh_ifinfo);
1051 }
1052
1053 spin_unlock_bh(&neigh->ifinfo_lock);
1054 }
1055
1056 /**
1057 * batadv_purge_orig_ifinfo() - purge obsolete ifinfo entries from originator
1058 * @bat_priv: the bat priv with all the mesh interface information
1059 * @orig_node: orig node which is to be checked
1060 *
1061 * Return: true if any ifinfo entry was purged, false otherwise.
1062 */
1063 static bool
batadv_purge_orig_ifinfo(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node)1064 batadv_purge_orig_ifinfo(struct batadv_priv *bat_priv,
1065 struct batadv_orig_node *orig_node)
1066 {
1067 struct batadv_orig_ifinfo *orig_ifinfo;
1068 struct batadv_hard_iface *if_outgoing;
1069 struct hlist_node *node_tmp;
1070 bool ifinfo_purged = false;
1071
1072 spin_lock_bh(&orig_node->neigh_list_lock);
1073
1074 /* for all ifinfo objects for this originator */
1075 hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
1076 &orig_node->ifinfo_list, list) {
1077 if_outgoing = orig_ifinfo->if_outgoing;
1078
1079 /* always keep the default interface */
1080 if (if_outgoing == BATADV_IF_DEFAULT)
1081 continue;
1082
1083 /* don't purge if the interface is not (going) down */
1084 if (if_outgoing->if_status != BATADV_IF_INACTIVE &&
1085 if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED)
1086 continue;
1087
1088 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1089 "router/ifinfo purge: originator %pM, iface: %s\n",
1090 orig_node->orig, if_outgoing->net_dev->name);
1091
1092 ifinfo_purged = true;
1093
1094 hlist_del_rcu(&orig_ifinfo->list);
1095 batadv_orig_ifinfo_put(orig_ifinfo);
1096 if (orig_node->last_bonding_candidate == orig_ifinfo) {
1097 orig_node->last_bonding_candidate = NULL;
1098 batadv_orig_ifinfo_put(orig_ifinfo);
1099 }
1100 }
1101
1102 spin_unlock_bh(&orig_node->neigh_list_lock);
1103
1104 return ifinfo_purged;
1105 }
1106
1107 /**
1108 * batadv_purge_orig_neighbors() - purges neighbors from originator
1109 * @bat_priv: the bat priv with all the mesh interface information
1110 * @orig_node: orig node which is to be checked
1111 *
1112 * Return: true if any neighbor was purged, false otherwise
1113 */
1114 static bool
batadv_purge_orig_neighbors(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node)1115 batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
1116 struct batadv_orig_node *orig_node)
1117 {
1118 struct batadv_hard_iface *if_incoming;
1119 struct batadv_neigh_node *neigh_node;
1120 struct hlist_node *node_tmp;
1121 bool neigh_purged = false;
1122 unsigned long last_seen;
1123
1124 spin_lock_bh(&orig_node->neigh_list_lock);
1125
1126 /* for all neighbors towards this originator ... */
1127 hlist_for_each_entry_safe(neigh_node, node_tmp,
1128 &orig_node->neigh_list, list) {
1129 last_seen = neigh_node->last_seen;
1130 if_incoming = neigh_node->if_incoming;
1131
1132 if (batadv_has_timed_out(last_seen, BATADV_PURGE_TIMEOUT) ||
1133 if_incoming->if_status == BATADV_IF_INACTIVE ||
1134 if_incoming->if_status == BATADV_IF_TO_BE_REMOVED) {
1135 if (if_incoming->if_status == BATADV_IF_INACTIVE ||
1136 if_incoming->if_status == BATADV_IF_TO_BE_REMOVED)
1137 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1138 "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n",
1139 orig_node->orig, neigh_node->addr,
1140 if_incoming->net_dev->name);
1141 else
1142 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1143 "neighbor timeout: originator %pM, neighbor: %pM, last_seen: %u\n",
1144 orig_node->orig, neigh_node->addr,
1145 jiffies_to_msecs(last_seen));
1146
1147 neigh_purged = true;
1148
1149 hlist_del_rcu(&neigh_node->list);
1150 batadv_neigh_node_put(neigh_node);
1151 } else {
1152 /* only necessary if not the whole neighbor is to be
1153 * deleted, but some interface has been removed.
1154 */
1155 batadv_purge_neigh_ifinfo(bat_priv, neigh_node);
1156 }
1157 }
1158
1159 spin_unlock_bh(&orig_node->neigh_list_lock);
1160 return neigh_purged;
1161 }
1162
1163 /**
1164 * batadv_find_best_neighbor() - finds the best neighbor after purging
1165 * @bat_priv: the bat priv with all the mesh interface information
1166 * @orig_node: orig node which is to be checked
1167 * @if_outgoing: the interface for which the metric should be compared
1168 *
1169 * Return: the current best neighbor, with refcount increased.
1170 */
1171 static struct batadv_neigh_node *
batadv_find_best_neighbor(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,struct batadv_hard_iface * if_outgoing)1172 batadv_find_best_neighbor(struct batadv_priv *bat_priv,
1173 struct batadv_orig_node *orig_node,
1174 struct batadv_hard_iface *if_outgoing)
1175 {
1176 struct batadv_algo_ops *bao = bat_priv->algo_ops;
1177 struct batadv_neigh_node *best = NULL;
1178 struct batadv_neigh_node *neigh;
1179
1180 rcu_read_lock();
1181 hlist_for_each_entry_rcu(neigh, &orig_node->neigh_list, list) {
1182 if (best && (bao->neigh.cmp(neigh, if_outgoing, best,
1183 if_outgoing) <= 0))
1184 continue;
1185
1186 if (!kref_get_unless_zero(&neigh->refcount))
1187 continue;
1188
1189 batadv_neigh_node_put(best);
1190
1191 best = neigh;
1192 }
1193 rcu_read_unlock();
1194
1195 return best;
1196 }
1197
1198 /**
1199 * batadv_purge_orig_node() - purges obsolete information from an orig_node
1200 * @bat_priv: the bat priv with all the mesh interface information
1201 * @orig_node: orig node which is to be checked
1202 *
1203 * This function checks if the orig_node or substructures of it have become
1204 * obsolete, and purges this information if that's the case.
1205 *
1206 * Return: true if the orig_node is to be removed, false otherwise.
1207 */
batadv_purge_orig_node(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node)1208 static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
1209 struct batadv_orig_node *orig_node)
1210 {
1211 struct batadv_neigh_node *best_neigh_node;
1212 struct batadv_hard_iface *hard_iface;
1213 struct list_head *iter;
1214 bool changed_ifinfo;
1215 bool changed_neigh;
1216
1217 if (batadv_has_timed_out(orig_node->last_seen,
1218 2 * BATADV_PURGE_TIMEOUT)) {
1219 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1220 "Originator timeout: originator %pM, last_seen %u\n",
1221 orig_node->orig,
1222 jiffies_to_msecs(orig_node->last_seen));
1223 return true;
1224 }
1225 changed_ifinfo = batadv_purge_orig_ifinfo(bat_priv, orig_node);
1226 changed_neigh = batadv_purge_orig_neighbors(bat_priv, orig_node);
1227
1228 if (!changed_ifinfo && !changed_neigh)
1229 return false;
1230
1231 /* first for NULL ... */
1232 best_neigh_node = batadv_find_best_neighbor(bat_priv, orig_node,
1233 BATADV_IF_DEFAULT);
1234 batadv_update_route(bat_priv, orig_node, BATADV_IF_DEFAULT,
1235 best_neigh_node);
1236 batadv_neigh_node_put(best_neigh_node);
1237
1238 /* ... then for all other interfaces. */
1239 rcu_read_lock();
1240 netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
1241 if (hard_iface->if_status != BATADV_IF_ACTIVE)
1242 continue;
1243
1244 if (!kref_get_unless_zero(&hard_iface->refcount))
1245 continue;
1246
1247 best_neigh_node = batadv_find_best_neighbor(bat_priv,
1248 orig_node,
1249 hard_iface);
1250 batadv_update_route(bat_priv, orig_node, hard_iface,
1251 best_neigh_node);
1252 batadv_neigh_node_put(best_neigh_node);
1253
1254 batadv_hardif_put(hard_iface);
1255 }
1256 rcu_read_unlock();
1257
1258 return false;
1259 }
1260
1261 /**
1262 * batadv_purge_orig_ref() - Purge all outdated originators
1263 * @bat_priv: the bat priv with all the mesh interface information
1264 */
batadv_purge_orig_ref(struct batadv_priv * bat_priv)1265 void batadv_purge_orig_ref(struct batadv_priv *bat_priv)
1266 {
1267 spinlock_t *list_lock; /* spinlock to protect write access */
1268 struct batadv_hashtable *hash = bat_priv->orig_hash;
1269 struct batadv_orig_node *orig_node;
1270 struct hlist_node *node_tmp;
1271 struct hlist_head *head;
1272 u32 i;
1273
1274 if (!hash)
1275 return;
1276
1277 /* for all origins... */
1278 for (i = 0; i < hash->size; i++) {
1279 head = &hash->table[i];
1280 if (hlist_empty(head))
1281 continue;
1282 list_lock = &hash->list_locks[i];
1283
1284 spin_lock_bh(list_lock);
1285 hlist_for_each_entry_safe(orig_node, node_tmp,
1286 head, hash_entry) {
1287 if (batadv_purge_orig_node(bat_priv, orig_node)) {
1288 batadv_gw_node_delete(bat_priv, orig_node);
1289 hlist_del_rcu(&orig_node->hash_entry);
1290 batadv_tt_global_del_orig(orig_node->bat_priv,
1291 orig_node, -1,
1292 "originator timed out");
1293 batadv_orig_node_put(orig_node);
1294 continue;
1295 }
1296
1297 batadv_frag_purge_orig(orig_node,
1298 batadv_frag_check_entry);
1299 }
1300 spin_unlock_bh(list_lock);
1301 }
1302
1303 batadv_gw_election(bat_priv);
1304 }
1305
1306 /**
1307 * batadv_purge_orig() - periodic worker to purge stale originator entries
1308 * @work: delayed work embedded in the bat_priv
1309 *
1310 * Invoke batadv_purge_orig_ref() to drop stale originators and reschedule the
1311 * next run after BATADV_ORIG_WORK_PERIOD milliseconds.
1312 */
batadv_purge_orig(struct work_struct * work)1313 static void batadv_purge_orig(struct work_struct *work)
1314 {
1315 struct delayed_work *delayed_work;
1316 struct batadv_priv *bat_priv;
1317
1318 delayed_work = to_delayed_work(work);
1319 bat_priv = container_of(delayed_work, struct batadv_priv, orig_work);
1320 batadv_purge_orig_ref(bat_priv);
1321 queue_delayed_work(batadv_event_workqueue,
1322 &bat_priv->orig_work,
1323 msecs_to_jiffies(BATADV_ORIG_WORK_PERIOD));
1324 }
1325
1326 /**
1327 * batadv_orig_dump() - Dump to netlink the originator infos for a specific
1328 * outgoing interface
1329 * @msg: message to dump into
1330 * @cb: parameters for the dump
1331 *
1332 * Return: 0 or error value
1333 */
batadv_orig_dump(struct sk_buff * msg,struct netlink_callback * cb)1334 int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb)
1335 {
1336 struct batadv_hard_iface *primary_if;
1337 struct batadv_hard_iface *hard_iface;
1338 struct net_device *mesh_iface;
1339 struct batadv_priv *bat_priv;
1340 int ret;
1341
1342 mesh_iface = batadv_netlink_get_meshif(cb);
1343 if (IS_ERR(mesh_iface))
1344 return PTR_ERR(mesh_iface);
1345
1346 bat_priv = netdev_priv(mesh_iface);
1347
1348 primary_if = batadv_primary_if_get_selected(bat_priv);
1349 if (!primary_if) {
1350 ret = -ENOENT;
1351 goto out_put_mesh_iface;
1352 }
1353
1354 if (primary_if->if_status != BATADV_IF_ACTIVE) {
1355 ret = -ENOENT;
1356 goto out_put_primary_if;
1357 }
1358
1359 hard_iface = batadv_netlink_get_hardif(bat_priv, cb);
1360 if (IS_ERR(hard_iface) && PTR_ERR(hard_iface) != -ENONET) {
1361 ret = PTR_ERR(hard_iface);
1362 goto out_put_primary_if;
1363 } else if (IS_ERR(hard_iface)) {
1364 /* => PTR_ERR(hard_iface) == -ENONET
1365 * => no hard-iface given, ok
1366 */
1367 hard_iface = BATADV_IF_DEFAULT;
1368 }
1369
1370 if (!bat_priv->algo_ops->orig.dump) {
1371 ret = -EOPNOTSUPP;
1372 goto out_put_hard_iface;
1373 }
1374
1375 bat_priv->algo_ops->orig.dump(msg, cb, bat_priv, hard_iface);
1376
1377 ret = msg->len;
1378
1379 out_put_hard_iface:
1380 batadv_hardif_put(hard_iface);
1381 out_put_primary_if:
1382 batadv_hardif_put(primary_if);
1383 out_put_mesh_iface:
1384 dev_put(mesh_iface);
1385
1386 return ret;
1387 }
1388