X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=net%2Fxfrm%2Fxfrm_output.c;h=f4bfd6c4565119f9f3be6cb80547922b930b4f73;hb=9156ad48338e0306e508ead5c0d9986050744475;hp=75f289b488a709f2876afcd9aff16b24e05ff044;hpb=406ef77c893ebd882209be4e393d64b01fe72054;p=powerpc.git diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 75f289b488..f4bfd6c456 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c @@ -14,10 +14,31 @@ #include #include #include -#include #include #include +static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb) +{ + int nhead = x->props.header_len + LL_RESERVED_SPACE(skb->dst->dev) + - skb_headroom(skb); + + if (nhead > 0) + return pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); + + /* Check tail too... */ + return 0; +} + +static int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb) +{ + int err = xfrm_state_check_expire(x); + if (err < 0) + goto err; + err = xfrm_state_check_space(x, skb); +err: + return err; +} + int xfrm_output(struct sk_buff *skb) { struct dst_entry *dst = skb->dst; @@ -36,23 +57,24 @@ int xfrm_output(struct sk_buff *skb) if (err) goto error; - err = x->mode->output(x, skb); - if (err) - goto error; + if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { + XFRM_SKB_CB(skb)->seq = ++x->replay.oseq; + if (xfrm_aevent_is_on()) + xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); + } - err = x->type->output(x, skb); + err = x->outer_mode->output(x, skb); if (err) goto error; x->curlft.bytes += skb->len; x->curlft.packets++; - if (x->props.mode == XFRM_MODE_ROUTEOPTIMIZATION) - x->lastused = get_seconds(); - spin_unlock_bh(&x->lock); - skb_reset_network_header(skb); + err = x->type->output(x, skb); + if (err) + goto error_nolock; if (!(skb->dst = dst_pop(dst))) { err = -EHOSTUNREACH; @@ -60,7 +82,7 @@ int xfrm_output(struct sk_buff *skb) } dst = skb->dst; x = dst->xfrm; - } while (x && (x->props.mode != XFRM_MODE_TUNNEL)); + } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); err = 0;