Hi Dave: I posted this patch in an earlier thread but it seems to have been lost. Currently the SA selector check is always done with the details of the inner packet. This will break scenarios like nested tunnels as the outer tunnel's selector may be more restrictive. Cheers, -- Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ ) Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Index: kernel-source-2.5/net/xfrm/xfrm_policy.c =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/xfrm/xfrm_policy.c,v retrieving revision 1.9 diff -u -r1.9 xfrm_policy.c --- kernel-source-2.5/net/xfrm/xfrm_policy.c 20 Jun 2003 11:49:08 -0000 1.9 +++ kernel-source-2.5/net/xfrm/xfrm_policy.c 28 Jun 2003 07:32:41 -0000 @@ -866,19 +866,30 @@ /* First, check used SA against their selectors. */ if (skb->sp) { + struct flowi xfl; int i; + memcpy(&xfl, &fl, sizeof(xfl)); for (i=skb->sp->len-1; i>=0; i--) { - struct sec_decap_state *xvec = &(skb->sp->x[i]); - if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) + struct sec_decap_state *xvec = &(skb->sp->x[i]); + struct xfrm_state *x = xvec->xvec; + xfrm_address_t *saddr, *daddr; + + if (!xfrm_selector_match(&x->sel, &xfl, family)) return 0; /* If there is a post_input processor, try running it */ - if (xvec->xvec->type->post_input && - (xvec->xvec->type->post_input)(xvec->xvec, - &(xvec->decap), - skb) != 0) + if (x->type->post_input && + (x->type->post_input)(x, &(xvec->decap), skb) != 0) return 0; + + memset(&xfl, 0, sizeof(xfl)); + xfl.fl_ipsec_spi = x->id.spi; + xfl.proto = x->id.proto; + saddr = xfrm_flowi_saddr(&xfl, x->props.family); + daddr = xfrm_flowi_daddr(&xfl, x->props.family); + memcpy(daddr, &x->id.daddr, sizeof(*daddr)); + memcpy(saddr, &x->props.saddr, sizeof(*saddr)); } }