1 /* Copyright (C) 2007-2015 B.A.T.M.A.N. contributors: 2 * 3 * Marek Lindner, Simon Wunderlich 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of version 2 of the GNU General Public 7 * License as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "hard-interface.h" 19 #include "main.h" 20 21 #include <linux/bug.h> 22 #include <linux/byteorder/generic.h> 23 #include <linux/errno.h> 24 #include <linux/fs.h> 25 #include <linux/if_arp.h> 26 #include <linux/if_ether.h> 27 #include <linux/if.h> 28 #include <linux/kernel.h> 29 #include <linux/list.h> 30 #include <linux/netdevice.h> 31 #include <linux/printk.h> 32 #include <linux/rculist.h> 33 #include <linux/rtnetlink.h> 34 #include <linux/slab.h> 35 #include <linux/workqueue.h> 36 #include <net/net_namespace.h> 37 38 #include "bridge_loop_avoidance.h" 39 #include "debugfs.h" 40 #include "distributed-arp-table.h" 41 #include "gateway_client.h" 42 #include "originator.h" 43 #include "packet.h" 44 #include "send.h" 45 #include "soft-interface.h" 46 #include "sysfs.h" 47 #include "translation-table.h" 48 49 void batadv_hardif_free_rcu(struct rcu_head *rcu) 50 { 51 struct batadv_hard_iface *hard_iface; 52 53 hard_iface = container_of(rcu, struct batadv_hard_iface, rcu); 54 dev_put(hard_iface->net_dev); 55 kfree(hard_iface); 56 } 57 58 struct batadv_hard_iface * 59 batadv_hardif_get_by_netdev(const struct net_device *net_dev) 60 { 61 struct batadv_hard_iface *hard_iface; 62 63 rcu_read_lock(); 64 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 65 if (hard_iface->net_dev == net_dev && 66 atomic_inc_not_zero(&hard_iface->refcount)) 67 goto out; 68 } 69 70 hard_iface = NULL; 71 72 out: 73 rcu_read_unlock(); 74 return hard_iface; 75 } 76 77 /** 78 * batadv_is_on_batman_iface - check if a device is a batman iface descendant 79 * @net_dev: the device to check 80 * 81 * If the user creates any virtual device on top of a batman-adv interface, it 82 * is important to prevent this new interface to be used to create a new mesh 83 * network (this behaviour would lead to a batman-over-batman configuration). 84 * This function recursively checks all the fathers of the device passed as 85 * argument looking for a batman-adv soft interface. 86 * 87 * Returns true if the device is descendant of a batman-adv mesh interface (or 88 * if it is a batman-adv interface itself), false otherwise 89 */ 90 static bool batadv_is_on_batman_iface(const struct net_device *net_dev) 91 { 92 struct net_device *parent_dev; 93 bool ret; 94 95 /* check if this is a batman-adv mesh interface */ 96 if (batadv_softif_is_valid(net_dev)) 97 return true; 98 99 /* no more parents..stop recursion */ 100 if (dev_get_iflink(net_dev) == 0 || 101 dev_get_iflink(net_dev) == net_dev->ifindex) 102 return false; 103 104 /* recurse over the parent device */ 105 parent_dev = __dev_get_by_index(&init_net, dev_get_iflink(net_dev)); 106 /* if we got a NULL parent_dev there is something broken.. */ 107 if (WARN(!parent_dev, "Cannot find parent device")) 108 return false; 109 110 ret = batadv_is_on_batman_iface(parent_dev); 111 112 return ret; 113 } 114 115 static int batadv_is_valid_iface(const struct net_device *net_dev) 116 { 117 if (net_dev->flags & IFF_LOOPBACK) 118 return 0; 119 120 if (net_dev->type != ARPHRD_ETHER) 121 return 0; 122 123 if (net_dev->addr_len != ETH_ALEN) 124 return 0; 125 126 /* no batman over batman */ 127 if (batadv_is_on_batman_iface(net_dev)) 128 return 0; 129 130 return 1; 131 } 132 133 /** 134 * batadv_is_wifi_netdev - check if the given net_device struct is a wifi 135 * interface 136 * @net_device: the device to check 137 * 138 * Returns true if the net device is a 802.11 wireless device, false otherwise. 139 */ 140 bool batadv_is_wifi_netdev(struct net_device *net_device) 141 { 142 if (!net_device) 143 return false; 144 145 #ifdef CONFIG_WIRELESS_EXT 146 /* pre-cfg80211 drivers have to implement WEXT, so it is possible to 147 * check for wireless_handlers != NULL 148 */ 149 if (net_device->wireless_handlers) 150 return true; 151 #endif 152 153 /* cfg80211 drivers have to set ieee80211_ptr */ 154 if (net_device->ieee80211_ptr) 155 return true; 156 157 return false; 158 } 159 160 static struct batadv_hard_iface * 161 batadv_hardif_get_active(const struct net_device *soft_iface) 162 { 163 struct batadv_hard_iface *hard_iface; 164 165 rcu_read_lock(); 166 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 167 if (hard_iface->soft_iface != soft_iface) 168 continue; 169 170 if (hard_iface->if_status == BATADV_IF_ACTIVE && 171 atomic_inc_not_zero(&hard_iface->refcount)) 172 goto out; 173 } 174 175 hard_iface = NULL; 176 177 out: 178 rcu_read_unlock(); 179 return hard_iface; 180 } 181 182 static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv, 183 struct batadv_hard_iface *oldif) 184 { 185 struct batadv_hard_iface *primary_if; 186 187 primary_if = batadv_primary_if_get_selected(bat_priv); 188 if (!primary_if) 189 goto out; 190 191 batadv_dat_init_own_addr(bat_priv, primary_if); 192 batadv_bla_update_orig_address(bat_priv, primary_if, oldif); 193 out: 194 if (primary_if) 195 batadv_hardif_free_ref(primary_if); 196 } 197 198 static void batadv_primary_if_select(struct batadv_priv *bat_priv, 199 struct batadv_hard_iface *new_hard_iface) 200 { 201 struct batadv_hard_iface *curr_hard_iface; 202 203 ASSERT_RTNL(); 204 205 if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount)) 206 new_hard_iface = NULL; 207 208 curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1); 209 rcu_assign_pointer(bat_priv->primary_if, new_hard_iface); 210 211 if (!new_hard_iface) 212 goto out; 213 214 bat_priv->bat_algo_ops->bat_primary_iface_set(new_hard_iface); 215 batadv_primary_if_update_addr(bat_priv, curr_hard_iface); 216 217 out: 218 if (curr_hard_iface) 219 batadv_hardif_free_ref(curr_hard_iface); 220 } 221 222 static bool 223 batadv_hardif_is_iface_up(const struct batadv_hard_iface *hard_iface) 224 { 225 if (hard_iface->net_dev->flags & IFF_UP) 226 return true; 227 228 return false; 229 } 230 231 static void batadv_check_known_mac_addr(const struct net_device *net_dev) 232 { 233 const struct batadv_hard_iface *hard_iface; 234 235 rcu_read_lock(); 236 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 237 if ((hard_iface->if_status != BATADV_IF_ACTIVE) && 238 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)) 239 continue; 240 241 if (hard_iface->net_dev == net_dev) 242 continue; 243 244 if (!batadv_compare_eth(hard_iface->net_dev->dev_addr, 245 net_dev->dev_addr)) 246 continue; 247 248 pr_warn("The newly added mac address (%pM) already exists on: %s\n", 249 net_dev->dev_addr, hard_iface->net_dev->name); 250 pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); 251 } 252 rcu_read_unlock(); 253 } 254 255 /** 256 * batadv_hardif_recalc_extra_skbroom() - Recalculate skbuff extra head/tailroom 257 * @soft_iface: netdev struct of the mesh interface 258 */ 259 static void batadv_hardif_recalc_extra_skbroom(struct net_device *soft_iface) 260 { 261 const struct batadv_hard_iface *hard_iface; 262 unsigned short lower_header_len = ETH_HLEN; 263 unsigned short lower_headroom = 0; 264 unsigned short lower_tailroom = 0; 265 unsigned short needed_headroom; 266 267 rcu_read_lock(); 268 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 269 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE) 270 continue; 271 272 if (hard_iface->soft_iface != soft_iface) 273 continue; 274 275 lower_header_len = max_t(unsigned short, lower_header_len, 276 hard_iface->net_dev->hard_header_len); 277 278 lower_headroom = max_t(unsigned short, lower_headroom, 279 hard_iface->net_dev->needed_headroom); 280 281 lower_tailroom = max_t(unsigned short, lower_tailroom, 282 hard_iface->net_dev->needed_tailroom); 283 } 284 rcu_read_unlock(); 285 286 needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN); 287 needed_headroom += batadv_max_header_len(); 288 289 soft_iface->needed_headroom = needed_headroom; 290 soft_iface->needed_tailroom = lower_tailroom; 291 } 292 293 int batadv_hardif_min_mtu(struct net_device *soft_iface) 294 { 295 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 296 const struct batadv_hard_iface *hard_iface; 297 int min_mtu = INT_MAX; 298 299 rcu_read_lock(); 300 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 301 if ((hard_iface->if_status != BATADV_IF_ACTIVE) && 302 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)) 303 continue; 304 305 if (hard_iface->soft_iface != soft_iface) 306 continue; 307 308 min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu); 309 } 310 rcu_read_unlock(); 311 312 if (atomic_read(&bat_priv->fragmentation) == 0) 313 goto out; 314 315 /* with fragmentation enabled the maximum size of internally generated 316 * packets such as translation table exchanges or tvlv containers, etc 317 * has to be calculated 318 */ 319 min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE); 320 min_mtu -= sizeof(struct batadv_frag_packet); 321 min_mtu *= BATADV_FRAG_MAX_FRAGMENTS; 322 323 out: 324 /* report to the other components the maximum amount of bytes that 325 * batman-adv can send over the wire (without considering the payload 326 * overhead). For example, this value is used by TT to compute the 327 * maximum local table table size 328 */ 329 atomic_set(&bat_priv->packet_size_max, min_mtu); 330 331 /* the real soft-interface MTU is computed by removing the payload 332 * overhead from the maximum amount of bytes that was just computed. 333 * 334 * However batman-adv does not support MTUs bigger than ETH_DATA_LEN 335 */ 336 return min_t(int, min_mtu - batadv_max_header_len(), ETH_DATA_LEN); 337 } 338 339 /* adjusts the MTU if a new interface with a smaller MTU appeared. */ 340 void batadv_update_min_mtu(struct net_device *soft_iface) 341 { 342 soft_iface->mtu = batadv_hardif_min_mtu(soft_iface); 343 344 /* Check if the local translate table should be cleaned up to match a 345 * new (and smaller) MTU. 346 */ 347 batadv_tt_local_resize_to_mtu(soft_iface); 348 } 349 350 static void 351 batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface) 352 { 353 struct batadv_priv *bat_priv; 354 struct batadv_hard_iface *primary_if = NULL; 355 356 if (hard_iface->if_status != BATADV_IF_INACTIVE) 357 goto out; 358 359 bat_priv = netdev_priv(hard_iface->soft_iface); 360 361 bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); 362 hard_iface->if_status = BATADV_IF_TO_BE_ACTIVATED; 363 364 /* the first active interface becomes our primary interface or 365 * the next active interface after the old primary interface was removed 366 */ 367 primary_if = batadv_primary_if_get_selected(bat_priv); 368 if (!primary_if) 369 batadv_primary_if_select(bat_priv, hard_iface); 370 371 batadv_info(hard_iface->soft_iface, "Interface activated: %s\n", 372 hard_iface->net_dev->name); 373 374 batadv_update_min_mtu(hard_iface->soft_iface); 375 376 out: 377 if (primary_if) 378 batadv_hardif_free_ref(primary_if); 379 } 380 381 static void 382 batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface) 383 { 384 if ((hard_iface->if_status != BATADV_IF_ACTIVE) && 385 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)) 386 return; 387 388 hard_iface->if_status = BATADV_IF_INACTIVE; 389 390 batadv_info(hard_iface->soft_iface, "Interface deactivated: %s\n", 391 hard_iface->net_dev->name); 392 393 batadv_update_min_mtu(hard_iface->soft_iface); 394 } 395 396 /** 397 * batadv_master_del_slave - remove hard_iface from the current master interface 398 * @slave: the interface enslaved in another master 399 * @master: the master from which slave has to be removed 400 * 401 * Invoke ndo_del_slave on master passing slave as argument. In this way slave 402 * is free'd and master can correctly change its internal state. 403 * Return 0 on success, a negative value representing the error otherwise 404 */ 405 static int batadv_master_del_slave(struct batadv_hard_iface *slave, 406 struct net_device *master) 407 { 408 int ret; 409 410 if (!master) 411 return 0; 412 413 ret = -EBUSY; 414 if (master->netdev_ops->ndo_del_slave) 415 ret = master->netdev_ops->ndo_del_slave(master, slave->net_dev); 416 417 return ret; 418 } 419 420 int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, 421 const char *iface_name) 422 { 423 struct batadv_priv *bat_priv; 424 struct net_device *soft_iface, *master; 425 __be16 ethertype = htons(ETH_P_BATMAN); 426 int max_header_len = batadv_max_header_len(); 427 int ret; 428 429 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) 430 goto out; 431 432 if (!atomic_inc_not_zero(&hard_iface->refcount)) 433 goto out; 434 435 soft_iface = dev_get_by_name(&init_net, iface_name); 436 437 if (!soft_iface) { 438 soft_iface = batadv_softif_create(iface_name); 439 440 if (!soft_iface) { 441 ret = -ENOMEM; 442 goto err; 443 } 444 445 /* dev_get_by_name() increases the reference counter for us */ 446 dev_hold(soft_iface); 447 } 448 449 if (!batadv_softif_is_valid(soft_iface)) { 450 pr_err("Can't create batman mesh interface %s: already exists as regular interface\n", 451 soft_iface->name); 452 ret = -EINVAL; 453 goto err_dev; 454 } 455 456 /* check if the interface is enslaved in another virtual one and 457 * in that case unlink it first 458 */ 459 master = netdev_master_upper_dev_get(hard_iface->net_dev); 460 ret = batadv_master_del_slave(hard_iface, master); 461 if (ret) 462 goto err_dev; 463 464 hard_iface->soft_iface = soft_iface; 465 bat_priv = netdev_priv(hard_iface->soft_iface); 466 467 ret = netdev_master_upper_dev_link(hard_iface->net_dev, soft_iface); 468 if (ret) 469 goto err_dev; 470 471 ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface); 472 if (ret < 0) 473 goto err_upper; 474 475 hard_iface->if_num = bat_priv->num_ifaces; 476 bat_priv->num_ifaces++; 477 hard_iface->if_status = BATADV_IF_INACTIVE; 478 ret = batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); 479 if (ret < 0) { 480 bat_priv->bat_algo_ops->bat_iface_disable(hard_iface); 481 bat_priv->num_ifaces--; 482 hard_iface->if_status = BATADV_IF_NOT_IN_USE; 483 goto err_upper; 484 } 485 486 hard_iface->batman_adv_ptype.type = ethertype; 487 hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv; 488 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; 489 dev_add_pack(&hard_iface->batman_adv_ptype); 490 491 batadv_info(hard_iface->soft_iface, "Adding interface: %s\n", 492 hard_iface->net_dev->name); 493 494 if (atomic_read(&bat_priv->fragmentation) && 495 hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len) 496 batadv_info(hard_iface->soft_iface, 497 "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %i would solve the problem.\n", 498 hard_iface->net_dev->name, hard_iface->net_dev->mtu, 499 ETH_DATA_LEN + max_header_len); 500 501 if (!atomic_read(&bat_priv->fragmentation) && 502 hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len) 503 batadv_info(hard_iface->soft_iface, 504 "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %i.\n", 505 hard_iface->net_dev->name, hard_iface->net_dev->mtu, 506 ETH_DATA_LEN + max_header_len); 507 508 if (batadv_hardif_is_iface_up(hard_iface)) 509 batadv_hardif_activate_interface(hard_iface); 510 else 511 batadv_err(hard_iface->soft_iface, 512 "Not using interface %s (retrying later): interface not active\n", 513 hard_iface->net_dev->name); 514 515 batadv_hardif_recalc_extra_skbroom(soft_iface); 516 517 /* begin scheduling originator messages on that interface */ 518 batadv_schedule_bat_ogm(hard_iface); 519 520 out: 521 return 0; 522 523 err_upper: 524 netdev_upper_dev_unlink(hard_iface->net_dev, soft_iface); 525 err_dev: 526 hard_iface->soft_iface = NULL; 527 dev_put(soft_iface); 528 err: 529 batadv_hardif_free_ref(hard_iface); 530 return ret; 531 } 532 533 void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, 534 enum batadv_hard_if_cleanup autodel) 535 { 536 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 537 struct batadv_hard_iface *primary_if = NULL; 538 539 if (hard_iface->if_status == BATADV_IF_ACTIVE) 540 batadv_hardif_deactivate_interface(hard_iface); 541 542 if (hard_iface->if_status != BATADV_IF_INACTIVE) 543 goto out; 544 545 batadv_info(hard_iface->soft_iface, "Removing interface: %s\n", 546 hard_iface->net_dev->name); 547 dev_remove_pack(&hard_iface->batman_adv_ptype); 548 549 bat_priv->num_ifaces--; 550 batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces); 551 552 primary_if = batadv_primary_if_get_selected(bat_priv); 553 if (hard_iface == primary_if) { 554 struct batadv_hard_iface *new_if; 555 556 new_if = batadv_hardif_get_active(hard_iface->soft_iface); 557 batadv_primary_if_select(bat_priv, new_if); 558 559 if (new_if) 560 batadv_hardif_free_ref(new_if); 561 } 562 563 bat_priv->bat_algo_ops->bat_iface_disable(hard_iface); 564 hard_iface->if_status = BATADV_IF_NOT_IN_USE; 565 566 /* delete all references to this hard_iface */ 567 batadv_purge_orig_ref(bat_priv); 568 batadv_purge_outstanding_packets(bat_priv, hard_iface); 569 dev_put(hard_iface->soft_iface); 570 571 netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface); 572 batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface); 573 574 /* nobody uses this interface anymore */ 575 if (!bat_priv->num_ifaces) { 576 batadv_gw_check_client_stop(bat_priv); 577 578 if (autodel == BATADV_IF_CLEANUP_AUTO) 579 batadv_softif_destroy_sysfs(hard_iface->soft_iface); 580 } 581 582 hard_iface->soft_iface = NULL; 583 batadv_hardif_free_ref(hard_iface); 584 585 out: 586 if (primary_if) 587 batadv_hardif_free_ref(primary_if); 588 } 589 590 /** 591 * batadv_hardif_remove_interface_finish - cleans up the remains of a hardif 592 * @work: work queue item 593 * 594 * Free the parts of the hard interface which can not be removed under 595 * rtnl lock (to prevent deadlock situations). 596 */ 597 static void batadv_hardif_remove_interface_finish(struct work_struct *work) 598 { 599 struct batadv_hard_iface *hard_iface; 600 601 hard_iface = container_of(work, struct batadv_hard_iface, 602 cleanup_work); 603 604 batadv_debugfs_del_hardif(hard_iface); 605 batadv_sysfs_del_hardif(&hard_iface->hardif_obj); 606 batadv_hardif_free_ref(hard_iface); 607 } 608 609 static struct batadv_hard_iface * 610 batadv_hardif_add_interface(struct net_device *net_dev) 611 { 612 struct batadv_hard_iface *hard_iface; 613 int ret; 614 615 ASSERT_RTNL(); 616 617 ret = batadv_is_valid_iface(net_dev); 618 if (ret != 1) 619 goto out; 620 621 dev_hold(net_dev); 622 623 hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC); 624 if (!hard_iface) 625 goto release_dev; 626 627 ret = batadv_sysfs_add_hardif(&hard_iface->hardif_obj, net_dev); 628 if (ret) 629 goto free_if; 630 631 hard_iface->if_num = -1; 632 hard_iface->net_dev = net_dev; 633 hard_iface->soft_iface = NULL; 634 hard_iface->if_status = BATADV_IF_NOT_IN_USE; 635 636 ret = batadv_debugfs_add_hardif(hard_iface); 637 if (ret) 638 goto free_sysfs; 639 640 INIT_LIST_HEAD(&hard_iface->list); 641 INIT_WORK(&hard_iface->cleanup_work, 642 batadv_hardif_remove_interface_finish); 643 644 hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT; 645 if (batadv_is_wifi_netdev(net_dev)) 646 hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS; 647 648 /* extra reference for return */ 649 atomic_set(&hard_iface->refcount, 2); 650 651 batadv_check_known_mac_addr(hard_iface->net_dev); 652 list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); 653 654 return hard_iface; 655 656 free_sysfs: 657 batadv_sysfs_del_hardif(&hard_iface->hardif_obj); 658 free_if: 659 kfree(hard_iface); 660 release_dev: 661 dev_put(net_dev); 662 out: 663 return NULL; 664 } 665 666 static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface) 667 { 668 ASSERT_RTNL(); 669 670 /* first deactivate interface */ 671 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) 672 batadv_hardif_disable_interface(hard_iface, 673 BATADV_IF_CLEANUP_AUTO); 674 675 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) 676 return; 677 678 hard_iface->if_status = BATADV_IF_TO_BE_REMOVED; 679 queue_work(batadv_event_workqueue, &hard_iface->cleanup_work); 680 } 681 682 void batadv_hardif_remove_interfaces(void) 683 { 684 struct batadv_hard_iface *hard_iface, *hard_iface_tmp; 685 686 rtnl_lock(); 687 list_for_each_entry_safe(hard_iface, hard_iface_tmp, 688 &batadv_hardif_list, list) { 689 list_del_rcu(&hard_iface->list); 690 batadv_hardif_remove_interface(hard_iface); 691 } 692 rtnl_unlock(); 693 } 694 695 static int batadv_hard_if_event(struct notifier_block *this, 696 unsigned long event, void *ptr) 697 { 698 struct net_device *net_dev = netdev_notifier_info_to_dev(ptr); 699 struct batadv_hard_iface *hard_iface; 700 struct batadv_hard_iface *primary_if = NULL; 701 struct batadv_priv *bat_priv; 702 703 if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) { 704 batadv_sysfs_add_meshif(net_dev); 705 bat_priv = netdev_priv(net_dev); 706 batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS); 707 return NOTIFY_DONE; 708 } 709 710 hard_iface = batadv_hardif_get_by_netdev(net_dev); 711 if (!hard_iface && event == NETDEV_REGISTER) 712 hard_iface = batadv_hardif_add_interface(net_dev); 713 714 if (!hard_iface) 715 goto out; 716 717 switch (event) { 718 case NETDEV_UP: 719 batadv_hardif_activate_interface(hard_iface); 720 break; 721 case NETDEV_GOING_DOWN: 722 case NETDEV_DOWN: 723 batadv_hardif_deactivate_interface(hard_iface); 724 break; 725 case NETDEV_UNREGISTER: 726 list_del_rcu(&hard_iface->list); 727 728 batadv_hardif_remove_interface(hard_iface); 729 break; 730 case NETDEV_CHANGEMTU: 731 if (hard_iface->soft_iface) 732 batadv_update_min_mtu(hard_iface->soft_iface); 733 break; 734 case NETDEV_CHANGEADDR: 735 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE) 736 goto hardif_put; 737 738 batadv_check_known_mac_addr(hard_iface->net_dev); 739 740 bat_priv = netdev_priv(hard_iface->soft_iface); 741 bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); 742 743 primary_if = batadv_primary_if_get_selected(bat_priv); 744 if (!primary_if) 745 goto hardif_put; 746 747 if (hard_iface == primary_if) 748 batadv_primary_if_update_addr(bat_priv, NULL); 749 break; 750 default: 751 break; 752 } 753 754 hardif_put: 755 batadv_hardif_free_ref(hard_iface); 756 out: 757 if (primary_if) 758 batadv_hardif_free_ref(primary_if); 759 return NOTIFY_DONE; 760 } 761 762 struct notifier_block batadv_hard_if_notifier = { 763 .notifier_call = batadv_hard_if_event, 764 }; 765