Commit 8cb65d00 authored by Toshiaki Makita's avatar Toshiaki Makita Committed by David S. Miller

net: Move check for multiple vlans to drivers

To allow drivers to handle the features check for multiple tags,
move the check to ndo_features_check().
As no drivers currently handle multiple tagged TSO, introduce
dflt_features_check() and call it if the driver does not have
ndo_features_check().
Signed-off-by: default avatarToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f5a7fb88
...@@ -12557,6 +12557,7 @@ static netdev_features_t bnx2x_features_check(struct sk_buff *skb, ...@@ -12557,6 +12557,7 @@ static netdev_features_t bnx2x_features_check(struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,
netdev_features_t features) netdev_features_t features)
{ {
features = vlan_features_check(skb, features);
return vxlan_features_check(skb, features); return vxlan_features_check(skb, features);
} }
......
...@@ -2373,6 +2373,7 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb, ...@@ -2373,6 +2373,7 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,
netdev_features_t features) netdev_features_t features)
{ {
features = vlan_features_check(skb, features);
return vxlan_features_check(skb, features); return vxlan_features_check(skb, features);
} }
#endif #endif
......
...@@ -507,6 +507,7 @@ static netdev_features_t qlcnic_features_check(struct sk_buff *skb, ...@@ -507,6 +507,7 @@ static netdev_features_t qlcnic_features_check(struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,
netdev_features_t features) netdev_features_t features)
{ {
features = vlan_features_check(skb, features);
return vxlan_features_check(skb, features); return vxlan_features_check(skb, features);
} }
#endif #endif
......
...@@ -606,4 +606,26 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb) ...@@ -606,4 +606,26 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
return true; return true;
} }
/**
* vlan_features_check - drop unsafe features for skb with multiple tags.
* @skb: skbuff to query
* @features: features to be checked
*
* Returns features without unsafe ones if the skb has multiple tags.
*/
static inline netdev_features_t vlan_features_check(const struct sk_buff *skb,
netdev_features_t features)
{
if (skb_vlan_tagged_multi(skb))
features = netdev_intersect_features(features,
NETIF_F_SG |
NETIF_F_HIGHDMA |
NETIF_F_FRAGLIST |
NETIF_F_GEN_CSUM |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);
return features;
}
#endif /* !(_LINUX_IF_VLAN_H_) */ #endif /* !(_LINUX_IF_VLAN_H_) */
...@@ -2562,6 +2562,13 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, ...@@ -2562,6 +2562,13 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
return features; return features;
} }
static netdev_features_t dflt_features_check(const struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
return vlan_features_check(skb, features);
}
netdev_features_t netif_skb_features(struct sk_buff *skb) netdev_features_t netif_skb_features(struct sk_buff *skb)
{ {
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
...@@ -2583,22 +2590,12 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) ...@@ -2583,22 +2590,12 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
dev->vlan_features | dev->vlan_features |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX); NETIF_F_HW_VLAN_STAG_TX);
else
goto finalize;
if (skb_vlan_tagged_multi(skb))
features = netdev_intersect_features(features,
NETIF_F_SG |
NETIF_F_HIGHDMA |
NETIF_F_FRAGLIST |
NETIF_F_GEN_CSUM |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);
finalize:
if (dev->netdev_ops->ndo_features_check) if (dev->netdev_ops->ndo_features_check)
features &= dev->netdev_ops->ndo_features_check(skb, dev, features &= dev->netdev_ops->ndo_features_check(skb, dev,
features); features);
else
features &= dflt_features_check(skb, dev, features);
return harmonize_features(skb, features); return harmonize_features(skb, features);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment