diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 16:31:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 16:31:22 -0400 |
commit | e1bd2ac5a6b7a8b625e40c9e9f8b6dea4cf22f85 (patch) | |
tree | 9366e9fb481da2c7195ca3f2bafeffebbf001363 /drivers/net/ifb.c | |
parent | 0b9062f6b57a87f22309c6b920a51aaa66ce2a13 (diff) | |
parent | 15028aad00ddf241581fbe74a02ec89cbb28d35d (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (183 commits)
[TG3]: Update version to 3.78.
[TG3]: Add missing NVRAM strapping.
[TG3]: Enable auto MDI.
[TG3]: Fix the polarity bit.
[TG3]: Fix irq_sync race condition.
[NET_SCHED]: ematch: module autoloading
[TCP]: tcp probe wraparound handling and other changes
[RTNETLINK]: rtnl_link: allow specifying initial device address
[RTNETLINK]: rtnl_link API simplification
[VLAN]: Fix MAC address handling
[ETH]: Validate address in eth_mac_addr
[NET]: Fix races in net_rx_action vs netpoll.
[AF_UNIX]: Rewrite garbage collector, fixes race.
[NETFILTER]: {ip, nf}_conntrack_sctp: fix remotely triggerable NULL ptr dereference (CVE-2007-2876)
[NET]: Make all initialized struct seq_operations const.
[UDP]: Fix length check.
[IPV6]: Remove unneeded pointer idev from addrconf_cleanup().
[DECNET]: Another unnecessary net/tcp.h inclusion in net/dn.h
[IPV6]: Make IPV6_{RECV,2292}RTHDR boolean options.
[IPV6]: Do not send RH0 anymore.
...
Fixed up trivial conflict in Documentation/feature-removal-schedule.txt
manually.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/net/ifb.c')
-rw-r--r-- | drivers/net/ifb.c | 78 |
1 files changed, 45 insertions, 33 deletions
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 07b4c0d7a75c..f5c3598e59af 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c | |||
@@ -136,13 +136,14 @@ resched: | |||
136 | 136 | ||
137 | } | 137 | } |
138 | 138 | ||
139 | static void __init ifb_setup(struct net_device *dev) | 139 | static void ifb_setup(struct net_device *dev) |
140 | { | 140 | { |
141 | /* Initialize the device structure. */ | 141 | /* Initialize the device structure. */ |
142 | dev->get_stats = ifb_get_stats; | 142 | dev->get_stats = ifb_get_stats; |
143 | dev->hard_start_xmit = ifb_xmit; | 143 | dev->hard_start_xmit = ifb_xmit; |
144 | dev->open = &ifb_open; | 144 | dev->open = &ifb_open; |
145 | dev->stop = &ifb_close; | 145 | dev->stop = &ifb_close; |
146 | dev->destructor = free_netdev; | ||
146 | 147 | ||
147 | /* Fill in device structure with ethernet-generic values. */ | 148 | /* Fill in device structure with ethernet-generic values. */ |
148 | ether_setup(dev); | 149 | ether_setup(dev); |
@@ -197,12 +198,6 @@ static struct net_device_stats *ifb_get_stats(struct net_device *dev) | |||
197 | return stats; | 198 | return stats; |
198 | } | 199 | } |
199 | 200 | ||
200 | static struct net_device **ifbs; | ||
201 | |||
202 | /* Number of ifb devices to be set up by this module. */ | ||
203 | module_param(numifbs, int, 0); | ||
204 | MODULE_PARM_DESC(numifbs, "Number of ifb devices"); | ||
205 | |||
206 | static int ifb_close(struct net_device *dev) | 201 | static int ifb_close(struct net_device *dev) |
207 | { | 202 | { |
208 | struct ifb_private *dp = netdev_priv(dev); | 203 | struct ifb_private *dp = netdev_priv(dev); |
@@ -226,6 +221,28 @@ static int ifb_open(struct net_device *dev) | |||
226 | return 0; | 221 | return 0; |
227 | } | 222 | } |
228 | 223 | ||
224 | static int ifb_validate(struct nlattr *tb[], struct nlattr *data[]) | ||
225 | { | ||
226 | if (tb[IFLA_ADDRESS]) { | ||
227 | if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) | ||
228 | return -EINVAL; | ||
229 | if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) | ||
230 | return -EADDRNOTAVAIL; | ||
231 | } | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static struct rtnl_link_ops ifb_link_ops __read_mostly = { | ||
236 | .kind = "ifb", | ||
237 | .priv_size = sizeof(struct ifb_private), | ||
238 | .setup = ifb_setup, | ||
239 | .validate = ifb_validate, | ||
240 | }; | ||
241 | |||
242 | /* Number of ifb devices to be set up by this module. */ | ||
243 | module_param(numifbs, int, 0); | ||
244 | MODULE_PARM_DESC(numifbs, "Number of ifb devices"); | ||
245 | |||
229 | static int __init ifb_init_one(int index) | 246 | static int __init ifb_init_one(int index) |
230 | { | 247 | { |
231 | struct net_device *dev_ifb; | 248 | struct net_device *dev_ifb; |
@@ -237,49 +254,44 @@ static int __init ifb_init_one(int index) | |||
237 | if (!dev_ifb) | 254 | if (!dev_ifb) |
238 | return -ENOMEM; | 255 | return -ENOMEM; |
239 | 256 | ||
240 | if ((err = register_netdev(dev_ifb))) { | 257 | err = dev_alloc_name(dev_ifb, dev_ifb->name); |
241 | free_netdev(dev_ifb); | 258 | if (err < 0) |
242 | dev_ifb = NULL; | 259 | goto err; |
243 | } else { | ||
244 | ifbs[index] = dev_ifb; | ||
245 | } | ||
246 | 260 | ||
247 | return err; | 261 | dev_ifb->rtnl_link_ops = &ifb_link_ops; |
248 | } | 262 | err = register_netdevice(dev_ifb); |
263 | if (err < 0) | ||
264 | goto err; | ||
265 | return 0; | ||
249 | 266 | ||
250 | static void ifb_free_one(int index) | 267 | err: |
251 | { | 268 | free_netdev(dev_ifb); |
252 | unregister_netdev(ifbs[index]); | 269 | return err; |
253 | free_netdev(ifbs[index]); | ||
254 | } | 270 | } |
255 | 271 | ||
256 | static int __init ifb_init_module(void) | 272 | static int __init ifb_init_module(void) |
257 | { | 273 | { |
258 | int i, err = 0; | 274 | int i, err; |
259 | ifbs = kmalloc(numifbs * sizeof(void *), GFP_KERNEL); | 275 | |
260 | if (!ifbs) | 276 | rtnl_lock(); |
261 | return -ENOMEM; | 277 | err = __rtnl_link_register(&ifb_link_ops); |
278 | |||
262 | for (i = 0; i < numifbs && !err; i++) | 279 | for (i = 0; i < numifbs && !err; i++) |
263 | err = ifb_init_one(i); | 280 | err = ifb_init_one(i); |
264 | if (err) { | 281 | if (err) |
265 | i--; | 282 | __rtnl_link_unregister(&ifb_link_ops); |
266 | while (--i >= 0) | 283 | rtnl_unlock(); |
267 | ifb_free_one(i); | ||
268 | } | ||
269 | 284 | ||
270 | return err; | 285 | return err; |
271 | } | 286 | } |
272 | 287 | ||
273 | static void __exit ifb_cleanup_module(void) | 288 | static void __exit ifb_cleanup_module(void) |
274 | { | 289 | { |
275 | int i; | 290 | rtnl_link_unregister(&ifb_link_ops); |
276 | |||
277 | for (i = 0; i < numifbs; i++) | ||
278 | ifb_free_one(i); | ||
279 | kfree(ifbs); | ||
280 | } | 291 | } |
281 | 292 | ||
282 | module_init(ifb_init_module); | 293 | module_init(ifb_init_module); |
283 | module_exit(ifb_cleanup_module); | 294 | module_exit(ifb_cleanup_module); |
284 | MODULE_LICENSE("GPL"); | 295 | MODULE_LICENSE("GPL"); |
285 | MODULE_AUTHOR("Jamal Hadi Salim"); | 296 | MODULE_AUTHOR("Jamal Hadi Salim"); |
297 | MODULE_ALIAS_RTNL_LINK("ifb"); | ||