aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2013-02-11 04:10:26 -0500
committerAntonio Quartulli <ordex@autistici.org>2013-03-27 05:27:34 -0400
commita4ac28c0d06a1c22138225a228d3a4eaffe9dd77 (patch)
tree22b25cf7d9ae68263b15d60f4dded639b35d93ed /net/batman-adv
parente07932ae6fb74ef707b2b27762fb0ad8aea4b55f (diff)
batman-adv: Allow to use rntl_link for device creation/deletion
The sysfs configuration interface of batman-adv to add/remove soft-interfaces is not deadlock free and doesn't follow the currently common way to create new virtual interfaces. An additional interface though rtnl_link is introduced which provides easy device creation/deletion with tools like "ip": $ ip link add dev bat0 type batadv $ ip link del dev bat0 Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/main.c2
-rw-r--r--net/batman-adv/main.h1
-rw-r--r--net/batman-adv/soft-interface.c29
-rw-r--r--net/batman-adv/soft-interface.h1
4 files changed, 33 insertions, 0 deletions
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 0495a7dc7505..62b1f89b7b4d 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -71,6 +71,7 @@ static int __init batadv_init(void)
71 batadv_debugfs_init(); 71 batadv_debugfs_init();
72 72
73 register_netdevice_notifier(&batadv_hard_if_notifier); 73 register_netdevice_notifier(&batadv_hard_if_notifier);
74 rtnl_link_register(&batadv_link_ops);
74 75
75 pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n", 76 pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n",
76 BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION); 77 BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION);
@@ -81,6 +82,7 @@ static int __init batadv_init(void)
81static void __exit batadv_exit(void) 82static void __exit batadv_exit(void)
82{ 83{
83 batadv_debugfs_destroy(); 84 batadv_debugfs_destroy();
85 rtnl_link_unregister(&batadv_link_ops);
84 unregister_netdevice_notifier(&batadv_hard_if_notifier); 86 unregister_netdevice_notifier(&batadv_hard_if_notifier);
85 batadv_hardif_remove_interfaces(); 87 batadv_hardif_remove_interfaces();
86 88
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 0afd4ee7708b..a9e12e65aa15 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -152,6 +152,7 @@ enum batadv_uev_type {
152#include <linux/percpu.h> 152#include <linux/percpu.h>
153#include <linux/slab.h> 153#include <linux/slab.h>
154#include <net/sock.h> /* struct sock */ 154#include <net/sock.h> /* struct sock */
155#include <net/rtnetlink.h>
155#include <linux/jiffies.h> 156#include <linux/jiffies.h>
156#include <linux/seq_file.h> 157#include <linux/seq_file.h>
157#include "types.h" 158#include "types.h"
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index bc77a5be960d..545c863b35fc 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -570,6 +570,8 @@ struct net_device *batadv_softif_create(const char *name)
570 if (!soft_iface) 570 if (!soft_iface)
571 return NULL; 571 return NULL;
572 572
573 soft_iface->rtnl_link_ops = &batadv_link_ops;
574
573 ret = register_netdevice(soft_iface); 575 ret = register_netdevice(soft_iface);
574 if (ret < 0) { 576 if (ret < 0) {
575 pr_err("Unable to register the batman interface '%s': %i\n", 577 pr_err("Unable to register the batman interface '%s': %i\n",
@@ -592,6 +594,26 @@ void batadv_softif_destroy_sysfs(struct net_device *soft_iface)
592 queue_work(batadv_event_workqueue, &bat_priv->cleanup_work); 594 queue_work(batadv_event_workqueue, &bat_priv->cleanup_work);
593} 595}
594 596
597/**
598 * batadv_softif_destroy_netlink - deletion of batadv_soft_interface via netlink
599 * @soft_iface: the to-be-removed batman-adv interface
600 * @head: list pointer
601 */
602static void batadv_softif_destroy_netlink(struct net_device *soft_iface,
603 struct list_head *head)
604{
605 struct batadv_hard_iface *hard_iface;
606
607 list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
608 if (hard_iface->soft_iface == soft_iface)
609 batadv_hardif_disable_interface(hard_iface,
610 BATADV_IF_CLEANUP_KEEP);
611 }
612
613 batadv_sysfs_del_meshif(soft_iface);
614 unregister_netdevice_queue(soft_iface, head);
615}
616
595int batadv_softif_is_valid(const struct net_device *net_dev) 617int batadv_softif_is_valid(const struct net_device *net_dev)
596{ 618{
597 if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) 619 if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx)
@@ -600,6 +622,13 @@ int batadv_softif_is_valid(const struct net_device *net_dev)
600 return 0; 622 return 0;
601} 623}
602 624
625struct rtnl_link_ops batadv_link_ops __read_mostly = {
626 .kind = "batadv",
627 .priv_size = sizeof(struct batadv_priv),
628 .setup = batadv_softif_init_early,
629 .dellink = batadv_softif_destroy_netlink,
630};
631
603/* ethtool */ 632/* ethtool */
604static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 633static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
605{ 634{
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h
index 49bc66bb774a..2f2472c2ea0d 100644
--- a/net/batman-adv/soft-interface.h
+++ b/net/batman-adv/soft-interface.h
@@ -27,5 +27,6 @@ void batadv_interface_rx(struct net_device *soft_iface,
27struct net_device *batadv_softif_create(const char *name); 27struct net_device *batadv_softif_create(const char *name);
28void batadv_softif_destroy_sysfs(struct net_device *soft_iface); 28void batadv_softif_destroy_sysfs(struct net_device *soft_iface);
29int batadv_softif_is_valid(const struct net_device *net_dev); 29int batadv_softif_is_valid(const struct net_device *net_dev);
30extern struct rtnl_link_ops batadv_link_ops;
30 31
31#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */ 32#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */