diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 2 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 3 | ||||
-rw-r--r-- | net/core/skbuff.c | 53 |
3 files changed, 56 insertions, 2 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 1c15b189c52b..b65a5051361f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3602,7 +3602,7 @@ another_round: | |||
3602 | 3602 | ||
3603 | if (skb->protocol == cpu_to_be16(ETH_P_8021Q) || | 3603 | if (skb->protocol == cpu_to_be16(ETH_P_8021Q) || |
3604 | skb->protocol == cpu_to_be16(ETH_P_8021AD)) { | 3604 | skb->protocol == cpu_to_be16(ETH_P_8021AD)) { |
3605 | skb = vlan_untag(skb); | 3605 | skb = skb_vlan_untag(skb); |
3606 | if (unlikely(!skb)) | 3606 | if (unlikely(!skb)) |
3607 | goto unlock; | 3607 | goto unlock; |
3608 | } | 3608 | } |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 8d39071f32d7..f0493e3b7471 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -804,7 +804,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, | |||
804 | (nla_total_size(sizeof(struct ifla_vf_mac)) + | 804 | (nla_total_size(sizeof(struct ifla_vf_mac)) + |
805 | nla_total_size(sizeof(struct ifla_vf_vlan)) + | 805 | nla_total_size(sizeof(struct ifla_vf_vlan)) + |
806 | nla_total_size(sizeof(struct ifla_vf_spoofchk)) + | 806 | nla_total_size(sizeof(struct ifla_vf_spoofchk)) + |
807 | nla_total_size(sizeof(struct ifla_vf_rate))); | 807 | nla_total_size(sizeof(struct ifla_vf_rate)) + |
808 | nla_total_size(sizeof(struct ifla_vf_link_state))); | ||
808 | return size; | 809 | return size; |
809 | } else | 810 | } else |
810 | return 0; | 811 | return 0; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 224506a6fa80..163b673f9e62 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/scatterlist.h> | 62 | #include <linux/scatterlist.h> |
63 | #include <linux/errqueue.h> | 63 | #include <linux/errqueue.h> |
64 | #include <linux/prefetch.h> | 64 | #include <linux/prefetch.h> |
65 | #include <linux/if_vlan.h> | ||
65 | 66 | ||
66 | #include <net/protocol.h> | 67 | #include <net/protocol.h> |
67 | #include <net/dst.h> | 68 | #include <net/dst.h> |
@@ -3973,3 +3974,55 @@ unsigned int skb_gso_transport_seglen(const struct sk_buff *skb) | |||
3973 | return shinfo->gso_size; | 3974 | return shinfo->gso_size; |
3974 | } | 3975 | } |
3975 | EXPORT_SYMBOL_GPL(skb_gso_transport_seglen); | 3976 | EXPORT_SYMBOL_GPL(skb_gso_transport_seglen); |
3977 | |||
3978 | static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb) | ||
3979 | { | ||
3980 | if (skb_cow(skb, skb_headroom(skb)) < 0) { | ||
3981 | kfree_skb(skb); | ||
3982 | return NULL; | ||
3983 | } | ||
3984 | |||
3985 | memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN); | ||
3986 | skb->mac_header += VLAN_HLEN; | ||
3987 | return skb; | ||
3988 | } | ||
3989 | |||
3990 | struct sk_buff *skb_vlan_untag(struct sk_buff *skb) | ||
3991 | { | ||
3992 | struct vlan_hdr *vhdr; | ||
3993 | u16 vlan_tci; | ||
3994 | |||
3995 | if (unlikely(vlan_tx_tag_present(skb))) { | ||
3996 | /* vlan_tci is already set-up so leave this for another time */ | ||
3997 | return skb; | ||
3998 | } | ||
3999 | |||
4000 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
4001 | if (unlikely(!skb)) | ||
4002 | goto err_free; | ||
4003 | |||
4004 | if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) | ||
4005 | goto err_free; | ||
4006 | |||
4007 | vhdr = (struct vlan_hdr *)skb->data; | ||
4008 | vlan_tci = ntohs(vhdr->h_vlan_TCI); | ||
4009 | __vlan_hwaccel_put_tag(skb, skb->protocol, vlan_tci); | ||
4010 | |||
4011 | skb_pull_rcsum(skb, VLAN_HLEN); | ||
4012 | vlan_set_encap_proto(skb, vhdr); | ||
4013 | |||
4014 | skb = skb_reorder_vlan_header(skb); | ||
4015 | if (unlikely(!skb)) | ||
4016 | goto err_free; | ||
4017 | |||
4018 | skb_reset_network_header(skb); | ||
4019 | skb_reset_transport_header(skb); | ||
4020 | skb_reset_mac_len(skb); | ||
4021 | |||
4022 | return skb; | ||
4023 | |||
4024 | err_free: | ||
4025 | kfree_skb(skb); | ||
4026 | return NULL; | ||
4027 | } | ||
4028 | EXPORT_SYMBOL(skb_vlan_untag); | ||