Commit d2069403 authored by Florian Westphal's avatar Florian Westphal Committed by David S. Miller

net: core: introduce netif_skb_dev_features

Will be used by upcoming ipv4 forward path change that needs to
determine feature mask using skb->dst->dev instead of skb->dev.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f80889a5
...@@ -3068,7 +3068,12 @@ void netdev_change_features(struct net_device *dev); ...@@ -3068,7 +3068,12 @@ void netdev_change_features(struct net_device *dev);
void netif_stacked_transfer_operstate(const struct net_device *rootdev, void netif_stacked_transfer_operstate(const struct net_device *rootdev,
struct net_device *dev); struct net_device *dev);
netdev_features_t netif_skb_features(struct sk_buff *skb); netdev_features_t netif_skb_dev_features(struct sk_buff *skb,
const struct net_device *dev);
static inline netdev_features_t netif_skb_features(struct sk_buff *skb)
{
return netif_skb_dev_features(skb, skb->dev);
}
static inline bool net_gso_ok(netdev_features_t features, int gso_type) static inline bool net_gso_ok(netdev_features_t features, int gso_type)
{ {
......
...@@ -2420,7 +2420,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault); ...@@ -2420,7 +2420,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault);
* 2. No high memory really exists on this machine. * 2. No high memory really exists on this machine.
*/ */
static int illegal_highdma(struct net_device *dev, struct sk_buff *skb) static int illegal_highdma(const struct net_device *dev, struct sk_buff *skb)
{ {
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
int i; int i;
...@@ -2495,34 +2495,36 @@ static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features) ...@@ -2495,34 +2495,36 @@ static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features)
} }
static netdev_features_t harmonize_features(struct sk_buff *skb, static netdev_features_t harmonize_features(struct sk_buff *skb,
const struct net_device *dev,
netdev_features_t features) netdev_features_t features)
{ {
if (skb->ip_summed != CHECKSUM_NONE && if (skb->ip_summed != CHECKSUM_NONE &&
!can_checksum_protocol(features, skb_network_protocol(skb))) { !can_checksum_protocol(features, skb_network_protocol(skb))) {
features &= ~NETIF_F_ALL_CSUM; features &= ~NETIF_F_ALL_CSUM;
} else if (illegal_highdma(skb->dev, skb)) { } else if (illegal_highdma(dev, skb)) {
features &= ~NETIF_F_SG; features &= ~NETIF_F_SG;
} }
return features; return features;
} }
netdev_features_t netif_skb_features(struct sk_buff *skb) netdev_features_t netif_skb_dev_features(struct sk_buff *skb,
const struct net_device *dev)
{ {
__be16 protocol = skb->protocol; __be16 protocol = skb->protocol;
netdev_features_t features = skb->dev->features; netdev_features_t features = dev->features;
if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs) if (skb_shinfo(skb)->gso_segs > dev->gso_max_segs)
features &= ~NETIF_F_GSO_MASK; features &= ~NETIF_F_GSO_MASK;
if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) {
struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
protocol = veh->h_vlan_encapsulated_proto; protocol = veh->h_vlan_encapsulated_proto;
} else if (!vlan_tx_tag_present(skb)) { } else if (!vlan_tx_tag_present(skb)) {
return harmonize_features(skb, features); return harmonize_features(skb, dev, features);
} }
features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | features &= (dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX); NETIF_F_HW_VLAN_STAG_TX);
if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD))
...@@ -2530,9 +2532,9 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) ...@@ -2530,9 +2532,9 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX; NETIF_F_HW_VLAN_STAG_TX;
return harmonize_features(skb, features); return harmonize_features(skb, dev, features);
} }
EXPORT_SYMBOL(netif_skb_features); EXPORT_SYMBOL(netif_skb_dev_features);
int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq) struct netdev_queue *txq)
......
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