Skip to content

Commit

Permalink
[IPSEC]: Add async resume support on input
Browse files Browse the repository at this point in the history
This patch adds support for async resumptions on input.  To do so, the
transform would return -EINPROGRESS and subsequently invoke the
function xfrm_input_resume to resume processing.

Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
herbertx authored and davem330 committed Jan 28, 2008
1 parent 60d5fcf commit 1bf06cd
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,7 @@ 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_input(struct sk_buff *skb, int nexthdr, __be32 spi,
int encap_type);
extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
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);
Expand Down
3 changes: 3 additions & 0 deletions net/ipv4/xfrm4_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
xfrm4_rcv_encap_finish);
return 0;
#else
if (async)
return xfrm4_rcv_encap_finish(skb);

return -iph->protocol;
#endif
}
Expand Down
3 changes: 3 additions & 0 deletions net/ipv6/xfrm6_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
ip6_rcv_finish);
return -1;
#else
if (async)
return ip6_rcv_finish(skb);

return 1;
#endif
}
Expand Down
38 changes: 33 additions & 5 deletions net/xfrm/xfrm_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,17 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
int err;
__be32 seq;
struct xfrm_state *x;
xfrm_address_t *daddr;
int decaps = 0;
unsigned int daddroff = XFRM_SPI_SKB_CB(skb)->daddroff;
int async = 0;

/* A negative encap_type indicates async resumption. */
if (encap_type < 0) {
async = 1;
x = skb->sp->xvec[skb->sp->len - 1];
seq = XFRM_SKB_CB(skb)->seq;
goto resume;
}

/* Allocate new secpath or COW existing one. */
if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
Expand All @@ -116,6 +125,9 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
skb->sp = sp;
}

daddr = (xfrm_address_t *)(skb_network_header(skb) +
XFRM_SPI_SKB_CB(skb)->daddroff);

seq = 0;
if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
goto drop;
Expand All @@ -124,9 +136,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
if (skb->sp->len == XFRM_MAX_DEPTH)
goto drop;

x = xfrm_state_lookup((xfrm_address_t *)
(skb_network_header(skb) + daddroff),
spi, nexthdr, AF_INET);
x = xfrm_state_lookup(daddr, spi, nexthdr, AF_INET);
if (x == NULL)
goto drop;

Expand All @@ -147,8 +157,14 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)

spin_unlock(&x->lock);

XFRM_SKB_CB(skb)->seq = seq;

nexthdr = x->type->input(x, skb);

if (nexthdr == -EINPROGRESS)
return 0;

resume:
spin_lock(&x->lock);
if (nexthdr <= 0) {
if (nexthdr == -EBADMSG)
Expand Down Expand Up @@ -177,6 +193,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
break;
}

/*
* We need the inner address. However, we only get here for
* transport mode so the outer address is identical.
*/
daddr = &x->id.daddr;

err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
if (err < 0)
goto drop;
Expand All @@ -190,7 +212,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
netif_rx(skb);
return 0;
} else {
return x->inner_mode->afinfo->transport_finish(skb, 0);
return x->inner_mode->afinfo->transport_finish(skb, async);
}

drop_unlock:
Expand All @@ -201,6 +223,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
}
EXPORT_SYMBOL(xfrm_input);

int xfrm_input_resume(struct sk_buff *skb, int nexthdr)
{
return xfrm_input(skb, nexthdr, 0, -1);
}
EXPORT_SYMBOL(xfrm_input_resume);

void __init xfrm_input_init(void)
{
secpath_cachep = kmem_cache_create("secpath_cache",
Expand Down

0 comments on commit 1bf06cd

Please sign in to comment.