diff options
author | Patrick McHardy <kaber@trash.net> | 2007-06-13 15:05:41 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-11 01:14:39 -0400 |
commit | 2f4284a406cb25d1e41454cbf9ec4545b5ed70a1 (patch) | |
tree | dcc09152f9e1e59e263fe47e2633547914f98445 | |
parent | c17d8874f9959070552fddf1b4e1d73c0c144c0f (diff) |
[VLAN]: Move some device intialization code to dev->init callback
Move some device initialization code to new dev->init callback to make
it shareable with netlink. Additionally this fixes a minor bug, dev->iflink
is set after registration, which causes an incorrect value in the initial
netlink message.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/8021q/vlan.c | 92 |
1 files changed, 46 insertions, 46 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 3678f0719934..dc95f7cbf291 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -291,6 +291,48 @@ static int unregister_vlan_device(struct net_device *dev) | |||
291 | return ret; | 291 | return ret; |
292 | } | 292 | } |
293 | 293 | ||
294 | /* | ||
295 | * vlan network devices have devices nesting below it, and are a special | ||
296 | * "super class" of normal network devices; split their locks off into a | ||
297 | * separate class since they always nest. | ||
298 | */ | ||
299 | static struct lock_class_key vlan_netdev_xmit_lock_key; | ||
300 | |||
301 | static int vlan_dev_init(struct net_device *dev) | ||
302 | { | ||
303 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | ||
304 | |||
305 | /* IFF_BROADCAST|IFF_MULTICAST; ??? */ | ||
306 | dev->flags = real_dev->flags & ~IFF_UP; | ||
307 | dev->iflink = real_dev->ifindex; | ||
308 | dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | | ||
309 | (1<<__LINK_STATE_DORMANT))) | | ||
310 | (1<<__LINK_STATE_PRESENT); | ||
311 | |||
312 | /* TODO: maybe just assign it to be ETHERNET? */ | ||
313 | dev->type = real_dev->type; | ||
314 | |||
315 | memcpy(dev->broadcast, real_dev->broadcast, real_dev->addr_len); | ||
316 | memcpy(dev->dev_addr, real_dev->dev_addr, real_dev->addr_len); | ||
317 | dev->addr_len = real_dev->addr_len; | ||
318 | |||
319 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { | ||
320 | dev->hard_header = real_dev->hard_header; | ||
321 | dev->hard_header_len = real_dev->hard_header_len; | ||
322 | dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; | ||
323 | dev->rebuild_header = real_dev->rebuild_header; | ||
324 | } else { | ||
325 | dev->hard_header = vlan_dev_hard_header; | ||
326 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; | ||
327 | dev->hard_start_xmit = vlan_dev_hard_start_xmit; | ||
328 | dev->rebuild_header = vlan_dev_rebuild_header; | ||
329 | } | ||
330 | dev->hard_header_parse = real_dev->hard_header_parse; | ||
331 | |||
332 | lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key); | ||
333 | return 0; | ||
334 | } | ||
335 | |||
294 | static void vlan_setup(struct net_device *new_dev) | 336 | static void vlan_setup(struct net_device *new_dev) |
295 | { | 337 | { |
296 | SET_MODULE_OWNER(new_dev); | 338 | SET_MODULE_OWNER(new_dev); |
@@ -311,6 +353,7 @@ static void vlan_setup(struct net_device *new_dev) | |||
311 | 353 | ||
312 | /* set up method calls */ | 354 | /* set up method calls */ |
313 | new_dev->change_mtu = vlan_dev_change_mtu; | 355 | new_dev->change_mtu = vlan_dev_change_mtu; |
356 | new_dev->init = vlan_dev_init; | ||
314 | new_dev->open = vlan_dev_open; | 357 | new_dev->open = vlan_dev_open; |
315 | new_dev->stop = vlan_dev_stop; | 358 | new_dev->stop = vlan_dev_stop; |
316 | new_dev->set_mac_address = vlan_dev_set_mac_address; | 359 | new_dev->set_mac_address = vlan_dev_set_mac_address; |
@@ -339,14 +382,6 @@ static void vlan_transfer_operstate(const struct net_device *dev, struct net_dev | |||
339 | } | 382 | } |
340 | } | 383 | } |
341 | 384 | ||
342 | /* | ||
343 | * vlan network devices have devices nesting below it, and are a special | ||
344 | * "super class" of normal network devices; split their locks off into a | ||
345 | * separate class since they always nest. | ||
346 | */ | ||
347 | static struct lock_class_key vlan_netdev_xmit_lock_key; | ||
348 | |||
349 | |||
350 | /* Attach a VLAN device to a mac address (ie Ethernet Card). | 385 | /* Attach a VLAN device to a mac address (ie Ethernet Card). |
351 | * Returns the device that was created, or NULL if there was | 386 | * Returns the device that was created, or NULL if there was |
352 | * an error of some kind. | 387 | * an error of some kind. |
@@ -435,49 +470,17 @@ static struct net_device *register_vlan_device(struct net_device *real_dev, | |||
435 | if (new_dev == NULL) | 470 | if (new_dev == NULL) |
436 | goto out_ret_null; | 471 | goto out_ret_null; |
437 | 472 | ||
438 | #ifdef VLAN_DEBUG | ||
439 | printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name); | ||
440 | #endif | ||
441 | /* IFF_BROADCAST|IFF_MULTICAST; ??? */ | ||
442 | new_dev->flags = real_dev->flags; | ||
443 | new_dev->flags &= ~IFF_UP; | ||
444 | |||
445 | new_dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | | ||
446 | (1<<__LINK_STATE_DORMANT))) | | ||
447 | (1<<__LINK_STATE_PRESENT); | ||
448 | |||
449 | /* need 4 bytes for extra VLAN header info, | 473 | /* need 4 bytes for extra VLAN header info, |
450 | * hope the underlying device can handle it. | 474 | * hope the underlying device can handle it. |
451 | */ | 475 | */ |
452 | new_dev->mtu = real_dev->mtu; | 476 | new_dev->mtu = real_dev->mtu; |
453 | 477 | ||
454 | /* TODO: maybe just assign it to be ETHERNET? */ | 478 | #ifdef VLAN_DEBUG |
455 | new_dev->type = real_dev->type; | 479 | printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name); |
456 | |||
457 | new_dev->hard_header_len = real_dev->hard_header_len; | ||
458 | if (!(real_dev->features & NETIF_F_HW_VLAN_TX)) { | ||
459 | /* Regular ethernet + 4 bytes (18 total). */ | ||
460 | new_dev->hard_header_len += VLAN_HLEN; | ||
461 | } | ||
462 | |||
463 | VLAN_MEM_DBG("new_dev->priv malloc, addr: %p size: %i\n", | 480 | VLAN_MEM_DBG("new_dev->priv malloc, addr: %p size: %i\n", |
464 | new_dev->priv, | 481 | new_dev->priv, |
465 | sizeof(struct vlan_dev_info)); | 482 | sizeof(struct vlan_dev_info)); |
466 | 483 | #endif | |
467 | memcpy(new_dev->broadcast, real_dev->broadcast, real_dev->addr_len); | ||
468 | memcpy(new_dev->dev_addr, real_dev->dev_addr, real_dev->addr_len); | ||
469 | new_dev->addr_len = real_dev->addr_len; | ||
470 | |||
471 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { | ||
472 | new_dev->hard_header = real_dev->hard_header; | ||
473 | new_dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; | ||
474 | new_dev->rebuild_header = real_dev->rebuild_header; | ||
475 | } else { | ||
476 | new_dev->hard_header = vlan_dev_hard_header; | ||
477 | new_dev->hard_start_xmit = vlan_dev_hard_start_xmit; | ||
478 | new_dev->rebuild_header = vlan_dev_rebuild_header; | ||
479 | } | ||
480 | new_dev->hard_header_parse = real_dev->hard_header_parse; | ||
481 | 484 | ||
482 | VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */ | 485 | VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */ |
483 | VLAN_DEV_INFO(new_dev)->real_dev = real_dev; | 486 | VLAN_DEV_INFO(new_dev)->real_dev = real_dev; |
@@ -492,9 +495,6 @@ static struct net_device *register_vlan_device(struct net_device *real_dev, | |||
492 | if (register_netdevice(new_dev)) | 495 | if (register_netdevice(new_dev)) |
493 | goto out_free_newdev; | 496 | goto out_free_newdev; |
494 | 497 | ||
495 | lockdep_set_class(&new_dev->_xmit_lock, &vlan_netdev_xmit_lock_key); | ||
496 | |||
497 | new_dev->iflink = real_dev->ifindex; | ||
498 | vlan_transfer_operstate(real_dev, new_dev); | 498 | vlan_transfer_operstate(real_dev, new_dev); |
499 | linkwatch_fire_event(new_dev); /* _MUST_ call rfc2863_policy() */ | 499 | linkwatch_fire_event(new_dev); /* _MUST_ call rfc2863_policy() */ |
500 | 500 | ||