aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/soft-interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/soft-interface.c')
-rw-r--r--net/batman-adv/soft-interface.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 6b548fde8e04..2711e870f557 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: 1/* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors:
2 * 2 *
3 * Marek Lindner, Simon Wunderlich 3 * Marek Lindner, Simon Wunderlich
4 * 4 *
@@ -124,7 +124,6 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
124 batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX); 124 batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX);
125 } 125 }
126 126
127 dev->addr_assign_type &= ~NET_ADDR_RANDOM;
128 return 0; 127 return 0;
129} 128}
130 129
@@ -181,7 +180,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
181 goto dropped; 180 goto dropped;
182 181
183 /* Register the client MAC in the transtable */ 182 /* Register the client MAC in the transtable */
184 batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); 183 if (!is_multicast_ether_addr(ethhdr->h_source))
184 batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
185 185
186 /* don't accept stp packets. STP does not help in meshes. 186 /* don't accept stp packets. STP does not help in meshes.
187 * better use the bridge loop avoidance ... 187 * better use the bridge loop avoidance ...
@@ -449,6 +449,30 @@ static void batadv_interface_setup(struct net_device *dev)
449 memset(priv, 0, sizeof(*priv)); 449 memset(priv, 0, sizeof(*priv));
450} 450}
451 451
452/**
453 * batadv_softif_destroy_finish - cleans up the remains of a softif
454 * @work: work queue item
455 *
456 * Free the parts of the soft interface which can not be removed under
457 * rtnl lock (to prevent deadlock situations).
458 */
459static void batadv_softif_destroy_finish(struct work_struct *work)
460{
461 struct batadv_priv *bat_priv;
462 struct net_device *soft_iface;
463
464 bat_priv = container_of(work, struct batadv_priv,
465 cleanup_work);
466 soft_iface = bat_priv->soft_iface;
467
468 batadv_debugfs_del_meshif(soft_iface);
469 batadv_sysfs_del_meshif(soft_iface);
470
471 rtnl_lock();
472 unregister_netdevice(soft_iface);
473 rtnl_unlock();
474}
475
452struct net_device *batadv_softif_create(const char *name) 476struct net_device *batadv_softif_create(const char *name)
453{ 477{
454 struct net_device *soft_iface; 478 struct net_device *soft_iface;
@@ -463,6 +487,8 @@ struct net_device *batadv_softif_create(const char *name)
463 goto out; 487 goto out;
464 488
465 bat_priv = netdev_priv(soft_iface); 489 bat_priv = netdev_priv(soft_iface);
490 bat_priv->soft_iface = soft_iface;
491 INIT_WORK(&bat_priv->cleanup_work, batadv_softif_destroy_finish);
466 492
467 /* batadv_interface_stats() needs to be available as soon as 493 /* batadv_interface_stats() needs to be available as soon as
468 * register_netdevice() has been called 494 * register_netdevice() has been called
@@ -480,7 +506,9 @@ struct net_device *batadv_softif_create(const char *name)
480 506
481 atomic_set(&bat_priv->aggregated_ogms, 1); 507 atomic_set(&bat_priv->aggregated_ogms, 1);
482 atomic_set(&bat_priv->bonding, 0); 508 atomic_set(&bat_priv->bonding, 0);
509#ifdef CONFIG_BATMAN_ADV_BLA
483 atomic_set(&bat_priv->bridge_loop_avoidance, 0); 510 atomic_set(&bat_priv->bridge_loop_avoidance, 0);
511#endif
484#ifdef CONFIG_BATMAN_ADV_DAT 512#ifdef CONFIG_BATMAN_ADV_DAT
485 atomic_set(&bat_priv->distributed_arp_table, 1); 513 atomic_set(&bat_priv->distributed_arp_table, 1);
486#endif 514#endif
@@ -491,7 +519,9 @@ struct net_device *batadv_softif_create(const char *name)
491 atomic_set(&bat_priv->gw_bandwidth, 41); 519 atomic_set(&bat_priv->gw_bandwidth, 41);
492 atomic_set(&bat_priv->orig_interval, 1000); 520 atomic_set(&bat_priv->orig_interval, 1000);
493 atomic_set(&bat_priv->hop_penalty, 30); 521 atomic_set(&bat_priv->hop_penalty, 30);
522#ifdef CONFIG_BATMAN_ADV_DEBUG
494 atomic_set(&bat_priv->log_level, 0); 523 atomic_set(&bat_priv->log_level, 0);
524#endif
495 atomic_set(&bat_priv->fragmentation, 1); 525 atomic_set(&bat_priv->fragmentation, 1);
496 atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); 526 atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
497 atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); 527 atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
@@ -547,10 +577,10 @@ out:
547 577
548void batadv_softif_destroy(struct net_device *soft_iface) 578void batadv_softif_destroy(struct net_device *soft_iface)
549{ 579{
550 batadv_debugfs_del_meshif(soft_iface); 580 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
551 batadv_sysfs_del_meshif(soft_iface); 581
552 batadv_mesh_free(soft_iface); 582 batadv_mesh_free(soft_iface);
553 unregister_netdevice(soft_iface); 583 queue_work(batadv_event_workqueue, &bat_priv->cleanup_work);
554} 584}
555 585
556int batadv_softif_is_valid(const struct net_device *net_dev) 586int batadv_softif_is_valid(const struct net_device *net_dev)
@@ -581,10 +611,10 @@ static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
581static void batadv_get_drvinfo(struct net_device *dev, 611static void batadv_get_drvinfo(struct net_device *dev,
582 struct ethtool_drvinfo *info) 612 struct ethtool_drvinfo *info)
583{ 613{
584 strcpy(info->driver, "B.A.T.M.A.N. advanced"); 614 strlcpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver));
585 strcpy(info->version, BATADV_SOURCE_VERSION); 615 strlcpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version));
586 strcpy(info->fw_version, "N/A"); 616 strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
587 strcpy(info->bus_info, "batman"); 617 strlcpy(info->bus_info, "batman", sizeof(info->bus_info));
588} 618}
589 619
590static u32 batadv_get_msglevel(struct net_device *dev) 620static u32 batadv_get_msglevel(struct net_device *dev)