Linux Audio

Check our new training course

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