net: vlan: add protocol argument to packet tagging functions
Add a protocol argument to the VLAN packet tagging functions. In case of HW tagging, we need that protocol available in the ndo_start_xmit functions, so it is stored in a new field in the skb. The new field fits into a hole (on 64 bit) and doesn't increase the sks's size. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
1fd9b1fc31
commit
86a9bad3ab
@@ -157,9 +157,18 @@ static inline bool vlan_uses_dev(const struct net_device *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool vlan_hw_offload_capable(netdev_features_t features,
|
||||
__be16 proto)
|
||||
{
|
||||
if (proto == htons(ETH_P_8021Q) && features & NETIF_F_HW_VLAN_CTAG_TX)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* vlan_insert_tag - regular VLAN tag inserting
|
||||
* @skb: skbuff to tag
|
||||
* @vlan_proto: VLAN encapsulation protocol
|
||||
* @vlan_tci: VLAN TCI to insert
|
||||
*
|
||||
* Inserts the VLAN tag into @skb as part of the payload
|
||||
@@ -170,7 +179,8 @@ static inline bool vlan_uses_dev(const struct net_device *dev)
|
||||
*
|
||||
* Does not change skb->protocol so this function can be used during receive.
|
||||
*/
|
||||
static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci)
|
||||
static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
|
||||
__be16 vlan_proto, u16 vlan_tci)
|
||||
{
|
||||
struct vlan_ethhdr *veth;
|
||||
|
||||
@@ -185,7 +195,7 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci)
|
||||
skb->mac_header -= VLAN_HLEN;
|
||||
|
||||
/* first, the ethernet type */
|
||||
veth->h_vlan_proto = htons(ETH_P_8021Q);
|
||||
veth->h_vlan_proto = vlan_proto;
|
||||
|
||||
/* now, the TCI */
|
||||
veth->h_vlan_TCI = htons(vlan_tci);
|
||||
@@ -204,24 +214,28 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci)
|
||||
* Following the skb_unshare() example, in case of error, the calling function
|
||||
* doesn't have to worry about freeing the original skb.
|
||||
*/
|
||||
static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
|
||||
static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb,
|
||||
__be16 vlan_proto, u16 vlan_tci)
|
||||
{
|
||||
skb = vlan_insert_tag(skb, vlan_tci);
|
||||
skb = vlan_insert_tag(skb, vlan_proto, vlan_tci);
|
||||
if (skb)
|
||||
skb->protocol = htons(ETH_P_8021Q);
|
||||
skb->protocol = vlan_proto;
|
||||
return skb;
|
||||
}
|
||||
|
||||
/**
|
||||
* __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting
|
||||
* @skb: skbuff to tag
|
||||
* @vlan_proto: VLAN encapsulation protocol
|
||||
* @vlan_tci: VLAN TCI to insert
|
||||
*
|
||||
* Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest
|
||||
*/
|
||||
static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb,
|
||||
__be16 vlan_proto,
|
||||
u16 vlan_tci)
|
||||
{
|
||||
skb->vlan_proto = vlan_proto;
|
||||
skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci;
|
||||
return skb;
|
||||
}
|
||||
@@ -236,12 +250,13 @@ static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb,
|
||||
* Assumes skb->dev is the target that will xmit this frame.
|
||||
* Returns a VLAN tagged skb.
|
||||
*/
|
||||
static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
|
||||
static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb,
|
||||
__be16 vlan_proto, u16 vlan_tci)
|
||||
{
|
||||
if (skb->dev->features & NETIF_F_HW_VLAN_CTAG_TX) {
|
||||
return __vlan_hwaccel_put_tag(skb, vlan_tci);
|
||||
if (vlan_hw_offload_capable(skb->dev->features, vlan_proto)) {
|
||||
return __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci);
|
||||
} else {
|
||||
return __vlan_put_tag(skb, vlan_tci);
|
||||
return __vlan_put_tag(skb, vlan_proto, vlan_tci);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user