aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2011-10-12 17:56:25 -0400
committerDavid S. Miller <davem@davemloft.net>2011-10-19 19:24:15 -0400
commit4c22400ab64d434a00ecbe0c655a16956c902aa8 (patch)
tree7806378cebccfea754fb566b9a707167071ad207 /drivers/net/bonding
parent672d82c18d222e51b40ff47e660fc54ec3e3e0a9 (diff)
bonding: Use a per netns implementation of /sys/class/net/bonding_masters.
This fixes a network namespace misfeature that bonding_masters looked at current instead of the remembering the context where in which /sys/class/net/bonding_masters was opened in to see which network namespace to act upon. This removes the need for sysfs to handle tagged directories with untagged members allowing for a conceptually simpler sysfs implementation. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c7
-rw-r--r--drivers/net/bonding/bond_sysfs.c45
-rw-r--r--drivers/net/bonding/bonding.h7
3 files changed, 38 insertions, 21 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6191e633728..41430baa132 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4888,6 +4888,7 @@ static int __net_init bond_net_init(struct net *net)
4888 INIT_LIST_HEAD(&bn->dev_list); 4888 INIT_LIST_HEAD(&bn->dev_list);
4889 4889
4890 bond_create_proc_dir(bn); 4890 bond_create_proc_dir(bn);
4891 bond_create_sysfs(bn);
4891 4892
4892 return 0; 4893 return 0;
4893} 4894}
@@ -4896,6 +4897,7 @@ static void __net_exit bond_net_exit(struct net *net)
4896{ 4897{
4897 struct bond_net *bn = net_generic(net, bond_net_id); 4898 struct bond_net *bn = net_generic(net, bond_net_id);
4898 4899
4900 bond_destroy_sysfs(bn);
4899 bond_destroy_proc_dir(bn); 4901 bond_destroy_proc_dir(bn);
4900} 4902}
4901 4903
@@ -4933,10 +4935,6 @@ static int __init bonding_init(void)
4933 goto err; 4935 goto err;
4934 } 4936 }
4935 4937
4936 res = bond_create_sysfs();
4937 if (res)
4938 goto err;
4939
4940 register_netdevice_notifier(&bond_netdev_notifier); 4938 register_netdevice_notifier(&bond_netdev_notifier);
4941 register_inetaddr_notifier(&bond_inetaddr_notifier); 4939 register_inetaddr_notifier(&bond_inetaddr_notifier);
4942out: 4940out:
@@ -4954,7 +4952,6 @@ static void __exit bonding_exit(void)
4954 unregister_netdevice_notifier(&bond_netdev_notifier); 4952 unregister_netdevice_notifier(&bond_netdev_notifier);
4955 unregister_inetaddr_notifier(&bond_inetaddr_notifier); 4953 unregister_inetaddr_notifier(&bond_inetaddr_notifier);
4956 4954
4957 bond_destroy_sysfs();
4958 bond_destroy_debugfs(); 4955 bond_destroy_debugfs();
4959 4956
4960 rtnl_link_unregister(&bond_link_ops); 4957 rtnl_link_unregister(&bond_link_ops);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 2dfb4bf9008..6044ff809c2 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -55,8 +55,8 @@ static ssize_t bonding_show_bonds(struct class *cls,
55 struct class_attribute *attr, 55 struct class_attribute *attr,
56 char *buf) 56 char *buf)
57{ 57{
58 struct net *net = current->nsproxy->net_ns; 58 struct bond_net *bn =
59 struct bond_net *bn = net_generic(net, bond_net_id); 59 container_of(attr, struct bond_net, class_attr_bonding_masters);
60 int res = 0; 60 int res = 0;
61 struct bonding *bond; 61 struct bonding *bond;
62 62
@@ -79,9 +79,8 @@ static ssize_t bonding_show_bonds(struct class *cls,
79 return res; 79 return res;
80} 80}
81 81
82static struct net_device *bond_get_by_name(struct net *net, const char *ifname) 82static struct net_device *bond_get_by_name(struct bond_net *bn, const char *ifname)
83{ 83{
84 struct bond_net *bn = net_generic(net, bond_net_id);
85 struct bonding *bond; 84 struct bonding *bond;
86 85
87 list_for_each_entry(bond, &bn->dev_list, bond_list) { 86 list_for_each_entry(bond, &bn->dev_list, bond_list) {
@@ -103,7 +102,8 @@ static ssize_t bonding_store_bonds(struct class *cls,
103 struct class_attribute *attr, 102 struct class_attribute *attr,
104 const char *buffer, size_t count) 103 const char *buffer, size_t count)
105{ 104{
106 struct net *net = current->nsproxy->net_ns; 105 struct bond_net *bn =
106 container_of(attr, struct bond_net, class_attr_bonding_masters);
107 char command[IFNAMSIZ + 1] = {0, }; 107 char command[IFNAMSIZ + 1] = {0, };
108 char *ifname; 108 char *ifname;
109 int rv, res = count; 109 int rv, res = count;
@@ -116,7 +116,7 @@ static ssize_t bonding_store_bonds(struct class *cls,
116 116
117 if (command[0] == '+') { 117 if (command[0] == '+') {
118 pr_info("%s is being created...\n", ifname); 118 pr_info("%s is being created...\n", ifname);
119 rv = bond_create(net, ifname); 119 rv = bond_create(bn->net, ifname);
120 if (rv) { 120 if (rv) {
121 if (rv == -EEXIST) 121 if (rv == -EEXIST)
122 pr_info("%s already exists.\n", ifname); 122 pr_info("%s already exists.\n", ifname);
@@ -128,7 +128,7 @@ static ssize_t bonding_store_bonds(struct class *cls,
128 struct net_device *bond_dev; 128 struct net_device *bond_dev;
129 129
130 rtnl_lock(); 130 rtnl_lock();
131 bond_dev = bond_get_by_name(net, ifname); 131 bond_dev = bond_get_by_name(bn, ifname);
132 if (bond_dev) { 132 if (bond_dev) {
133 pr_info("%s is being deleted...\n", ifname); 133 pr_info("%s is being deleted...\n", ifname);
134 unregister_netdevice(bond_dev); 134 unregister_netdevice(bond_dev);
@@ -150,9 +150,24 @@ err_no_cmd:
150 return -EPERM; 150 return -EPERM;
151} 151}
152 152
153static const void *bonding_namespace(struct class *cls,
154 const struct class_attribute *attr)
155{
156 const struct bond_net *bn =
157 container_of(attr, struct bond_net, class_attr_bonding_masters);
158 return bn->net;
159}
160
153/* class attribute for bond_masters file. This ends up in /sys/class/net */ 161/* class attribute for bond_masters file. This ends up in /sys/class/net */
154static CLASS_ATTR(bonding_masters, S_IWUSR | S_IRUGO, 162static const struct class_attribute class_attr_bonding_masters = {
155 bonding_show_bonds, bonding_store_bonds); 163 .attr = {
164 .name = "bonding_masters",
165 .mode = S_IWUSR | S_IRUGO,
166 },
167 .show = bonding_show_bonds,
168 .store = bonding_store_bonds,
169 .namespace = bonding_namespace,
170};
156 171
157int bond_create_slave_symlinks(struct net_device *master, 172int bond_create_slave_symlinks(struct net_device *master,
158 struct net_device *slave) 173 struct net_device *slave)
@@ -1655,11 +1670,13 @@ static struct attribute_group bonding_group = {
1655 * Initialize sysfs. This sets up the bonding_masters file in 1670 * Initialize sysfs. This sets up the bonding_masters file in
1656 * /sys/class/net. 1671 * /sys/class/net.
1657 */ 1672 */
1658int bond_create_sysfs(void) 1673int bond_create_sysfs(struct bond_net *bn)
1659{ 1674{
1660 int ret; 1675 int ret;
1661 1676
1662 ret = netdev_class_create_file(&class_attr_bonding_masters); 1677 bn->class_attr_bonding_masters = class_attr_bonding_masters;
1678
1679 ret = netdev_class_create_file(&bn->class_attr_bonding_masters);
1663 /* 1680 /*
1664 * Permit multiple loads of the module by ignoring failures to 1681 * Permit multiple loads of the module by ignoring failures to
1665 * create the bonding_masters sysfs file. Bonding devices 1682 * create the bonding_masters sysfs file. Bonding devices
@@ -1673,7 +1690,7 @@ int bond_create_sysfs(void)
1673 */ 1690 */
1674 if (ret == -EEXIST) { 1691 if (ret == -EEXIST) {
1675 /* Is someone being kinky and naming a device bonding_master? */ 1692 /* Is someone being kinky and naming a device bonding_master? */
1676 if (__dev_get_by_name(&init_net, 1693 if (__dev_get_by_name(bn->net,
1677 class_attr_bonding_masters.attr.name)) 1694 class_attr_bonding_masters.attr.name))
1678 pr_err("network device named %s already exists in sysfs", 1695 pr_err("network device named %s already exists in sysfs",
1679 class_attr_bonding_masters.attr.name); 1696 class_attr_bonding_masters.attr.name);
@@ -1687,9 +1704,9 @@ int bond_create_sysfs(void)
1687/* 1704/*
1688 * Remove /sys/class/net/bonding_masters. 1705 * Remove /sys/class/net/bonding_masters.
1689 */ 1706 */
1690void bond_destroy_sysfs(void) 1707void bond_destroy_sysfs(struct bond_net *bn)
1691{ 1708{
1692 netdev_class_remove_file(&class_attr_bonding_masters); 1709 netdev_class_remove_file(&bn->class_attr_bonding_masters);
1693} 1710}
1694 1711
1695/* 1712/*
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index e8233661560..82fec5fc75d 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -379,11 +379,13 @@ static inline bool bond_is_slave_inactive(struct slave *slave)
379 return slave->inactive; 379 return slave->inactive;
380} 380}
381 381
382struct bond_net;
383
382struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); 384struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
383int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); 385int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
384int bond_create(struct net *net, const char *name); 386int bond_create(struct net *net, const char *name);
385int bond_create_sysfs(void); 387int bond_create_sysfs(struct bond_net *net);
386void bond_destroy_sysfs(void); 388void bond_destroy_sysfs(struct bond_net *net);
387void bond_prepare_sysfs_group(struct bonding *bond); 389void bond_prepare_sysfs_group(struct bonding *bond);
388int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave); 390int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
389void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave); 391void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
@@ -409,6 +411,7 @@ struct bond_net {
409#ifdef CONFIG_PROC_FS 411#ifdef CONFIG_PROC_FS
410 struct proc_dir_entry * proc_dir; 412 struct proc_dir_entry * proc_dir;
411#endif 413#endif
414 struct class_attribute class_attr_bonding_masters;
412}; 415};
413 416
414#ifdef CONFIG_PROC_FS 417#ifdef CONFIG_PROC_FS