xfrm: bail early on slave pass over skb
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>
This commit is contained in:
parent
389cc2f326
commit
272c2330ad
|
@ -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;
|
||||
|
|
|
@ -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 (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
|
||||
struct sk_buff *segs;
|
||||
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue