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/jiffies.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 */ 47 static 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 */ 56 struct batadv_orig_node * 57 batadv_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 86 static 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 */ 95 bool 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 */ 111 struct batadv_orig_node_vlan * 112 batadv_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 */ 146 struct batadv_orig_node_vlan * 147 batadv_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 169 out: 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 */ 180 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_originator_init() - Initialize all originator structures 191 * @bat_priv: the bat priv with all the soft interface information 192 * 193 * Return: 0 on success or negative error number in case of failure 194 */ 195 int batadv_originator_init(struct batadv_priv *bat_priv) 196 { 197 if (bat_priv->orig_hash) 198 return 0; 199 200 bat_priv->orig_hash = batadv_hash_new(1024); 201 202 if (!bat_priv->orig_hash) 203 goto err; 204 205 batadv_hash_set_lock_class(bat_priv->orig_hash, 206 &batadv_orig_hash_lock_class_key); 207 208 INIT_DELAYED_WORK(&bat_priv->orig_work, batadv_purge_orig); 209 queue_delayed_work(batadv_event_workqueue, 210 &bat_priv->orig_work, 211 msecs_to_jiffies(BATADV_ORIG_WORK_PERIOD)); 212 213 return 0; 214 215 err: 216 return -ENOMEM; 217 } 218 219 /** 220 * batadv_neigh_ifinfo_release() - release neigh_ifinfo from lists and queue for 221 * free after rcu grace period 222 * @ref: kref pointer of the neigh_ifinfo 223 */ 224 void batadv_neigh_ifinfo_release(struct kref *ref) 225 { 226 struct batadv_neigh_ifinfo *neigh_ifinfo; 227 228 neigh_ifinfo = container_of(ref, struct batadv_neigh_ifinfo, refcount); 229 230 if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT) 231 batadv_hardif_put(neigh_ifinfo->if_outgoing); 232 233 kfree_rcu(neigh_ifinfo, rcu); 234 } 235 236 /** 237 * batadv_hardif_neigh_release() - release hardif neigh node from lists and 238 * queue for free after rcu grace period 239 * @ref: kref pointer of the neigh_node 240 */ 241 void batadv_hardif_neigh_release(struct kref *ref) 242 { 243 struct batadv_hardif_neigh_node *hardif_neigh; 244 245 hardif_neigh = container_of(ref, struct batadv_hardif_neigh_node, 246 refcount); 247 248 spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); 249 hlist_del_init_rcu(&hardif_neigh->list); 250 spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); 251 252 batadv_hardif_put(hardif_neigh->if_incoming); 253 kfree_rcu(hardif_neigh, rcu); 254 } 255 256 /** 257 * batadv_neigh_node_release() - release neigh_node from lists and queue for 258 * free after rcu grace period 259 * @ref: kref pointer of the neigh_node 260 */ 261 void batadv_neigh_node_release(struct kref *ref) 262 { 263 struct hlist_node *node_tmp; 264 struct batadv_neigh_node *neigh_node; 265 struct batadv_neigh_ifinfo *neigh_ifinfo; 266 267 neigh_node = container_of(ref, struct batadv_neigh_node, refcount); 268 269 hlist_for_each_entry_safe(neigh_ifinfo, node_tmp, 270 &neigh_node->ifinfo_list, list) { 271 batadv_neigh_ifinfo_put(neigh_ifinfo); 272 } 273 274 batadv_hardif_neigh_put(neigh_node->hardif_neigh); 275 276 batadv_hardif_put(neigh_node->if_incoming); 277 278 kfree_rcu(neigh_node, rcu); 279 } 280 281 /** 282 * batadv_orig_router_get() - router to the originator depending on iface 283 * @orig_node: the orig node for the router 284 * @if_outgoing: the interface where the payload packet has been received or 285 * the OGM should be sent to 286 * 287 * Return: the neighbor which should be the router for this orig_node/iface. 288 * 289 * The object is returned with refcounter increased by 1. 290 */ 291 struct batadv_neigh_node * 292 batadv_orig_router_get(struct batadv_orig_node *orig_node, 293 const struct batadv_hard_iface *if_outgoing) 294 { 295 struct batadv_orig_ifinfo *orig_ifinfo; 296 struct batadv_neigh_node *router = NULL; 297 298 rcu_read_lock(); 299 hlist_for_each_entry_rcu(orig_ifinfo, &orig_node->ifinfo_list, list) { 300 if (orig_ifinfo->if_outgoing != if_outgoing) 301 continue; 302 303 router = rcu_dereference(orig_ifinfo->router); 304 break; 305 } 306 307 if (router && !kref_get_unless_zero(&router->refcount)) 308 router = NULL; 309 310 rcu_read_unlock(); 311 return router; 312 } 313 314 /** 315 * batadv_orig_to_router() - get next hop neighbor to an orig address 316 * @bat_priv: the bat priv with all the soft interface information 317 * @orig_addr: the originator MAC address to search the best next hop router for 318 * @if_outgoing: the interface where the payload packet has been received or 319 * the OGM should be sent to 320 * 321 * Return: A neighbor node which is the best router towards the given originator 322 * address. 323 */ 324 struct batadv_neigh_node * 325 batadv_orig_to_router(struct batadv_priv *bat_priv, u8 *orig_addr, 326 struct batadv_hard_iface *if_outgoing) 327 { 328 struct batadv_neigh_node *neigh_node; 329 struct batadv_orig_node *orig_node; 330 331 orig_node = batadv_orig_hash_find(bat_priv, orig_addr); 332 if (!orig_node) 333 return NULL; 334 335 neigh_node = batadv_find_router(bat_priv, orig_node, if_outgoing); 336 batadv_orig_node_put(orig_node); 337 338 return neigh_node; 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 orig_node->mcast_flags |= BATADV_MCAST_HAVE_MC_PTYPE_CAPA; 973 INIT_HLIST_NODE(&orig_node->mcast_want_all_unsnoopables_node); 974 INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv4_node); 975 INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv6_node); 976 spin_lock_init(&orig_node->mcast_handler_lock); 977 #endif 978 979 /* create a vlan object for the "untagged" LAN */ 980 vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS); 981 if (!vlan) 982 goto free_orig_node; 983 /* batadv_orig_node_vlan_new() increases the refcounter. 984 * Immediately release vlan since it is not needed anymore in this 985 * context 986 */ 987 batadv_orig_node_vlan_put(vlan); 988 989 for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) { 990 INIT_HLIST_HEAD(&orig_node->fragments[i].fragment_list); 991 spin_lock_init(&orig_node->fragments[i].lock); 992 orig_node->fragments[i].size = 0; 993 } 994 995 return orig_node; 996 free_orig_node: 997 kfree(orig_node); 998 return NULL; 999 } 1000 1001 /** 1002 * batadv_purge_neigh_ifinfo() - purge obsolete ifinfo entries from neighbor 1003 * @bat_priv: the bat priv with all the soft interface information 1004 * @neigh: orig node which is to be checked 1005 */ 1006 static void 1007 batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv, 1008 struct batadv_neigh_node *neigh) 1009 { 1010 struct batadv_neigh_ifinfo *neigh_ifinfo; 1011 struct batadv_hard_iface *if_outgoing; 1012 struct hlist_node *node_tmp; 1013 1014 spin_lock_bh(&neigh->ifinfo_lock); 1015 1016 /* for all ifinfo objects for this neighinator */ 1017 hlist_for_each_entry_safe(neigh_ifinfo, node_tmp, 1018 &neigh->ifinfo_list, list) { 1019 if_outgoing = neigh_ifinfo->if_outgoing; 1020 1021 /* always keep the default interface */ 1022 if (if_outgoing == BATADV_IF_DEFAULT) 1023 continue; 1024 1025 /* don't purge if the interface is not (going) down */ 1026 if (if_outgoing->if_status != BATADV_IF_INACTIVE && 1027 if_outgoing->if_status != BATADV_IF_NOT_IN_USE && 1028 if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED) 1029 continue; 1030 1031 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1032 "neighbor/ifinfo purge: neighbor %pM, iface: %s\n", 1033 neigh->addr, if_outgoing->net_dev->name); 1034 1035 hlist_del_rcu(&neigh_ifinfo->list); 1036 batadv_neigh_ifinfo_put(neigh_ifinfo); 1037 } 1038 1039 spin_unlock_bh(&neigh->ifinfo_lock); 1040 } 1041 1042 /** 1043 * batadv_purge_orig_ifinfo() - purge obsolete ifinfo entries from originator 1044 * @bat_priv: the bat priv with all the soft interface information 1045 * @orig_node: orig node which is to be checked 1046 * 1047 * Return: true if any ifinfo entry was purged, false otherwise. 1048 */ 1049 static bool 1050 batadv_purge_orig_ifinfo(struct batadv_priv *bat_priv, 1051 struct batadv_orig_node *orig_node) 1052 { 1053 struct batadv_orig_ifinfo *orig_ifinfo; 1054 struct batadv_hard_iface *if_outgoing; 1055 struct hlist_node *node_tmp; 1056 bool ifinfo_purged = false; 1057 1058 spin_lock_bh(&orig_node->neigh_list_lock); 1059 1060 /* for all ifinfo objects for this originator */ 1061 hlist_for_each_entry_safe(orig_ifinfo, node_tmp, 1062 &orig_node->ifinfo_list, list) { 1063 if_outgoing = orig_ifinfo->if_outgoing; 1064 1065 /* always keep the default interface */ 1066 if (if_outgoing == BATADV_IF_DEFAULT) 1067 continue; 1068 1069 /* don't purge if the interface is not (going) down */ 1070 if (if_outgoing->if_status != BATADV_IF_INACTIVE && 1071 if_outgoing->if_status != BATADV_IF_NOT_IN_USE && 1072 if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED) 1073 continue; 1074 1075 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1076 "router/ifinfo purge: originator %pM, iface: %s\n", 1077 orig_node->orig, if_outgoing->net_dev->name); 1078 1079 ifinfo_purged = true; 1080 1081 hlist_del_rcu(&orig_ifinfo->list); 1082 batadv_orig_ifinfo_put(orig_ifinfo); 1083 if (orig_node->last_bonding_candidate == orig_ifinfo) { 1084 orig_node->last_bonding_candidate = NULL; 1085 batadv_orig_ifinfo_put(orig_ifinfo); 1086 } 1087 } 1088 1089 spin_unlock_bh(&orig_node->neigh_list_lock); 1090 1091 return ifinfo_purged; 1092 } 1093 1094 /** 1095 * batadv_purge_orig_neighbors() - purges neighbors from originator 1096 * @bat_priv: the bat priv with all the soft interface information 1097 * @orig_node: orig node which is to be checked 1098 * 1099 * Return: true if any neighbor was purged, false otherwise 1100 */ 1101 static bool 1102 batadv_purge_orig_neighbors(struct batadv_priv *bat_priv, 1103 struct batadv_orig_node *orig_node) 1104 { 1105 struct hlist_node *node_tmp; 1106 struct batadv_neigh_node *neigh_node; 1107 bool neigh_purged = false; 1108 unsigned long last_seen; 1109 struct batadv_hard_iface *if_incoming; 1110 1111 spin_lock_bh(&orig_node->neigh_list_lock); 1112 1113 /* for all neighbors towards this originator ... */ 1114 hlist_for_each_entry_safe(neigh_node, node_tmp, 1115 &orig_node->neigh_list, list) { 1116 last_seen = neigh_node->last_seen; 1117 if_incoming = neigh_node->if_incoming; 1118 1119 if (batadv_has_timed_out(last_seen, BATADV_PURGE_TIMEOUT) || 1120 if_incoming->if_status == BATADV_IF_INACTIVE || 1121 if_incoming->if_status == BATADV_IF_NOT_IN_USE || 1122 if_incoming->if_status == BATADV_IF_TO_BE_REMOVED) { 1123 if (if_incoming->if_status == BATADV_IF_INACTIVE || 1124 if_incoming->if_status == BATADV_IF_NOT_IN_USE || 1125 if_incoming->if_status == BATADV_IF_TO_BE_REMOVED) 1126 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1127 "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n", 1128 orig_node->orig, neigh_node->addr, 1129 if_incoming->net_dev->name); 1130 else 1131 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1132 "neighbor timeout: originator %pM, neighbor: %pM, last_seen: %u\n", 1133 orig_node->orig, neigh_node->addr, 1134 jiffies_to_msecs(last_seen)); 1135 1136 neigh_purged = true; 1137 1138 hlist_del_rcu(&neigh_node->list); 1139 batadv_neigh_node_put(neigh_node); 1140 } else { 1141 /* only necessary if not the whole neighbor is to be 1142 * deleted, but some interface has been removed. 1143 */ 1144 batadv_purge_neigh_ifinfo(bat_priv, neigh_node); 1145 } 1146 } 1147 1148 spin_unlock_bh(&orig_node->neigh_list_lock); 1149 return neigh_purged; 1150 } 1151 1152 /** 1153 * batadv_find_best_neighbor() - finds the best neighbor after purging 1154 * @bat_priv: the bat priv with all the soft interface information 1155 * @orig_node: orig node which is to be checked 1156 * @if_outgoing: the interface for which the metric should be compared 1157 * 1158 * Return: the current best neighbor, with refcount increased. 1159 */ 1160 static struct batadv_neigh_node * 1161 batadv_find_best_neighbor(struct batadv_priv *bat_priv, 1162 struct batadv_orig_node *orig_node, 1163 struct batadv_hard_iface *if_outgoing) 1164 { 1165 struct batadv_neigh_node *best = NULL, *neigh; 1166 struct batadv_algo_ops *bao = bat_priv->algo_ops; 1167 1168 rcu_read_lock(); 1169 hlist_for_each_entry_rcu(neigh, &orig_node->neigh_list, list) { 1170 if (best && (bao->neigh.cmp(neigh, if_outgoing, best, 1171 if_outgoing) <= 0)) 1172 continue; 1173 1174 if (!kref_get_unless_zero(&neigh->refcount)) 1175 continue; 1176 1177 batadv_neigh_node_put(best); 1178 1179 best = neigh; 1180 } 1181 rcu_read_unlock(); 1182 1183 return best; 1184 } 1185 1186 /** 1187 * batadv_purge_orig_node() - purges obsolete information from an orig_node 1188 * @bat_priv: the bat priv with all the soft interface information 1189 * @orig_node: orig node which is to be checked 1190 * 1191 * This function checks if the orig_node or substructures of it have become 1192 * obsolete, and purges this information if that's the case. 1193 * 1194 * Return: true if the orig_node is to be removed, false otherwise. 1195 */ 1196 static bool batadv_purge_orig_node(struct batadv_priv *bat_priv, 1197 struct batadv_orig_node *orig_node) 1198 { 1199 struct batadv_neigh_node *best_neigh_node; 1200 struct batadv_hard_iface *hard_iface; 1201 bool changed_ifinfo, changed_neigh; 1202 1203 if (batadv_has_timed_out(orig_node->last_seen, 1204 2 * BATADV_PURGE_TIMEOUT)) { 1205 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1206 "Originator timeout: originator %pM, last_seen %u\n", 1207 orig_node->orig, 1208 jiffies_to_msecs(orig_node->last_seen)); 1209 return true; 1210 } 1211 changed_ifinfo = batadv_purge_orig_ifinfo(bat_priv, orig_node); 1212 changed_neigh = batadv_purge_orig_neighbors(bat_priv, orig_node); 1213 1214 if (!changed_ifinfo && !changed_neigh) 1215 return false; 1216 1217 /* first for NULL ... */ 1218 best_neigh_node = batadv_find_best_neighbor(bat_priv, orig_node, 1219 BATADV_IF_DEFAULT); 1220 batadv_update_route(bat_priv, orig_node, BATADV_IF_DEFAULT, 1221 best_neigh_node); 1222 batadv_neigh_node_put(best_neigh_node); 1223 1224 /* ... then for all other interfaces. */ 1225 rcu_read_lock(); 1226 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 1227 if (hard_iface->if_status != BATADV_IF_ACTIVE) 1228 continue; 1229 1230 if (hard_iface->soft_iface != bat_priv->soft_iface) 1231 continue; 1232 1233 if (!kref_get_unless_zero(&hard_iface->refcount)) 1234 continue; 1235 1236 best_neigh_node = batadv_find_best_neighbor(bat_priv, 1237 orig_node, 1238 hard_iface); 1239 batadv_update_route(bat_priv, orig_node, hard_iface, 1240 best_neigh_node); 1241 batadv_neigh_node_put(best_neigh_node); 1242 1243 batadv_hardif_put(hard_iface); 1244 } 1245 rcu_read_unlock(); 1246 1247 return false; 1248 } 1249 1250 /** 1251 * batadv_purge_orig_ref() - Purge all outdated originators 1252 * @bat_priv: the bat priv with all the soft interface information 1253 */ 1254 void batadv_purge_orig_ref(struct batadv_priv *bat_priv) 1255 { 1256 struct batadv_hashtable *hash = bat_priv->orig_hash; 1257 struct hlist_node *node_tmp; 1258 struct hlist_head *head; 1259 spinlock_t *list_lock; /* spinlock to protect write access */ 1260 struct batadv_orig_node *orig_node; 1261 u32 i; 1262 1263 if (!hash) 1264 return; 1265 1266 /* for all origins... */ 1267 for (i = 0; i < hash->size; i++) { 1268 head = &hash->table[i]; 1269 list_lock = &hash->list_locks[i]; 1270 1271 spin_lock_bh(list_lock); 1272 hlist_for_each_entry_safe(orig_node, node_tmp, 1273 head, hash_entry) { 1274 if (batadv_purge_orig_node(bat_priv, orig_node)) { 1275 batadv_gw_node_delete(bat_priv, orig_node); 1276 hlist_del_rcu(&orig_node->hash_entry); 1277 batadv_tt_global_del_orig(orig_node->bat_priv, 1278 orig_node, -1, 1279 "originator timed out"); 1280 batadv_orig_node_put(orig_node); 1281 continue; 1282 } 1283 1284 batadv_frag_purge_orig(orig_node, 1285 batadv_frag_check_entry); 1286 } 1287 spin_unlock_bh(list_lock); 1288 } 1289 1290 batadv_gw_election(bat_priv); 1291 } 1292 1293 static void batadv_purge_orig(struct work_struct *work) 1294 { 1295 struct delayed_work *delayed_work; 1296 struct batadv_priv *bat_priv; 1297 1298 delayed_work = to_delayed_work(work); 1299 bat_priv = container_of(delayed_work, struct batadv_priv, orig_work); 1300 batadv_purge_orig_ref(bat_priv); 1301 queue_delayed_work(batadv_event_workqueue, 1302 &bat_priv->orig_work, 1303 msecs_to_jiffies(BATADV_ORIG_WORK_PERIOD)); 1304 } 1305 1306 /** 1307 * batadv_orig_dump() - Dump to netlink the originator infos for a specific 1308 * outgoing interface 1309 * @msg: message to dump into 1310 * @cb: parameters for the dump 1311 * 1312 * Return: 0 or error value 1313 */ 1314 int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb) 1315 { 1316 struct net *net = sock_net(cb->skb->sk); 1317 struct net_device *soft_iface; 1318 struct net_device *hard_iface = NULL; 1319 struct batadv_hard_iface *hardif = BATADV_IF_DEFAULT; 1320 struct batadv_priv *bat_priv; 1321 struct batadv_hard_iface *primary_if = NULL; 1322 int ret; 1323 int ifindex, hard_ifindex; 1324 1325 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX); 1326 if (!ifindex) 1327 return -EINVAL; 1328 1329 soft_iface = dev_get_by_index(net, ifindex); 1330 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { 1331 ret = -ENODEV; 1332 goto out; 1333 } 1334 1335 bat_priv = netdev_priv(soft_iface); 1336 1337 primary_if = batadv_primary_if_get_selected(bat_priv); 1338 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { 1339 ret = -ENOENT; 1340 goto out; 1341 } 1342 1343 hard_ifindex = batadv_netlink_get_ifindex(cb->nlh, 1344 BATADV_ATTR_HARD_IFINDEX); 1345 if (hard_ifindex) { 1346 hard_iface = dev_get_by_index(net, hard_ifindex); 1347 if (hard_iface) 1348 hardif = batadv_hardif_get_by_netdev(hard_iface); 1349 1350 if (!hardif) { 1351 ret = -ENODEV; 1352 goto out; 1353 } 1354 1355 if (hardif->soft_iface != soft_iface) { 1356 ret = -ENOENT; 1357 goto out; 1358 } 1359 } 1360 1361 if (!bat_priv->algo_ops->orig.dump) { 1362 ret = -EOPNOTSUPP; 1363 goto out; 1364 } 1365 1366 bat_priv->algo_ops->orig.dump(msg, cb, bat_priv, hardif); 1367 1368 ret = msg->len; 1369 1370 out: 1371 batadv_hardif_put(hardif); 1372 dev_put(hard_iface); 1373 batadv_hardif_put(primary_if); 1374 dev_put(soft_iface); 1375 1376 return ret; 1377 } 1378