From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Horman Subject: [PATCH v2 net-next repost] MPLS: Use mpls_features to activate software MPLS GSO segmentation Date: Fri, 30 May 2014 14:35:19 +0900 Message-ID: <20140530053519.GA3444@verge.net.au> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org To: David Miller , netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Return-path: Content-Disposition: inline List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces-yBygre7rU0TnMu66kgdUjQ@public.gmane.org Sender: "dev" List-Id: netdev.vger.kernel.org If an MPLS packet requires segmentation then use mpls_features to determine if the software implementation should be used. As no driver advertises MPLS GSO segmentation this will always be the case. I had not noticed that this was necessary before as software MPLS GSO segmentation was already being used in my test environment. I believe that the reason for that is the skbs in question always had fragments and the driver I used does not advertise NETIF_F_FRAGLIST (which seems to be the case for most drivers). Thus software segmentation was activated by skb_gso_ok(). Thanks to Jesse Gross for prompting me to investigate this. Acked-by: Jesse Gross Signed-off-by: Simon Horman --- v2 * Added Ack from Jesse Gross * Removed duplicate 'Thus' from changelog --- net/core/dev.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/net/core/dev.c b/net/core/dev.c index 0355ca5..15f3e6f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2540,6 +2540,40 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) } EXPORT_SYMBOL(netif_skb_features); +/* If MPLS offload request, verify we are testing hardware MPLS features + * instead of standard features for the netdev. + */ +#ifdef CONFIG_NET_MPLS_GSO +static inline netdev_features_t net_mpls_features(struct sk_buff *skb, + struct net_device *dev, netdev_features_t features) +{ + /* There is no support for MPLS LRO. So the only way that + * an MPLS skb could require GSO segmentation is if it + * was received as a non-MPLS skb and then became an MPLS skb. + * This may be effected by Open vSwitch in which case the + * mac_len will non-zero and not equal to skb_network_offset + * as the former indicates the end of L2 the latter indicates + * the beginning of L3 and there is a gap between them occupied + * by the MPLS label stack. + * + * Thus it is possible to avoid traversing any VLAN tags that are + * present to determine if the ethtype is MPLS. Instead the + * inequality of mac_llen and skb_network_offset are used to + * determine if a packet is MPLS for the purpose of determining + * offload features. + */ + if (skb->mac_len && skb->mac_len != skb_network_offset(skb)) + features &= dev->mpls_features; + return features; +} +#else +static inline netdev_features_t net_mpls_features(struct sk_buff *skb, + struct net_device *dev, netdev_features_t features) +{ + return features; +} +#endif + int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, struct netdev_queue *txq) { @@ -2576,6 +2610,8 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, if (skb->encapsulation) features &= dev->hw_enc_features; + features = net_mpls_features(skb, dev, features); + if (netif_needs_gso(skb, features)) { if (unlikely(dev_gso_segment(skb, features))) goto out_kfree_skb; -- 1.8.5.2