netdev
[Top] [All Lists]

Re: [PATCH 3/3 XFRM]: Fix invalid key for lookup of cached bundles

To: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Subject: Re: [PATCH 3/3 XFRM]: Fix invalid key for lookup of cached bundles
From: Patrick McHardy <kaber@xxxxxxxxx>
Date: Sun, 06 Mar 2005 13:34:24 +0100
Cc: davem@xxxxxxxxxxxxx, netdev@xxxxxxxxxxx
In-reply-to: <E1D7t0w-0008Qa-00@gondolin.me.apana.org.au>
References: <E1D7t0w-0008Qa-00@gondolin.me.apana.org.au>
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.5) Gecko/20050106 Debian/1.7.5-1
Herbert Xu wrote:
Patrick McHardy <kaber@xxxxxxxxx> wrote:

@@ -97,6 +104,7 @@
                err = xfrm_dst_lookup((struct xfrm_dst**)&rt, &fl_tunnel, 
AF_INET);
                if (err)
                        goto error;
+               rt->u.dst.flags |= DST_XFRM_TUNNEL;


This line doesn't look right.  rt is an entry in the IPv4 routing
cache, right? If so why should its flags change when some bundle is
created?

How about this one ? It keeps the DST_XFRM_TUNNEL flag and sets it on the first xfrm_dst in a bundle. I know it doesn't really belong there, but the alternatives are walking through the bundle an additional time or having xfrm_bundle_ok() return if it is a tunnel-mode bundle, but in that case we can only compare tos etc after the call to xfrm_bundle_ok(), which is rather expensive. I also moved the oif check to the checks performed only in transport mode, this reduces the number of cached bundles in tunnel mode to one per src/dst if the selector isn't narrower than that.

Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
===== include/net/dst.h 1.26 vs edited =====
--- 1.26/include/net/dst.h      2005-02-15 23:23:10 +01:00
+++ edited/include/net/dst.h    2005-03-06 12:50:54 +01:00
@@ -48,6 +48,7 @@
 #define DST_NOXFRM             2
 #define DST_NOPOLICY           4
 #define DST_NOHASH             8
+#define DST_XFRM_TUNNEL                16
        unsigned long           lastuse;
        unsigned long           expires;
 
===== net/ipv4/xfrm4_policy.c 1.15 vs edited =====
--- 1.15/net/ipv4/xfrm4_policy.c        2005-03-05 01:58:41 +01:00
+++ edited/net/ipv4/xfrm4_policy.c      2005-03-06 13:26:44 +01:00
@@ -30,9 +30,15 @@
        read_lock_bh(&policy->lock);
        for (dst = policy->bundles; dst; dst = dst->next) {
                struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
-               if (xdst->u.rt.fl.oif == fl->oif &&     /*XXX*/
-                   xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
+               if (xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
                    xdst->u.rt.fl.fl4_src == fl->fl4_src &&
+                   (dst->flags & DST_XFRM_TUNNEL ||
+                    (!(xdst->u.rt.fl.fl4_tos ^ fl->fl4_tos) & 
+                                 (IPTOS_RT_MASK|RTO_ONLINK) &&
+#ifdef CONFIG_IP_ROUTE_FWMARK
+                     xdst->u.rt.fl.fl4_fwmark == fl->fl4_fwmark &&
+#endif
+                     xdst->u.rt.fl.oif == fl->oif)) &&
                    xfrm_bundle_ok(xdst, fl, AF_INET)) {
                        dst_clone(dst);
                        break;
@@ -97,6 +103,7 @@
                err = xfrm_dst_lookup((struct xfrm_dst**)&rt, &fl_tunnel, 
AF_INET);
                if (err)
                        goto error;
+               dst->flags |= DST_XFRM_TUNNEL;
        } else {
                dst_hold(&rt->u.dst);
        }
<Prev in Thread] Current Thread [Next in Thread>