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