]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ipsec: Fix bogus bundle flowi
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 2 Mar 2010 02:51:56 +0000 (02:51 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 1 Apr 2010 23:02:06 +0000 (16:02 -0700)
[ Upstream commit 87c1e12b5eeb7b30b4b41291bef8e0b41fc3dde9 ]

When I merged the bundle creation code, I introduced a bogus
flowi value in the bundle.  Instead of getting from the caller,
it was instead set to the flow in the route object, which is
totally different.

The end result is that the bundles we created never match, and
we instead end up with an ever growing bundle list.

Thanks to Jamal for find this problem.

Reported-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: Steffen Klassert <steffen.klassert@secunet.com>
Acked-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
include/net/xfrm.h
net/ipv4/xfrm4_policy.c
net/ipv6/xfrm6_policy.c
net/xfrm/xfrm_policy.c

index 60c27706e7b99fcce2d7df451564ae4569d394f4..1e355d8c8530c8658d3adcdbfad27b51cd140cc5 100644 (file)
@@ -274,7 +274,8 @@ struct xfrm_policy_afinfo {
                                             struct dst_entry *dst,
                                             int nfheader_len);
        int                     (*fill_dst)(struct xfrm_dst *xdst,
-                                           struct net_device *dev);
+                                           struct net_device *dev,
+                                           struct flowi *fl);
 };
 
 extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
index 67107d63c1cd5318545aebe0072459bf0869fba3..e4a1483fba7776b3df5a9008967f5dc5a7c4b558 100644 (file)
@@ -91,11 +91,12 @@ static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
        return 0;
 }
 
-static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+                         struct flowi *fl)
 {
        struct rtable *rt = (struct rtable *)xdst->route;
 
-       xdst->u.rt.fl = rt->fl;
+       xdst->u.rt.fl = *fl;
 
        xdst->u.dst.dev = dev;
        dev_hold(dev);
index dbdc696f5fc5b5fbc207b48135fa768028f7e7f4..ae181651c75a82d32fdb6596068e3bb5c7839740 100644 (file)
@@ -116,7 +116,8 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
        return 0;
 }
 
-static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+                         struct flowi *fl)
 {
        struct rt6_info *rt = (struct rt6_info*)xdst->route;
 
index 0ecb16a9a8831b9c145a3db4d2e142331061d776..f12dd3d885206412be29e1df4e510f6a3b5b147c 100644 (file)
@@ -1354,7 +1354,8 @@ static inline int xfrm_init_path(struct xfrm_dst *path, struct dst_entry *dst,
        return err;
 }
 
-static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+                               struct flowi *fl)
 {
        struct xfrm_policy_afinfo *afinfo =
                xfrm_policy_get_afinfo(xdst->u.dst.ops->family);
@@ -1363,7 +1364,7 @@ static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
        if (!afinfo)
                return -EINVAL;
 
-       err = afinfo->fill_dst(xdst, dev);
+       err = afinfo->fill_dst(xdst, dev, fl);
 
        xfrm_policy_put_afinfo(afinfo);
 
@@ -1468,7 +1469,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
        for (dst_prev = dst0; dst_prev != dst; dst_prev = dst_prev->child) {
                struct xfrm_dst *xdst = (struct xfrm_dst *)dst_prev;
 
-               err = xfrm_fill_dst(xdst, dev);
+               err = xfrm_fill_dst(xdst, dev, fl);
                if (err)
                        goto free_dst;