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