diff options
author | Sven Eckelmann <sven@narfation.org> | 2013-02-11 04:10:26 -0500 |
---|---|---|
committer | Antonio Quartulli <ordex@autistici.org> | 2013-03-27 05:27:34 -0400 |
commit | a4ac28c0d06a1c22138225a228d3a4eaffe9dd77 (patch) | |
tree | 22b25cf7d9ae68263b15d60f4dded639b35d93ed /net/batman-adv | |
parent | e07932ae6fb74ef707b2b27762fb0ad8aea4b55f (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.c | 2 | ||||
-rw-r--r-- | net/batman-adv/main.h | 1 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.c | 29 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.h | 1 |
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) | |||
81 | static void __exit batadv_exit(void) | 82 | static 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 | */ | ||
602 | static 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 | |||
595 | int batadv_softif_is_valid(const struct net_device *net_dev) | 617 | int 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 | ||
625 | struct 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 */ |
604 | static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 633 | static 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, | |||
27 | struct net_device *batadv_softif_create(const char *name); | 27 | struct net_device *batadv_softif_create(const char *name); |
28 | void batadv_softif_destroy_sysfs(struct net_device *soft_iface); | 28 | void batadv_softif_destroy_sysfs(struct net_device *soft_iface); |
29 | int batadv_softif_is_valid(const struct net_device *net_dev); | 29 | int batadv_softif_is_valid(const struct net_device *net_dev); |
30 | extern 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_ */ |