diff options
author | Steffen Klassert <steffen.klassert@secunet.com> | 2017-12-20 10:41:36 +0100 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2017-12-20 10:41:36 +0100 |
commit | f53c723902d1ac5f0b0a11d7c9dcbff748dde74e (patch) | |
tree | 50841e9a0ff29530ee84e262857333925e09f2ff /net/sched/sch_generic.c | |
parent | xfrm: Separate ESP handling from segmentation for GRO packets. (diff) | |
download | linux-f53c723902d1ac5f0b0a11d7c9dcbff748dde74e.tar.xz linux-f53c723902d1ac5f0b0a11d7c9dcbff748dde74e.zip |
net: Add asynchronous callbacks for xfrm on layer 2.
This patch implements asynchronous crypto callbacks
and a backlog handler that can be used when IPsec
is done at layer 2 in the TX path. It also extends
the skb validate functions so that we can update
the driver transmit return codes based on async
crypto operation or to indicate that we queued the
packet in a backlog queue.
Joint work with: Aviv Heller <avivh@mellanox.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/sched/sch_generic.c')
-rw-r--r-- | net/sched/sch_generic.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 876fab2604b8..f9a8761f0ff2 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -32,6 +32,7 @@ #include <net/pkt_sched.h> #include <net/dst.h> #include <trace/events/qdisc.h> +#include <net/xfrm.h> /* Qdisc to use by default */ const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops; @@ -230,6 +231,8 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, /* skb in gso_skb were already validated */ *validate = false; + if (xfrm_offload(skb)) + *validate = true; /* check the reason of requeuing without tx lock first */ txq = skb_get_tx_queue(txq->dev, skb); if (!netif_xmit_frozen_or_stopped(txq)) { @@ -285,6 +288,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, spinlock_t *root_lock, bool validate) { int ret = NETDEV_TX_BUSY; + bool again = false; /* And release qdisc */ if (root_lock) @@ -292,7 +296,17 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, /* Note that we validate skb (GSO, checksum, ...) outside of locks */ if (validate) - skb = validate_xmit_skb_list(skb, dev); + skb = validate_xmit_skb_list(skb, dev, &again); + +#ifdef CONFIG_XFRM_OFFLOAD + if (unlikely(again)) { + if (root_lock) + spin_lock(root_lock); + + dev_requeue_skb(skb, q); + return false; + } +#endif if (likely(skb)) { HARD_TX_LOCK(dev, txq, smp_processor_id()); |