Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+6 −1
Original line number Original line Diff line number Diff line
@@ -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)
{
{
+12 −10
Original line number Original line Diff line number Diff line
@@ -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)
}
}


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)
				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)