On Tue, Jul 01, 2003 at 12:01:17AM -0700, David S. Miller wrote: > > Ugh, can you implement this more cleanly possibly? > > All of this struct flow copying/clearing/etc. on EVERY PACKET > is totally unacceptable. Struct flow is huge and it's bad enough > that we have to build one of them each input event. Sure. In fact, checking anything apart from the inner SA is pointless since whoever added the policy check would've presumably carried out that check already. So here is the new patch which only checks the inner-most SA. -- 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 1 Jul 2003 09:58:53 -0000 @@ -866,19 +866,23 @@ /* First, check used SA against their selectors. */ if (skb->sp) { - int i; + int i = skb->sp->len - 1; + struct sec_decap_state *xvec = skb->sp->x + i; + struct xfrm_state *x = xvec->xvec; - 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)) - return 0; + if (!xfrm_selector_match(&x->sel, &fl, family)) + return 0; + for (;;) { /* 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; + + if (--i < 0) + break; + xvec--; + x = xvec->xvec; } }