1 /* Copyright (C) 2007-2012 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, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * 02110-1301, USA 18 */ 19 20 #include "main.h" 21 #include "hard-interface.h" 22 #include "soft-interface.h" 23 #include "send.h" 24 #include "translation-table.h" 25 #include "routing.h" 26 #include "sysfs.h" 27 #include "originator.h" 28 #include "hash.h" 29 #include "bridge_loop_avoidance.h" 30 31 #include <linux/if_arp.h> 32 33 void batadv_hardif_free_rcu(struct rcu_head *rcu) 34 { 35 struct batadv_hard_iface *hard_iface; 36 37 hard_iface = container_of(rcu, struct batadv_hard_iface, rcu); 38 dev_put(hard_iface->net_dev); 39 kfree(hard_iface); 40 } 41 42 struct batadv_hard_iface * 43 batadv_hardif_get_by_netdev(const struct net_device *net_dev) 44 { 45 struct batadv_hard_iface *hard_iface; 46 47 rcu_read_lock(); 48 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 49 if (hard_iface->net_dev == net_dev && 50 atomic_inc_not_zero(&hard_iface->refcount)) 51 goto out; 52 } 53 54 hard_iface = NULL; 55 56 out: 57 rcu_read_unlock(); 58 return hard_iface; 59 } 60 61 static int batadv_is_valid_iface(const struct net_device *net_dev) 62 { 63 if (net_dev->flags & IFF_LOOPBACK) 64 return 0; 65 66 if (net_dev->type != ARPHRD_ETHER) 67 return 0; 68 69 if (net_dev->addr_len != ETH_ALEN) 70 return 0; 71 72 /* no batman over batman */ 73 if (batadv_softif_is_valid(net_dev)) 74 return 0; 75 76 return 1; 77 } 78 79 static struct batadv_hard_iface * 80 batadv_hardif_get_active(const struct net_device *soft_iface) 81 { 82 struct batadv_hard_iface *hard_iface; 83 84 rcu_read_lock(); 85 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 86 if (hard_iface->soft_iface != soft_iface) 87 continue; 88 89 if (hard_iface->if_status == BATADV_IF_ACTIVE && 90 atomic_inc_not_zero(&hard_iface->refcount)) 91 goto out; 92 } 93 94 hard_iface = NULL; 95 96 out: 97 rcu_read_unlock(); 98 return hard_iface; 99 } 100 101 static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv, 102 struct batadv_hard_iface *oldif) 103 { 104 struct batadv_vis_packet *vis_packet; 105 struct batadv_hard_iface *primary_if; 106 107 primary_if = batadv_primary_if_get_selected(bat_priv); 108 if (!primary_if) 109 goto out; 110 111 vis_packet = (struct batadv_vis_packet *) 112 bat_priv->my_vis_info->skb_packet->data; 113 memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN); 114 memcpy(vis_packet->sender_orig, 115 primary_if->net_dev->dev_addr, ETH_ALEN); 116 117 batadv_bla_update_orig_address(bat_priv, primary_if, oldif); 118 out: 119 if (primary_if) 120 batadv_hardif_free_ref(primary_if); 121 } 122 123 static void batadv_primary_if_select(struct batadv_priv *bat_priv, 124 struct batadv_hard_iface *new_hard_iface) 125 { 126 struct batadv_hard_iface *curr_hard_iface; 127 128 ASSERT_RTNL(); 129 130 if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount)) 131 new_hard_iface = NULL; 132 133 curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1); 134 rcu_assign_pointer(bat_priv->primary_if, new_hard_iface); 135 136 if (!new_hard_iface) 137 goto out; 138 139 bat_priv->bat_algo_ops->bat_primary_iface_set(new_hard_iface); 140 batadv_primary_if_update_addr(bat_priv, curr_hard_iface); 141 142 out: 143 if (curr_hard_iface) 144 batadv_hardif_free_ref(curr_hard_iface); 145 } 146 147 static bool 148 batadv_hardif_is_iface_up(const struct batadv_hard_iface *hard_iface) 149 { 150 if (hard_iface->net_dev->flags & IFF_UP) 151 return true; 152 153 return false; 154 } 155 156 static void batadv_check_known_mac_addr(const struct net_device *net_dev) 157 { 158 const struct batadv_hard_iface *hard_iface; 159 160 rcu_read_lock(); 161 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 162 if ((hard_iface->if_status != BATADV_IF_ACTIVE) && 163 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)) 164 continue; 165 166 if (hard_iface->net_dev == net_dev) 167 continue; 168 169 if (!batadv_compare_eth(hard_iface->net_dev->dev_addr, 170 net_dev->dev_addr)) 171 continue; 172 173 pr_warn("The newly added mac address (%pM) already exists on: %s\n", 174 net_dev->dev_addr, hard_iface->net_dev->name); 175 pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); 176 } 177 rcu_read_unlock(); 178 } 179 180 int batadv_hardif_min_mtu(struct net_device *soft_iface) 181 { 182 const struct batadv_priv *bat_priv = netdev_priv(soft_iface); 183 const struct batadv_hard_iface *hard_iface; 184 /* allow big frames if all devices are capable to do so 185 * (have MTU > 1500 + BAT_HEADER_LEN) 186 */ 187 int min_mtu = ETH_DATA_LEN; 188 189 if (atomic_read(&bat_priv->fragmentation)) 190 goto out; 191 192 rcu_read_lock(); 193 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 194 if ((hard_iface->if_status != BATADV_IF_ACTIVE) && 195 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)) 196 continue; 197 198 if (hard_iface->soft_iface != soft_iface) 199 continue; 200 201 min_mtu = min_t(int, 202 hard_iface->net_dev->mtu - BATADV_HEADER_LEN, 203 min_mtu); 204 } 205 rcu_read_unlock(); 206 out: 207 return min_mtu; 208 } 209 210 /* adjusts the MTU if a new interface with a smaller MTU appeared. */ 211 void batadv_update_min_mtu(struct net_device *soft_iface) 212 { 213 int min_mtu; 214 215 min_mtu = batadv_hardif_min_mtu(soft_iface); 216 if (soft_iface->mtu != min_mtu) 217 soft_iface->mtu = min_mtu; 218 } 219 220 static void 221 batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface) 222 { 223 struct batadv_priv *bat_priv; 224 struct batadv_hard_iface *primary_if = NULL; 225 226 if (hard_iface->if_status != BATADV_IF_INACTIVE) 227 goto out; 228 229 bat_priv = netdev_priv(hard_iface->soft_iface); 230 231 bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); 232 hard_iface->if_status = BATADV_IF_TO_BE_ACTIVATED; 233 234 /* the first active interface becomes our primary interface or 235 * the next active interface after the old primary interface was removed 236 */ 237 primary_if = batadv_primary_if_get_selected(bat_priv); 238 if (!primary_if) 239 batadv_primary_if_select(bat_priv, hard_iface); 240 241 batadv_info(hard_iface->soft_iface, "Interface activated: %s\n", 242 hard_iface->net_dev->name); 243 244 batadv_update_min_mtu(hard_iface->soft_iface); 245 246 out: 247 if (primary_if) 248 batadv_hardif_free_ref(primary_if); 249 } 250 251 static void 252 batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface) 253 { 254 if ((hard_iface->if_status != BATADV_IF_ACTIVE) && 255 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)) 256 return; 257 258 hard_iface->if_status = BATADV_IF_INACTIVE; 259 260 batadv_info(hard_iface->soft_iface, "Interface deactivated: %s\n", 261 hard_iface->net_dev->name); 262 263 batadv_update_min_mtu(hard_iface->soft_iface); 264 } 265 266 int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, 267 const char *iface_name) 268 { 269 struct batadv_priv *bat_priv; 270 struct net_device *soft_iface; 271 __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); 272 int ret; 273 274 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) 275 goto out; 276 277 if (!atomic_inc_not_zero(&hard_iface->refcount)) 278 goto out; 279 280 /* hard-interface is part of a bridge */ 281 if (hard_iface->net_dev->priv_flags & IFF_BRIDGE_PORT) 282 pr_err("You are about to enable batman-adv on '%s' which already is part of a bridge. Unless you know exactly what you are doing this is probably wrong and won't work the way you think it would.\n", 283 hard_iface->net_dev->name); 284 285 soft_iface = dev_get_by_name(&init_net, iface_name); 286 287 if (!soft_iface) { 288 soft_iface = batadv_softif_create(iface_name); 289 290 if (!soft_iface) { 291 ret = -ENOMEM; 292 goto err; 293 } 294 295 /* dev_get_by_name() increases the reference counter for us */ 296 dev_hold(soft_iface); 297 } 298 299 if (!batadv_softif_is_valid(soft_iface)) { 300 pr_err("Can't create batman mesh interface %s: already exists as regular interface\n", 301 soft_iface->name); 302 ret = -EINVAL; 303 goto err_dev; 304 } 305 306 hard_iface->soft_iface = soft_iface; 307 bat_priv = netdev_priv(hard_iface->soft_iface); 308 309 ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface); 310 if (ret < 0) 311 goto err_dev; 312 313 hard_iface->if_num = bat_priv->num_ifaces; 314 bat_priv->num_ifaces++; 315 hard_iface->if_status = BATADV_IF_INACTIVE; 316 batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); 317 318 hard_iface->batman_adv_ptype.type = ethertype; 319 hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv; 320 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; 321 dev_add_pack(&hard_iface->batman_adv_ptype); 322 323 atomic_set(&hard_iface->frag_seqno, 1); 324 batadv_info(hard_iface->soft_iface, "Adding interface: %s\n", 325 hard_iface->net_dev->name); 326 327 if (atomic_read(&bat_priv->fragmentation) && 328 hard_iface->net_dev->mtu < ETH_DATA_LEN + BATADV_HEADER_LEN) 329 batadv_info(hard_iface->soft_iface, 330 "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 %zi would solve the problem.\n", 331 hard_iface->net_dev->name, hard_iface->net_dev->mtu, 332 ETH_DATA_LEN + BATADV_HEADER_LEN); 333 334 if (!atomic_read(&bat_priv->fragmentation) && 335 hard_iface->net_dev->mtu < ETH_DATA_LEN + BATADV_HEADER_LEN) 336 batadv_info(hard_iface->soft_iface, 337 "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 %zi.\n", 338 hard_iface->net_dev->name, hard_iface->net_dev->mtu, 339 ETH_DATA_LEN + BATADV_HEADER_LEN); 340 341 if (batadv_hardif_is_iface_up(hard_iface)) 342 batadv_hardif_activate_interface(hard_iface); 343 else 344 batadv_err(hard_iface->soft_iface, 345 "Not using interface %s (retrying later): interface not active\n", 346 hard_iface->net_dev->name); 347 348 /* begin scheduling originator messages on that interface */ 349 batadv_schedule_bat_ogm(hard_iface); 350 351 out: 352 return 0; 353 354 err_dev: 355 dev_put(soft_iface); 356 err: 357 batadv_hardif_free_ref(hard_iface); 358 return ret; 359 } 360 361 void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface) 362 { 363 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 364 struct batadv_hard_iface *primary_if = NULL; 365 366 if (hard_iface->if_status == BATADV_IF_ACTIVE) 367 batadv_hardif_deactivate_interface(hard_iface); 368 369 if (hard_iface->if_status != BATADV_IF_INACTIVE) 370 goto out; 371 372 batadv_info(hard_iface->soft_iface, "Removing interface: %s\n", 373 hard_iface->net_dev->name); 374 dev_remove_pack(&hard_iface->batman_adv_ptype); 375 376 bat_priv->num_ifaces--; 377 batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces); 378 379 primary_if = batadv_primary_if_get_selected(bat_priv); 380 if (hard_iface == primary_if) { 381 struct batadv_hard_iface *new_if; 382 383 new_if = batadv_hardif_get_active(hard_iface->soft_iface); 384 batadv_primary_if_select(bat_priv, new_if); 385 386 if (new_if) 387 batadv_hardif_free_ref(new_if); 388 } 389 390 bat_priv->bat_algo_ops->bat_iface_disable(hard_iface); 391 hard_iface->if_status = BATADV_IF_NOT_IN_USE; 392 393 /* delete all references to this hard_iface */ 394 batadv_purge_orig_ref(bat_priv); 395 batadv_purge_outstanding_packets(bat_priv, hard_iface); 396 dev_put(hard_iface->soft_iface); 397 398 /* nobody uses this interface anymore */ 399 if (!bat_priv->num_ifaces) 400 batadv_softif_destroy(hard_iface->soft_iface); 401 402 hard_iface->soft_iface = NULL; 403 batadv_hardif_free_ref(hard_iface); 404 405 out: 406 if (primary_if) 407 batadv_hardif_free_ref(primary_if); 408 } 409 410 static struct batadv_hard_iface * 411 batadv_hardif_add_interface(struct net_device *net_dev) 412 { 413 struct batadv_hard_iface *hard_iface; 414 int ret; 415 416 ASSERT_RTNL(); 417 418 ret = batadv_is_valid_iface(net_dev); 419 if (ret != 1) 420 goto out; 421 422 dev_hold(net_dev); 423 424 hard_iface = kmalloc(sizeof(*hard_iface), GFP_ATOMIC); 425 if (!hard_iface) 426 goto release_dev; 427 428 ret = batadv_sysfs_add_hardif(&hard_iface->hardif_obj, net_dev); 429 if (ret) 430 goto free_if; 431 432 hard_iface->if_num = -1; 433 hard_iface->net_dev = net_dev; 434 hard_iface->soft_iface = NULL; 435 hard_iface->if_status = BATADV_IF_NOT_IN_USE; 436 INIT_LIST_HEAD(&hard_iface->list); 437 /* extra reference for return */ 438 atomic_set(&hard_iface->refcount, 2); 439 440 batadv_check_known_mac_addr(hard_iface->net_dev); 441 list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); 442 443 /* This can't be called via a bat_priv callback because 444 * we have no bat_priv yet. 445 */ 446 atomic_set(&hard_iface->seqno, 1); 447 hard_iface->packet_buff = NULL; 448 449 return hard_iface; 450 451 free_if: 452 kfree(hard_iface); 453 release_dev: 454 dev_put(net_dev); 455 out: 456 return NULL; 457 } 458 459 static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface) 460 { 461 ASSERT_RTNL(); 462 463 /* first deactivate interface */ 464 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) 465 batadv_hardif_disable_interface(hard_iface); 466 467 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) 468 return; 469 470 hard_iface->if_status = BATADV_IF_TO_BE_REMOVED; 471 batadv_sysfs_del_hardif(&hard_iface->hardif_obj); 472 batadv_hardif_free_ref(hard_iface); 473 } 474 475 void batadv_hardif_remove_interfaces(void) 476 { 477 struct batadv_hard_iface *hard_iface, *hard_iface_tmp; 478 479 rtnl_lock(); 480 list_for_each_entry_safe(hard_iface, hard_iface_tmp, 481 &batadv_hardif_list, list) { 482 list_del_rcu(&hard_iface->list); 483 batadv_hardif_remove_interface(hard_iface); 484 } 485 rtnl_unlock(); 486 } 487 488 static int batadv_hard_if_event(struct notifier_block *this, 489 unsigned long event, void *ptr) 490 { 491 struct net_device *net_dev = ptr; 492 struct batadv_hard_iface *hard_iface; 493 struct batadv_hard_iface *primary_if = NULL; 494 struct batadv_priv *bat_priv; 495 496 hard_iface = batadv_hardif_get_by_netdev(net_dev); 497 if (!hard_iface && event == NETDEV_REGISTER) 498 hard_iface = batadv_hardif_add_interface(net_dev); 499 500 if (!hard_iface) 501 goto out; 502 503 switch (event) { 504 case NETDEV_UP: 505 batadv_hardif_activate_interface(hard_iface); 506 break; 507 case NETDEV_GOING_DOWN: 508 case NETDEV_DOWN: 509 batadv_hardif_deactivate_interface(hard_iface); 510 break; 511 case NETDEV_UNREGISTER: 512 list_del_rcu(&hard_iface->list); 513 514 batadv_hardif_remove_interface(hard_iface); 515 break; 516 case NETDEV_CHANGEMTU: 517 if (hard_iface->soft_iface) 518 batadv_update_min_mtu(hard_iface->soft_iface); 519 break; 520 case NETDEV_CHANGEADDR: 521 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE) 522 goto hardif_put; 523 524 batadv_check_known_mac_addr(hard_iface->net_dev); 525 526 bat_priv = netdev_priv(hard_iface->soft_iface); 527 bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); 528 529 primary_if = batadv_primary_if_get_selected(bat_priv); 530 if (!primary_if) 531 goto hardif_put; 532 533 if (hard_iface == primary_if) 534 batadv_primary_if_update_addr(bat_priv, NULL); 535 break; 536 default: 537 break; 538 } 539 540 hardif_put: 541 batadv_hardif_free_ref(hard_iface); 542 out: 543 if (primary_if) 544 batadv_hardif_free_ref(primary_if); 545 return NOTIFY_DONE; 546 } 547 548 /* This function returns true if the interface represented by ifindex is a 549 * 802.11 wireless device 550 */ 551 bool batadv_is_wifi_iface(int ifindex) 552 { 553 struct net_device *net_device = NULL; 554 bool ret = false; 555 556 if (ifindex == BATADV_NULL_IFINDEX) 557 goto out; 558 559 net_device = dev_get_by_index(&init_net, ifindex); 560 if (!net_device) 561 goto out; 562 563 #ifdef CONFIG_WIRELESS_EXT 564 /* pre-cfg80211 drivers have to implement WEXT, so it is possible to 565 * check for wireless_handlers != NULL 566 */ 567 if (net_device->wireless_handlers) 568 ret = true; 569 else 570 #endif 571 /* cfg80211 drivers have to set ieee80211_ptr */ 572 if (net_device->ieee80211_ptr) 573 ret = true; 574 out: 575 if (net_device) 576 dev_put(net_device); 577 return ret; 578 } 579 580 struct notifier_block batadv_hard_if_notifier = { 581 .notifier_call = batadv_hard_if_event, 582 }; 583