diff options
Diffstat (limited to 'net/8021q/vlan.c')
-rw-r--r-- | net/8021q/vlan.c | 83 |
1 files changed, 47 insertions, 36 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 1e33dbb85d14..e68b503f1012 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -447,6 +447,51 @@ static int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_ | |||
447 | return 0; | 447 | return 0; |
448 | } | 448 | } |
449 | 449 | ||
450 | static int register_vlan_dev(struct net_device *dev) | ||
451 | { | ||
452 | struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev); | ||
453 | struct net_device *real_dev = vlan->real_dev; | ||
454 | unsigned short vlan_id = vlan->vlan_id; | ||
455 | struct vlan_group *grp, *ngrp = NULL; | ||
456 | int err; | ||
457 | |||
458 | grp = __vlan_find_group(real_dev->ifindex); | ||
459 | if (!grp) { | ||
460 | ngrp = grp = vlan_group_alloc(real_dev->ifindex); | ||
461 | if (!grp) | ||
462 | return -ENOBUFS; | ||
463 | } | ||
464 | |||
465 | err = register_netdevice(dev); | ||
466 | if (err < 0) | ||
467 | goto out_free_group; | ||
468 | |||
469 | /* Account for reference in struct vlan_dev_info */ | ||
470 | dev_hold(real_dev); | ||
471 | |||
472 | vlan_transfer_operstate(real_dev, dev); | ||
473 | linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */ | ||
474 | |||
475 | /* So, got the sucker initialized, now lets place | ||
476 | * it into our local structure. | ||
477 | */ | ||
478 | vlan_group_set_device(grp, vlan_id, dev); | ||
479 | if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX) | ||
480 | real_dev->vlan_rx_register(real_dev, ngrp); | ||
481 | if (real_dev->features & NETIF_F_HW_VLAN_FILTER) | ||
482 | real_dev->vlan_rx_add_vid(real_dev, vlan_id); | ||
483 | |||
484 | if (vlan_proc_add_dev(dev) < 0) | ||
485 | printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n", | ||
486 | dev->name); | ||
487 | return 0; | ||
488 | |||
489 | out_free_group: | ||
490 | if (ngrp) | ||
491 | vlan_group_free(ngrp); | ||
492 | return err; | ||
493 | } | ||
494 | |||
450 | /* Attach a VLAN device to a mac address (ie Ethernet Card). | 495 | /* Attach a VLAN device to a mac address (ie Ethernet Card). |
451 | * Returns the device that was created, or NULL if there was | 496 | * Returns the device that was created, or NULL if there was |
452 | * an error of some kind. | 497 | * an error of some kind. |
@@ -454,7 +499,6 @@ static int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_ | |||
454 | static struct net_device *register_vlan_device(struct net_device *real_dev, | 499 | static struct net_device *register_vlan_device(struct net_device *real_dev, |
455 | unsigned short VLAN_ID) | 500 | unsigned short VLAN_ID) |
456 | { | 501 | { |
457 | struct vlan_group *grp, *ngrp = NULL; | ||
458 | struct net_device *new_dev; | 502 | struct net_device *new_dev; |
459 | char name[IFNAMSIZ]; | 503 | char name[IFNAMSIZ]; |
460 | 504 | ||
@@ -522,37 +566,8 @@ static struct net_device *register_vlan_device(struct net_device *real_dev, | |||
522 | VLAN_DEV_INFO(new_dev)->dent = NULL; | 566 | VLAN_DEV_INFO(new_dev)->dent = NULL; |
523 | VLAN_DEV_INFO(new_dev)->flags = 1; | 567 | VLAN_DEV_INFO(new_dev)->flags = 1; |
524 | 568 | ||
525 | #ifdef VLAN_DEBUG | 569 | if (register_vlan_dev(new_dev) < 0) |
526 | printk(VLAN_DBG "About to go find the group for idx: %i\n", | 570 | goto out_free_newdev; |
527 | real_dev->ifindex); | ||
528 | #endif | ||
529 | grp = __vlan_find_group(real_dev->ifindex); | ||
530 | if (!grp) { | ||
531 | ngrp = grp = vlan_group_alloc(real_dev->ifindex); | ||
532 | if (!grp) | ||
533 | goto out_free_newdev; | ||
534 | } | ||
535 | |||
536 | if (register_netdevice(new_dev)) | ||
537 | goto out_free_group; | ||
538 | |||
539 | vlan_transfer_operstate(real_dev, new_dev); | ||
540 | linkwatch_fire_event(new_dev); /* _MUST_ call rfc2863_policy() */ | ||
541 | |||
542 | /* So, got the sucker initialized, now lets place | ||
543 | * it into our local structure. | ||
544 | */ | ||
545 | if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX) | ||
546 | real_dev->vlan_rx_register(real_dev, ngrp); | ||
547 | |||
548 | vlan_group_set_device(grp, VLAN_ID, new_dev); | ||
549 | |||
550 | if (vlan_proc_add_dev(new_dev)<0)/* create it's proc entry */ | ||
551 | printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n", | ||
552 | new_dev->name); | ||
553 | |||
554 | if (real_dev->features & NETIF_F_HW_VLAN_FILTER) | ||
555 | real_dev->vlan_rx_add_vid(real_dev, VLAN_ID); | ||
556 | 571 | ||
557 | /* Account for reference in struct vlan_dev_info */ | 572 | /* Account for reference in struct vlan_dev_info */ |
558 | dev_hold(real_dev); | 573 | dev_hold(real_dev); |
@@ -561,10 +576,6 @@ static struct net_device *register_vlan_device(struct net_device *real_dev, | |||
561 | #endif | 576 | #endif |
562 | return new_dev; | 577 | return new_dev; |
563 | 578 | ||
564 | out_free_group: | ||
565 | if (ngrp) | ||
566 | vlan_group_free(ngrp); | ||
567 | |||
568 | out_free_newdev: | 579 | out_free_newdev: |
569 | free_netdev(new_dev); | 580 | free_netdev(new_dev); |
570 | 581 | ||