OSDN Git Service

xfrm: bail early on slave pass over skb
authorJarod Wilson <jarod@redhat.com>
Fri, 19 Jun 2020 14:31:52 +0000 (10:31 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 22 Jun 2020 22:38:56 +0000 (15:38 -0700)
This is prep work for initial support of bonding hardware encryption
pass-through support. The bonding driver will fill in the slave_dev
pointer, and we use that to know not to skb_push() again on a given
skb that was already processed on the bond device.

CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev@vger.kernel.org
CC: intel-wired-lan@lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/xfrm.h
net/xfrm/xfrm_device.c

index 094fe68..e20b2b2 100644 (file)
@@ -127,6 +127,7 @@ struct xfrm_state_walk {
 
 struct xfrm_state_offload {
        struct net_device       *dev;
+       struct net_device       *slave_dev;
        unsigned long           offload_handle;
        unsigned int            num_exthdrs;
        u8                      flags;
index f50d1f9..b8918fc 100644 (file)
@@ -106,6 +106,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
        struct sk_buff *skb2, *nskb, *pskb = NULL;
        netdev_features_t esp_features = features;
        struct xfrm_offload *xo = xfrm_offload(skb);
+       struct net_device *dev = skb->dev;
        struct sec_path *sp;
 
        if (!xo)
@@ -119,6 +120,10 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
        if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND)
                return skb;
 
+       /* This skb was already validated on the master dev */
+       if ((x->xso.dev != dev) && (x->xso.slave_dev == dev))
+               return skb;
+
        local_irq_save(flags);
        sd = this_cpu_ptr(&softnet_data);
        err = !skb_queue_empty(&sd->xfrm_backlog);
@@ -129,25 +134,20 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
                return skb;
        }
 
-       if (skb_is_gso(skb)) {
-               struct net_device *dev = skb->dev;
-
-               if (unlikely(x->xso.dev != dev)) {
-                       struct sk_buff *segs;
+       if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
+               struct sk_buff *segs;
 
-                       /* Packet got rerouted, fixup features and segment it. */
-                       esp_features = esp_features & ~(NETIF_F_HW_ESP
-                                                       | NETIF_F_GSO_ESP);
+               /* Packet got rerouted, fixup features and segment it. */
+               esp_features = esp_features & ~(NETIF_F_HW_ESP | NETIF_F_GSO_ESP);
 
-                       segs = skb_gso_segment(skb, esp_features);
-                       if (IS_ERR(segs)) {
-                               kfree_skb(skb);
-                               atomic_long_inc(&dev->tx_dropped);
-                               return NULL;
-                       } else {
-                               consume_skb(skb);
-                               skb = segs;
-                       }
+               segs = skb_gso_segment(skb, esp_features);
+               if (IS_ERR(segs)) {
+                       kfree_skb(skb);
+                       atomic_long_inc(&dev->tx_dropped);
+                       return NULL;
+               } else {
+                       consume_skb(skb);
+                       skb = segs;
                }
        }