aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dummy.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-07-11 22:42:13 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 22:45:33 -0400
commit2d85cba2b272a5201a60966a65a4f8c0bcc0bb71 (patch)
treef8dd1ca6d7c963eade714a4ecc7aec4d7751f55a /drivers/net/dummy.c
parent8c979c26a0f093c13290320edda799d8335e50ae (diff)
[RTNETLINK]: rtnl_link API simplification
All drivers need to unregister their devices in the module unload function. While doing so they must hold the rtnl and atomically unregister the rtnl_link ops as well. This makes the rtnl_link_unregister function that takes the rtnl itself completely useless. Provide default newlink/dellink functions, make __rtnl_link_unregister and rtnl_link_unregister unregister all devices with matching rtnl_link_ops and change the existing users to take advantage of that. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dummy.c')
-rw-r--r--drivers/net/dummy.c57
1 files changed, 3 insertions, 54 deletions
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 91126b9ce453..373ff700404f 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -37,11 +37,6 @@
37#include <linux/rtnetlink.h> 37#include <linux/rtnetlink.h>
38#include <net/rtnetlink.h> 38#include <net/rtnetlink.h>
39 39
40struct dummy_priv {
41 struct net_device *dev;
42 struct list_head list;
43};
44
45static int numdummies = 1; 40static int numdummies = 1;
46 41
47static int dummy_xmit(struct sk_buff *skb, struct net_device *dev); 42static int dummy_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -89,37 +84,9 @@ static int dummy_xmit(struct sk_buff *skb, struct net_device *dev)
89 return 0; 84 return 0;
90} 85}
91 86
92static LIST_HEAD(dummies);
93
94static int dummy_newlink(struct net_device *dev,
95 struct nlattr *tb[], struct nlattr *data[])
96{
97 struct dummy_priv *priv = netdev_priv(dev);
98 int err;
99
100 err = register_netdevice(dev);
101 if (err < 0)
102 return err;
103
104 priv->dev = dev;
105 list_add_tail(&priv->list, &dummies);
106 return 0;
107}
108
109static void dummy_dellink(struct net_device *dev)
110{
111 struct dummy_priv *priv = netdev_priv(dev);
112
113 list_del(&priv->list);
114 unregister_netdevice(dev);
115}
116
117static struct rtnl_link_ops dummy_link_ops __read_mostly = { 87static struct rtnl_link_ops dummy_link_ops __read_mostly = {
118 .kind = "dummy", 88 .kind = "dummy",
119 .priv_size = sizeof(struct dummy_priv),
120 .setup = dummy_setup, 89 .setup = dummy_setup,
121 .newlink = dummy_newlink,
122 .dellink = dummy_dellink,
123}; 90};
124 91
125/* Number of dummy devices to be set up by this module. */ 92/* Number of dummy devices to be set up by this module. */
@@ -129,12 +96,9 @@ MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices");
129static int __init dummy_init_one(void) 96static int __init dummy_init_one(void)
130{ 97{
131 struct net_device *dev_dummy; 98 struct net_device *dev_dummy;
132 struct dummy_priv *priv;
133 int err; 99 int err;
134 100
135 dev_dummy = alloc_netdev(sizeof(struct dummy_priv), "dummy%d", 101 dev_dummy = alloc_netdev(0, "dummy%d", dummy_setup);
136 dummy_setup);
137
138 if (!dev_dummy) 102 if (!dev_dummy)
139 return -ENOMEM; 103 return -ENOMEM;
140 104
@@ -146,10 +110,6 @@ static int __init dummy_init_one(void)
146 err = register_netdevice(dev_dummy); 110 err = register_netdevice(dev_dummy);
147 if (err < 0) 111 if (err < 0)
148 goto err; 112 goto err;
149
150 priv = netdev_priv(dev_dummy);
151 priv->dev = dev_dummy;
152 list_add_tail(&priv->list, &dummies);
153 return 0; 113 return 0;
154 114
155err: 115err:
@@ -159,7 +119,6 @@ err:
159 119
160static int __init dummy_init_module(void) 120static int __init dummy_init_module(void)
161{ 121{
162 struct dummy_priv *priv, *next;
163 int i, err = 0; 122 int i, err = 0;
164 123
165 rtnl_lock(); 124 rtnl_lock();
@@ -167,11 +126,8 @@ static int __init dummy_init_module(void)
167 126
168 for (i = 0; i < numdummies && !err; i++) 127 for (i = 0; i < numdummies && !err; i++)
169 err = dummy_init_one(); 128 err = dummy_init_one();
170 if (err < 0) { 129 if (err < 0)
171 list_for_each_entry_safe(priv, next, &dummies, list)
172 dummy_dellink(priv->dev);
173 __rtnl_link_unregister(&dummy_link_ops); 130 __rtnl_link_unregister(&dummy_link_ops);
174 }
175 rtnl_unlock(); 131 rtnl_unlock();
176 132
177 return err; 133 return err;
@@ -179,14 +135,7 @@ static int __init dummy_init_module(void)
179 135
180static void __exit dummy_cleanup_module(void) 136static void __exit dummy_cleanup_module(void)
181{ 137{
182 struct dummy_priv *priv, *next; 138 rtnl_link_unregister(&dummy_link_ops);
183
184 rtnl_lock();
185 list_for_each_entry_safe(priv, next, &dummies, list)
186 dummy_dellink(priv->dev);
187
188 __rtnl_link_unregister(&dummy_link_ops);
189 rtnl_unlock();
190} 139}
191 140
192module_init(dummy_init_module); 141module_init(dummy_init_module);