From patchwork Mon Feb 11 09:10:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 2773 Return-Path: Received: from nm11-vm2.bullet.mail.sg3.yahoo.com (nm11-vm2.bullet.mail.sg3.yahoo.com [106.10.148.241]) by open-mesh.org (Postfix) with ESMTPS id B9DE66013E6 for ; Mon, 11 Feb 2013 10:10:50 +0100 (CET) Received: from [106.10.166.122] by nm11.bullet.mail.sg3.yahoo.com with NNFMP; 11 Feb 2013 09:10:47 -0000 Received: from [106.10.167.136] by tm11.bullet.mail.sg3.yahoo.com with NNFMP; 11 Feb 2013 09:10:47 -0000 Received: from [127.0.0.1] by smtp109.mail.sg3.yahoo.com with NNFMP; 11 Feb 2013 09:10:47 -0000 X-Yahoo-Newman-Id: 97712.97345.bm@smtp109.mail.sg3.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: Liop0o0VM1nmkTNB46iVcHJH0h0Msiv2K29xBZSjB_so8.C s98tCe9vbazV7KF3fc1bQmIe7xHPmUyNBF3TF1oPqYh8IVYjTSkj6iO9wiuc 8Sf6MKUC4ACkc5nwbd1QTMcsdNo.D4GFj1V6jaxKZ8BJ0OXU8bg6T_tfE73c _nPQR5fFbc1JBsBxHyVejHkiiRGYLgiawUFKQMsBVojx1_8ZUpcDwi8FPZgz y52IkfbeLhqQzpTYAu4PnwWxrmILK1LpKaKGYcIxmPlb41GUF23SH.pH5oKE Ks1Tz2VXu.AcjCtc60OFyhNFmEJ2U48RP6xIjIcFTXruKJoDVxELLuc3KNQx teI8.3h6_WOalpUzCG7Bartdv4fqYDdRuBRXoKcOjuxCaYj3FIXYbxJRMt6a 387025mWxRC.WWEd9giJUL9tUVgAoD9_8vZIPWK.DP39P X-Yahoo-SMTP: tW.h3tiswBBMXO2coYcbPigGD5Lt6zY_.Zc- Received: from localhost (lindner_marek@1.36.145.66 with plain) by smtp109.mail.sg3.yahoo.com with SMTP; 11 Feb 2013 01:10:47 -0800 PST From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Mon, 11 Feb 2013 17:10:22 +0800 Message-Id: <1360573828-24399-1-git-send-email-lindner_marek@yahoo.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <201302111710.04911.lindner_marek@yahoo.de> References: <201302111710.04911.lindner_marek@yahoo.de> Cc: Sven Eckelmann Subject: [B.A.T.M.A.N.] [PATCHv3 1/6] batman-adv: Move soft-interface initialization to ndo_init X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Feb 2013 09:10:53 -0000 From: Sven Eckelmann The initialization of an net_device object should be done in the init/constructor function and not from the outside after the register_netdevice was done to avoid race conditions. Signed-off-by: Sven Eckelmann --- hard-interface.c | 5 ++ soft-interface.c | 169 ++++++++++++++++++++++++++---------------------------- 2 files changed, 86 insertions(+), 88 deletions(-) diff --git a/hard-interface.c b/hard-interface.c index 368219e..da000e9 100644 --- a/hard-interface.c +++ b/hard-interface.c @@ -563,6 +563,11 @@ static int batadv_hard_if_event(struct notifier_block *this, struct batadv_hard_iface *primary_if = NULL; struct batadv_priv *bat_priv; + if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) { + batadv_sysfs_add_meshif(net_dev); + return NOTIFY_DONE; + } + hard_iface = batadv_hardif_get_by_netdev(net_dev); if (!hard_iface && event == NETDEV_REGISTER) hard_iface = batadv_hardif_add_interface(net_dev); diff --git a/soft-interface.c b/soft-interface.c index f93ae42..c5cb0a7 100644 --- a/soft-interface.c +++ b/soft-interface.c @@ -402,55 +402,6 @@ static void batadv_set_lockdep_class(struct net_device *dev) } /** - * batadv_softif_init - Late stage initialization of soft interface - * @dev: registered network device to modify - * - * Returns error code on failures - */ -static int batadv_softif_init(struct net_device *dev) -{ - batadv_set_lockdep_class(dev); - - return 0; -} - -static const struct net_device_ops batadv_netdev_ops = { - .ndo_init = batadv_softif_init, - .ndo_open = batadv_interface_open, - .ndo_stop = batadv_interface_release, - .ndo_get_stats = batadv_interface_stats, - .ndo_set_mac_address = batadv_interface_set_mac_addr, - .ndo_change_mtu = batadv_interface_change_mtu, - .ndo_start_xmit = batadv_interface_tx, - .ndo_validate_addr = eth_validate_addr -}; - -static void batadv_interface_setup(struct net_device *dev) -{ - struct batadv_priv *priv = netdev_priv(dev); - - ether_setup(dev); - - dev->netdev_ops = &batadv_netdev_ops; - dev->destructor = free_netdev; - dev->tx_queue_len = 0; - - /* can't call min_mtu, because the needed variables - * have not been initialized yet - */ - dev->mtu = ETH_DATA_LEN; - /* reserve more space in the skbuff for our header */ - dev->hard_header_len = BATADV_HEADER_LEN; - - /* generate random address */ - eth_hw_addr_random(dev); - - SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops); - - memset(priv, 0, sizeof(*priv)); -} - -/** * batadv_softif_destroy_finish - cleans up the remains of a softif * @work: work queue item * @@ -474,21 +425,22 @@ static void batadv_softif_destroy_finish(struct work_struct *work) rtnl_unlock(); } -struct net_device *batadv_softif_create(const char *name) +/** + * batadv_softif_init_late - late stage initialization of soft interface + * @dev: registered network device to modify + * + * Returns error code on failures + */ +static int batadv_softif_init_late(struct net_device *dev) { - struct net_device *soft_iface; struct batadv_priv *bat_priv; int ret; size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM; - soft_iface = alloc_netdev(sizeof(*bat_priv), name, - batadv_interface_setup); - - if (!soft_iface) - goto out; + batadv_set_lockdep_class(dev); - bat_priv = netdev_priv(soft_iface); - bat_priv->soft_iface = soft_iface; + bat_priv = netdev_priv(dev); + bat_priv->soft_iface = dev; INIT_WORK(&bat_priv->cleanup_work, batadv_softif_destroy_finish); /* batadv_interface_stats() needs to be available as soon as @@ -496,14 +448,7 @@ struct net_device *batadv_softif_create(const char *name) */ bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); if (!bat_priv->bat_counters) - goto free_soft_iface; - - ret = register_netdevice(soft_iface); - if (ret < 0) { - pr_err("Unable to register the batman interface '%s': %i\n", - name, ret); - goto free_bat_counters; - } + return -ENOMEM; atomic_set(&bat_priv->aggregated_ogms, 1); atomic_set(&bat_priv->bonding, 0); @@ -541,41 +486,89 @@ struct net_device *batadv_softif_create(const char *name) bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0; - ret = batadv_algo_select(bat_priv, batadv_routing_algo); - if (ret < 0) - goto unreg_soft_iface; - batadv_nc_init_bat_priv(bat_priv); - ret = batadv_sysfs_add_meshif(soft_iface); + ret = batadv_algo_select(bat_priv, batadv_routing_algo); if (ret < 0) - goto unreg_soft_iface; + goto free_bat_counters; - ret = batadv_debugfs_add_meshif(soft_iface); + ret = batadv_debugfs_add_meshif(dev); if (ret < 0) - goto unreg_sysfs; + goto free_bat_counters; - ret = batadv_mesh_init(soft_iface); + ret = batadv_mesh_init(dev); if (ret < 0) goto unreg_debugfs; - return soft_iface; + return 0; unreg_debugfs: - batadv_debugfs_del_meshif(soft_iface); -unreg_sysfs: - batadv_sysfs_del_meshif(soft_iface); -unreg_soft_iface: - free_percpu(bat_priv->bat_counters); - unregister_netdevice(soft_iface); - return NULL; - + batadv_debugfs_del_meshif(dev); free_bat_counters: free_percpu(bat_priv->bat_counters); -free_soft_iface: - free_netdev(soft_iface); -out: - return NULL; + + return ret; +} + +static const struct net_device_ops batadv_netdev_ops = { + .ndo_init = batadv_softif_init_late, + .ndo_open = batadv_interface_open, + .ndo_stop = batadv_interface_release, + .ndo_get_stats = batadv_interface_stats, + .ndo_set_mac_address = batadv_interface_set_mac_addr, + .ndo_change_mtu = batadv_interface_change_mtu, + .ndo_start_xmit = batadv_interface_tx, + .ndo_validate_addr = eth_validate_addr +}; + +/** + * batadv_softif_init_early - early stage initialization of soft interface + * @dev: registered network device to modify + */ +static void batadv_softif_init_early(struct net_device *dev) +{ + struct batadv_priv *priv = netdev_priv(dev); + + ether_setup(dev); + + dev->netdev_ops = &batadv_netdev_ops; + dev->destructor = free_netdev; + dev->tx_queue_len = 0; + + /* can't call min_mtu, because the needed variables + * have not been initialized yet + */ + dev->mtu = ETH_DATA_LEN; + /* reserve more space in the skbuff for our header */ + dev->hard_header_len = BATADV_HEADER_LEN; + + /* generate random address */ + eth_hw_addr_random(dev); + + SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops); + + memset(priv, 0, sizeof(*priv)); +} + +struct net_device *batadv_softif_create(const char *name) +{ + struct net_device *soft_iface; + int ret; + + soft_iface = alloc_netdev(sizeof(struct batadv_priv), name, + batadv_softif_init_early); + if (!soft_iface) + return NULL; + + ret = register_netdevice(soft_iface); + if (ret < 0) { + pr_err("Unable to register the batman interface '%s': %i\n", + name, ret); + free_netdev(soft_iface); + return NULL; + } + + return soft_iface; } void batadv_softif_destroy(struct net_device *soft_iface)