Skip to content

Commit

Permalink
net: Move check for multiple vlans to drivers
Browse files Browse the repository at this point in the history
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: Toshiaki Makita <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Toshiaki Makita authored and davem330 committed Mar 29, 2015
1 parent f5a7fb8 commit 8cb65d0
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 12 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -12557,6 +12557,7 @@ static netdev_features_t bnx2x_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
features = vlan_features_check(skb, features);
return vxlan_features_check(skb, features);
}

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlx4/en_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2373,6 +2373,7 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
features = vlan_features_check(skb, features);
return vxlan_features_check(skb, features);
}
#endif
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ static netdev_features_t qlcnic_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
features = vlan_features_check(skb, features);
return vxlan_features_check(skb, features);
}
#endif
Expand Down
22 changes: 22 additions & 0 deletions include/linux/if_vlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,4 +606,26 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
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_) */
21 changes: 9 additions & 12 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2562,6 +2562,13 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
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)
{
struct net_device *dev = skb->dev;
Expand All @@ -2583,22 +2590,12 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
dev->vlan_features |
NETIF_F_HW_VLAN_CTAG_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)
features &= dev->netdev_ops->ndo_features_check(skb, dev,
features);
else
features &= dflt_features_check(skb, dev, features);

return harmonize_features(skb, features);
}
Expand Down

0 comments on commit 8cb65d0

Please sign in to comment.