From patchwork Sun Jan 13 09:50:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 2702 Return-Path: Received: from nm9-vm1.bullet.mail.sg3.yahoo.com (nm9-vm1.bullet.mail.sg3.yahoo.com [106.10.148.208]) by open-mesh.org (Postfix) with ESMTPS id 54CBA601AF6 for ; Sun, 13 Jan 2013 10:51:22 +0100 (CET) Received: from [106.10.166.60] by nm9.bullet.mail.sg3.yahoo.com with NNFMP; 13 Jan 2013 09:51:18 -0000 Received: from [106.10.167.140] by tm17.bullet.mail.sg3.yahoo.com with NNFMP; 13 Jan 2013 09:51:18 -0000 Received: from [127.0.0.1] by smtp113.mail.sg3.yahoo.com with NNFMP; 13 Jan 2013 09:51:18 -0000 X-Yahoo-Newman-Id: 529695.85507.bm@smtp113.mail.sg3.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: kIOP.00VM1n6Amq3tnGB5HbftGCYdLvD43xTFq7aLZsjKqK nSLvXVUpcygRm5J4fcSJ9Vhpw00_E5XFbZmPeuetZNx9nXMd5Hnms8V.vZAh eB4tQWQmBtlC69Em1fON3GFNCz5gv_kN_5Pr0RgcfkhZQpfjP34Q3i5_cjNH .7eZ_Yu8_D.jwn_owjiT3wkThJHhmUi1jUmL34Ce7vBU6YX117Z8op8.b2lF uphGnekM6ccKFb_X_L0zYZZkRCWvumtD6Yd7wFaIm.QsyVE5ce5VO_UpTkJ9 0ZDuTGiE9ViE3RxyP9kqV0WHhGPXQNjahyg2Jjg.dnGqOWIwccY9ikAXHZ6V wRSL_UQaRHahoC9Mnrk.0bzA3VHoaTv517dPytEnzWmIsLoSW0FTLMoH9pQZ RDiAHcpuor17fWLYx47CKv0dPhB_1UYZnlCV3q4i1hq8_ X-Yahoo-SMTP: tW.h3tiswBBMXO2coYcbPigGD5Lt6zY_.Zc- Received: from localhost (lindner_marek@1.36.145.67 with plain) by smtp113.mail.sg3.yahoo.com with SMTP; 13 Jan 2013 01:51:18 -0800 PST From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Sun, 13 Jan 2013 17:50:58 +0800 Message-Id: <1358070663-8226-1-git-send-email-lindner_marek@yahoo.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <201301131750.39338.lindner_marek@yahoo.de> References: <201301131750.39338.lindner_marek@yahoo.de> Cc: Sven Eckelmann Subject: [B.A.T.M.A.N.] [PATCHv2 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: Sun, 13 Jan 2013 09:51:24 -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 | 167 ++++++++++++++++++++++++++---------------------------- 2 files changed, 85 insertions(+), 87 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 2711e87..1389c10 100644 --- a/soft-interface.c +++ b/soft-interface.c @@ -401,55 +401,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 * @@ -473,21 +424,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 @@ -495,14 +447,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); @@ -542,37 +487,85 @@ struct net_device *batadv_softif_create(const char *name) ret = batadv_algo_select(bat_priv, batadv_routing_algo); if (ret < 0) - goto unreg_soft_iface; - - ret = batadv_sysfs_add_meshif(soft_iface); - 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)