diff options
-rw-r--r-- | net/8021q/vlan.c | 81 | ||||
-rw-r--r-- | net/8021q/vlan.h | 13 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 100 |
3 files changed, 86 insertions, 108 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 54f234696411..8bc6385a06ee 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -307,87 +307,6 @@ int unregister_vlan_device(struct net_device *dev) | |||
307 | return ret; | 307 | return ret; |
308 | } | 308 | } |
309 | 309 | ||
310 | /* | ||
311 | * vlan network devices have devices nesting below it, and are a special | ||
312 | * "super class" of normal network devices; split their locks off into a | ||
313 | * separate class since they always nest. | ||
314 | */ | ||
315 | static struct lock_class_key vlan_netdev_xmit_lock_key; | ||
316 | |||
317 | static const struct header_ops vlan_header_ops = { | ||
318 | .create = vlan_dev_hard_header, | ||
319 | .rebuild = vlan_dev_rebuild_header, | ||
320 | .parse = eth_header_parse, | ||
321 | }; | ||
322 | |||
323 | static int vlan_dev_init(struct net_device *dev) | ||
324 | { | ||
325 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | ||
326 | int subclass = 0; | ||
327 | |||
328 | /* IFF_BROADCAST|IFF_MULTICAST; ??? */ | ||
329 | dev->flags = real_dev->flags & ~IFF_UP; | ||
330 | dev->iflink = real_dev->ifindex; | ||
331 | dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | | ||
332 | (1<<__LINK_STATE_DORMANT))) | | ||
333 | (1<<__LINK_STATE_PRESENT); | ||
334 | |||
335 | /* ipv6 shared card related stuff */ | ||
336 | dev->dev_id = real_dev->dev_id; | ||
337 | |||
338 | if (is_zero_ether_addr(dev->dev_addr)) | ||
339 | memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len); | ||
340 | if (is_zero_ether_addr(dev->broadcast)) | ||
341 | memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); | ||
342 | |||
343 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { | ||
344 | dev->header_ops = real_dev->header_ops; | ||
345 | dev->hard_header_len = real_dev->hard_header_len; | ||
346 | dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; | ||
347 | } else { | ||
348 | dev->header_ops = &vlan_header_ops; | ||
349 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; | ||
350 | dev->hard_start_xmit = vlan_dev_hard_start_xmit; | ||
351 | } | ||
352 | |||
353 | if (real_dev->priv_flags & IFF_802_1Q_VLAN) | ||
354 | subclass = 1; | ||
355 | |||
356 | lockdep_set_class_and_subclass(&dev->_xmit_lock, | ||
357 | &vlan_netdev_xmit_lock_key, subclass); | ||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | void vlan_setup(struct net_device *new_dev) | ||
362 | { | ||
363 | ether_setup(new_dev); | ||
364 | |||
365 | /* new_dev->ifindex = 0; it will be set when added to | ||
366 | * the global list. | ||
367 | * iflink is set as well. | ||
368 | */ | ||
369 | /* Make this thing known as a VLAN device */ | ||
370 | new_dev->priv_flags |= IFF_802_1Q_VLAN; | ||
371 | |||
372 | /* Set us up to have no queue, as the underlying Hardware device | ||
373 | * can do all the queueing we could want. | ||
374 | */ | ||
375 | new_dev->tx_queue_len = 0; | ||
376 | |||
377 | /* set up method calls */ | ||
378 | new_dev->change_mtu = vlan_dev_change_mtu; | ||
379 | new_dev->init = vlan_dev_init; | ||
380 | new_dev->open = vlan_dev_open; | ||
381 | new_dev->stop = vlan_dev_stop; | ||
382 | new_dev->set_mac_address = vlan_set_mac_address; | ||
383 | new_dev->set_multicast_list = vlan_dev_set_multicast_list; | ||
384 | new_dev->change_rx_flags = vlan_change_rx_flags; | ||
385 | new_dev->destructor = free_netdev; | ||
386 | new_dev->do_ioctl = vlan_dev_ioctl; | ||
387 | |||
388 | memset(new_dev->broadcast, 0, ETH_ALEN); | ||
389 | } | ||
390 | |||
391 | static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev) | 310 | static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev) |
392 | { | 311 | { |
393 | /* Have to respect userspace enforced dormant state | 312 | /* Have to respect userspace enforced dormant state |
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 2cd1393073ec..7b615d6b6f46 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h | |||
@@ -49,19 +49,8 @@ struct net_device *__find_vlan_dev(struct net_device* real_dev, | |||
49 | unsigned short VID); /* vlan.c */ | 49 | unsigned short VID); /* vlan.c */ |
50 | 50 | ||
51 | /* found in vlan_dev.c */ | 51 | /* found in vlan_dev.c */ |
52 | int vlan_dev_rebuild_header(struct sk_buff *skb); | ||
53 | int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, | 52 | int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, |
54 | struct packet_type *ptype, struct net_device *orig_dev); | 53 | struct packet_type *ptype, struct net_device *orig_dev); |
55 | int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, | ||
56 | unsigned short type, const void *daddr, | ||
57 | const void *saddr, unsigned len); | ||
58 | int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); | ||
59 | int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); | ||
60 | int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); | ||
61 | int vlan_dev_open(struct net_device* dev); | ||
62 | int vlan_dev_stop(struct net_device* dev); | ||
63 | int vlan_set_mac_address(struct net_device *dev, void *p); | ||
64 | int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); | ||
65 | void vlan_dev_set_ingress_priority(const struct net_device *dev, | 54 | void vlan_dev_set_ingress_priority(const struct net_device *dev, |
66 | u32 skb_prio, short vlan_prio); | 55 | u32 skb_prio, short vlan_prio); |
67 | int vlan_dev_set_egress_priority(const struct net_device *dev, | 56 | int vlan_dev_set_egress_priority(const struct net_device *dev, |
@@ -70,8 +59,6 @@ int vlan_dev_set_vlan_flag(const struct net_device *dev, | |||
70 | u32 flag, short flag_val); | 59 | u32 flag, short flag_val); |
71 | void vlan_dev_get_realdev_name(const struct net_device *dev, char *result); | 60 | void vlan_dev_get_realdev_name(const struct net_device *dev, char *result); |
72 | void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result); | 61 | void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result); |
73 | void vlan_change_rx_flags(struct net_device *dev, int change); | ||
74 | void vlan_dev_set_multicast_list(struct net_device *vlan_dev); | ||
75 | 62 | ||
76 | int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id); | 63 | int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id); |
77 | void vlan_setup(struct net_device *dev); | 64 | void vlan_setup(struct net_device *dev); |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 9543e9182796..51ce4217c039 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -47,7 +47,7 @@ | |||
47 | * | 47 | * |
48 | * TODO: This needs a checkup, I'm ignorant here. --BLG | 48 | * TODO: This needs a checkup, I'm ignorant here. --BLG |
49 | */ | 49 | */ |
50 | int vlan_dev_rebuild_header(struct sk_buff *skb) | 50 | static int vlan_dev_rebuild_header(struct sk_buff *skb) |
51 | { | 51 | { |
52 | struct net_device *dev = skb->dev; | 52 | struct net_device *dev = skb->dev; |
53 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); | 53 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); |
@@ -342,9 +342,10 @@ static inline unsigned short vlan_dev_get_egress_qos_mask(struct net_device* dev | |||
342 | * This is called when the SKB is moving down the stack towards the | 342 | * This is called when the SKB is moving down the stack towards the |
343 | * physical devices. | 343 | * physical devices. |
344 | */ | 344 | */ |
345 | int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, | 345 | static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, |
346 | unsigned short type, | 346 | unsigned short type, |
347 | const void *daddr, const void *saddr, unsigned len) | 347 | const void *daddr, const void *saddr, |
348 | unsigned int len) | ||
348 | { | 349 | { |
349 | struct vlan_hdr *vhdr; | 350 | struct vlan_hdr *vhdr; |
350 | unsigned short veth_TCI = 0; | 351 | unsigned short veth_TCI = 0; |
@@ -451,7 +452,7 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
451 | return rc; | 452 | return rc; |
452 | } | 453 | } |
453 | 454 | ||
454 | int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | 455 | static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) |
455 | { | 456 | { |
456 | struct net_device_stats *stats = &dev->stats; | 457 | struct net_device_stats *stats = &dev->stats; |
457 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); | 458 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); |
@@ -512,7 +513,8 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
512 | return 0; | 513 | return 0; |
513 | } | 514 | } |
514 | 515 | ||
515 | int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | 516 | static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, |
517 | struct net_device *dev) | ||
516 | { | 518 | { |
517 | struct net_device_stats *stats = &dev->stats; | 519 | struct net_device_stats *stats = &dev->stats; |
518 | unsigned short veth_TCI; | 520 | unsigned short veth_TCI; |
@@ -536,7 +538,7 @@ int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev | |||
536 | return 0; | 538 | return 0; |
537 | } | 539 | } |
538 | 540 | ||
539 | int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) | 541 | static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) |
540 | { | 542 | { |
541 | /* TODO: gotta make sure the underlying layer can handle it, | 543 | /* TODO: gotta make sure the underlying layer can handle it, |
542 | * maybe an IFF_VLAN_CAPABLE flag for devices? | 544 | * maybe an IFF_VLAN_CAPABLE flag for devices? |
@@ -626,7 +628,7 @@ void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result) | |||
626 | *result = VLAN_DEV_INFO(dev)->vlan_id; | 628 | *result = VLAN_DEV_INFO(dev)->vlan_id; |
627 | } | 629 | } |
628 | 630 | ||
629 | int vlan_dev_open(struct net_device *dev) | 631 | static int vlan_dev_open(struct net_device *dev) |
630 | { | 632 | { |
631 | struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev); | 633 | struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev); |
632 | struct net_device *real_dev = vlan->real_dev; | 634 | struct net_device *real_dev = vlan->real_dev; |
@@ -650,7 +652,7 @@ int vlan_dev_open(struct net_device *dev) | |||
650 | return 0; | 652 | return 0; |
651 | } | 653 | } |
652 | 654 | ||
653 | int vlan_dev_stop(struct net_device *dev) | 655 | static int vlan_dev_stop(struct net_device *dev) |
654 | { | 656 | { |
655 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | 657 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; |
656 | 658 | ||
@@ -666,7 +668,7 @@ int vlan_dev_stop(struct net_device *dev) | |||
666 | return 0; | 668 | return 0; |
667 | } | 669 | } |
668 | 670 | ||
669 | int vlan_set_mac_address(struct net_device *dev, void *p) | 671 | static int vlan_dev_set_mac_address(struct net_device *dev, void *p) |
670 | { | 672 | { |
671 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | 673 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; |
672 | struct sockaddr *addr = p; | 674 | struct sockaddr *addr = p; |
@@ -692,7 +694,7 @@ out: | |||
692 | return 0; | 694 | return 0; |
693 | } | 695 | } |
694 | 696 | ||
695 | int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 697 | static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
696 | { | 698 | { |
697 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | 699 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; |
698 | struct ifreq ifrr; | 700 | struct ifreq ifrr; |
@@ -716,7 +718,7 @@ int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
716 | return err; | 718 | return err; |
717 | } | 719 | } |
718 | 720 | ||
719 | void vlan_change_rx_flags(struct net_device *dev, int change) | 721 | static void vlan_dev_change_rx_flags(struct net_device *dev, int change) |
720 | { | 722 | { |
721 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | 723 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; |
722 | 724 | ||
@@ -726,8 +728,78 @@ void vlan_change_rx_flags(struct net_device *dev, int change) | |||
726 | dev_set_promiscuity(real_dev, dev->flags & IFF_PROMISC ? 1 : -1); | 728 | dev_set_promiscuity(real_dev, dev->flags & IFF_PROMISC ? 1 : -1); |
727 | } | 729 | } |
728 | 730 | ||
729 | /** Taken from Gleb + Lennert's VLAN code, and modified... */ | 731 | static void vlan_dev_set_multicast_list(struct net_device *vlan_dev) |
730 | void vlan_dev_set_multicast_list(struct net_device *vlan_dev) | ||
731 | { | 732 | { |
732 | dev_mc_sync(VLAN_DEV_INFO(vlan_dev)->real_dev, vlan_dev); | 733 | dev_mc_sync(VLAN_DEV_INFO(vlan_dev)->real_dev, vlan_dev); |
733 | } | 734 | } |
735 | |||
736 | /* | ||
737 | * vlan network devices have devices nesting below it, and are a special | ||
738 | * "super class" of normal network devices; split their locks off into a | ||
739 | * separate class since they always nest. | ||
740 | */ | ||
741 | static struct lock_class_key vlan_netdev_xmit_lock_key; | ||
742 | |||
743 | static const struct header_ops vlan_header_ops = { | ||
744 | .create = vlan_dev_hard_header, | ||
745 | .rebuild = vlan_dev_rebuild_header, | ||
746 | .parse = eth_header_parse, | ||
747 | }; | ||
748 | |||
749 | static int vlan_dev_init(struct net_device *dev) | ||
750 | { | ||
751 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | ||
752 | int subclass = 0; | ||
753 | |||
754 | /* IFF_BROADCAST|IFF_MULTICAST; ??? */ | ||
755 | dev->flags = real_dev->flags & ~IFF_UP; | ||
756 | dev->iflink = real_dev->ifindex; | ||
757 | dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | | ||
758 | (1<<__LINK_STATE_DORMANT))) | | ||
759 | (1<<__LINK_STATE_PRESENT); | ||
760 | |||
761 | /* ipv6 shared card related stuff */ | ||
762 | dev->dev_id = real_dev->dev_id; | ||
763 | |||
764 | if (is_zero_ether_addr(dev->dev_addr)) | ||
765 | memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len); | ||
766 | if (is_zero_ether_addr(dev->broadcast)) | ||
767 | memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); | ||
768 | |||
769 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { | ||
770 | dev->header_ops = real_dev->header_ops; | ||
771 | dev->hard_header_len = real_dev->hard_header_len; | ||
772 | dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; | ||
773 | } else { | ||
774 | dev->header_ops = &vlan_header_ops; | ||
775 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; | ||
776 | dev->hard_start_xmit = vlan_dev_hard_start_xmit; | ||
777 | } | ||
778 | |||
779 | if (real_dev->priv_flags & IFF_802_1Q_VLAN) | ||
780 | subclass = 1; | ||
781 | |||
782 | lockdep_set_class_and_subclass(&dev->_xmit_lock, | ||
783 | &vlan_netdev_xmit_lock_key, subclass); | ||
784 | return 0; | ||
785 | } | ||
786 | |||
787 | void vlan_setup(struct net_device *dev) | ||
788 | { | ||
789 | ether_setup(dev); | ||
790 | |||
791 | dev->priv_flags |= IFF_802_1Q_VLAN; | ||
792 | dev->tx_queue_len = 0; | ||
793 | |||
794 | dev->change_mtu = vlan_dev_change_mtu; | ||
795 | dev->init = vlan_dev_init; | ||
796 | dev->open = vlan_dev_open; | ||
797 | dev->stop = vlan_dev_stop; | ||
798 | dev->set_mac_address = vlan_dev_set_mac_address; | ||
799 | dev->set_multicast_list = vlan_dev_set_multicast_list; | ||
800 | dev->change_rx_flags = vlan_dev_change_rx_flags; | ||
801 | dev->do_ioctl = vlan_dev_ioctl; | ||
802 | dev->destructor = free_netdev; | ||
803 | |||
804 | memset(dev->broadcast, 0, ETH_ALEN); | ||
805 | } | ||