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