Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 78106
b: refs/heads/master
c: c6581a4
h: refs/heads/master
v: v3
  • Loading branch information
Herbert Xu authored and David S. Miller committed Jan 28, 2008
1 parent 0bf6587 commit 798cffa
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 862b82c6f960cc61274d370aa78ce1112f92a83e
refs/heads/master: c6581a457e661b7070e484ad723bbf555b17aca2
1 change: 1 addition & 0 deletions trunk/include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_init_state(struct xfrm_state *x);
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 xfrm4_extract_header(struct sk_buff *skb);
extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
Expand Down
57 changes: 40 additions & 17 deletions trunk/net/xfrm/xfrm_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <net/dst.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)
{
struct dst_entry *dst = skb->dst;
Expand All @@ -41,17 +43,13 @@ static int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb)
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 xfrm_state *x = dst->xfrm;
int err;

if (skb->ip_summed == CHECKSUM_PARTIAL) {
err = skb_checksum_help(skb);
if (err)
goto error_nolock;
}
if (err <= 0)
goto resume;

do {
err = x->outer_mode->output(x, skb);
Expand All @@ -75,6 +73,8 @@ static int xfrm_output_one(struct sk_buff *skb)
spin_unlock_bh(&x->lock);

err = x->type->output(x, skb);

resume:
if (err)
goto error_nolock;

Expand All @@ -97,18 +97,16 @@ static int xfrm_output_one(struct sk_buff *skb)
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)) == 0)) {
while (likely((err = xfrm_output_one(skb, err)) == 0)) {
struct xfrm_state *x;

nf_reset(skb);

err = skb->dst->ops->local_out(skb);
if (unlikely(err != 1))
break;
goto out;

x = skb->dst->xfrm;
if (!x)
Expand All @@ -118,18 +116,25 @@ static int xfrm_output2(struct sk_buff *skb)
x->inner_mode->afinfo->nf_post_routing, skb,
NULL, skb->dst->dev, xfrm_output2);
if (unlikely(err != 1))
break;
goto out;
}

if (err == -EINPROGRESS)
err = 0;

out:
return err;
}
EXPORT_SYMBOL_GPL(xfrm_output_resume);

int xfrm_output(struct sk_buff *skb)
static int xfrm_output2(struct sk_buff *skb)
{
struct sk_buff *segs;
return xfrm_output_resume(skb, 1);
}

if (!skb_is_gso(skb))
return xfrm_output2(skb);
static int xfrm_output_gso(struct sk_buff *skb)
{
struct sk_buff *segs;

segs = skb_gso_segment(skb, 0);
kfree_skb(skb);
Expand Down Expand Up @@ -157,4 +162,22 @@ int xfrm_output(struct sk_buff *skb)

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);

0 comments on commit 798cffa

Please sign in to comment.