mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-30 11:04:25 +00:00
[IPSEC]: Add async resume support on output
This patch adds support for async resumptions on output. To do so, the transform would return -EINPROGRESS and subsequently invoke the function xfrm_output_resume to resume processing. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
862b82c6f9
commit
c6581a457e
2 changed files with 41 additions and 17 deletions
|
@ -1119,6 +1119,7 @@ extern void xfrm_replay_notify(struct xfrm_state *x, int event);
|
||||||
extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
|
extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
|
||||||
extern int xfrm_init_state(struct xfrm_state *x);
|
extern int xfrm_init_state(struct xfrm_state *x);
|
||||||
extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
|
extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
|
||||||
|
extern int xfrm_output_resume(struct sk_buff *skb, int err);
|
||||||
extern int xfrm_output(struct sk_buff *skb);
|
extern int xfrm_output(struct sk_buff *skb);
|
||||||
extern int xfrm4_extract_header(struct sk_buff *skb);
|
extern int xfrm4_extract_header(struct sk_buff *skb);
|
||||||
extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
|
extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include <net/dst.h>
|
#include <net/dst.h>
|
||||||
#include <net/xfrm.h>
|
#include <net/xfrm.h>
|
||||||
|
|
||||||
|
static int xfrm_output2(struct sk_buff *skb);
|
||||||
|
|
||||||
static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
|
static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct dst_entry *dst = skb->dst;
|
struct dst_entry *dst = skb->dst;
|
||||||
|
@ -41,17 +43,13 @@ err:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xfrm_output_one(struct sk_buff *skb)
|
static int xfrm_output_one(struct sk_buff *skb, int err)
|
||||||
{
|
{
|
||||||
struct dst_entry *dst = skb->dst;
|
struct dst_entry *dst = skb->dst;
|
||||||
struct xfrm_state *x = dst->xfrm;
|
struct xfrm_state *x = dst->xfrm;
|
||||||
int err;
|
|
||||||
|
|
||||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
if (err <= 0)
|
||||||
err = skb_checksum_help(skb);
|
goto resume;
|
||||||
if (err)
|
|
||||||
goto error_nolock;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
err = x->outer_mode->output(x, skb);
|
err = x->outer_mode->output(x, skb);
|
||||||
|
@ -75,6 +73,8 @@ static int xfrm_output_one(struct sk_buff *skb)
|
||||||
spin_unlock_bh(&x->lock);
|
spin_unlock_bh(&x->lock);
|
||||||
|
|
||||||
err = x->type->output(x, skb);
|
err = x->type->output(x, skb);
|
||||||
|
|
||||||
|
resume:
|
||||||
if (err)
|
if (err)
|
||||||
goto error_nolock;
|
goto error_nolock;
|
||||||
|
|
||||||
|
@ -97,18 +97,16 @@ error_nolock:
|
||||||
goto out_exit;
|
goto out_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xfrm_output2(struct sk_buff *skb)
|
int xfrm_output_resume(struct sk_buff *skb, int err)
|
||||||
{
|
{
|
||||||
int err;
|
while (likely((err = xfrm_output_one(skb, err)) == 0)) {
|
||||||
|
|
||||||
while (likely((err = xfrm_output_one(skb)) == 0)) {
|
|
||||||
struct xfrm_state *x;
|
struct xfrm_state *x;
|
||||||
|
|
||||||
nf_reset(skb);
|
nf_reset(skb);
|
||||||
|
|
||||||
err = skb->dst->ops->local_out(skb);
|
err = skb->dst->ops->local_out(skb);
|
||||||
if (unlikely(err != 1))
|
if (unlikely(err != 1))
|
||||||
break;
|
goto out;
|
||||||
|
|
||||||
x = skb->dst->xfrm;
|
x = skb->dst->xfrm;
|
||||||
if (!x)
|
if (!x)
|
||||||
|
@ -118,19 +116,26 @@ static int xfrm_output2(struct sk_buff *skb)
|
||||||
x->inner_mode->afinfo->nf_post_routing, skb,
|
x->inner_mode->afinfo->nf_post_routing, skb,
|
||||||
NULL, skb->dst->dev, xfrm_output2);
|
NULL, skb->dst->dev, xfrm_output2);
|
||||||
if (unlikely(err != 1))
|
if (unlikely(err != 1))
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (err == -EINPROGRESS)
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(xfrm_output_resume);
|
||||||
|
|
||||||
int xfrm_output(struct sk_buff *skb)
|
static int xfrm_output2(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return xfrm_output_resume(skb, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xfrm_output_gso(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct sk_buff *segs;
|
struct sk_buff *segs;
|
||||||
|
|
||||||
if (!skb_is_gso(skb))
|
|
||||||
return xfrm_output2(skb);
|
|
||||||
|
|
||||||
segs = skb_gso_segment(skb, 0);
|
segs = skb_gso_segment(skb, 0);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
if (unlikely(IS_ERR(segs)))
|
if (unlikely(IS_ERR(segs)))
|
||||||
|
@ -157,4 +162,22 @@ int xfrm_output(struct sk_buff *skb)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xfrm_output(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (skb_is_gso(skb))
|
||||||
|
return xfrm_output_gso(skb);
|
||||||
|
|
||||||
|
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||||
|
err = skb_checksum_help(skb);
|
||||||
|
if (err) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xfrm_output2(skb);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL_GPL(xfrm_output);
|
EXPORT_SYMBOL_GPL(xfrm_output);
|
||||||
|
|
Loading…
Add table
Reference in a new issue