aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2010-03-01 21:51:56 -0500
committerDavid S. Miller <davem@davemloft.net>2010-03-03 04:04:37 -0500
commit87c1e12b5eeb7b30b4b41291bef8e0b41fc3dde9 (patch)
tree4e30c4d60c21ab5e0346648ed852258a96265288
parent3a5b27bf6f29574d667230c7e76e4b83fe3014e0 (diff)
ipsec: Fix bogus bundle flowi
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>
-rw-r--r--include/net/xfrm.h3
-rw-r--r--net/ipv4/xfrm4_policy.c5
-rw-r--r--net/ipv6/xfrm6_policy.c3
-rw-r--r--net/xfrm/xfrm_policy.c7
4 files changed, 11 insertions, 7 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index a7df3275b860..d74e080ba6c9 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -275,7 +275,8 @@ struct xfrm_policy_afinfo {
275 struct dst_entry *dst, 275 struct dst_entry *dst,
276 int nfheader_len); 276 int nfheader_len);
277 int (*fill_dst)(struct xfrm_dst *xdst, 277 int (*fill_dst)(struct xfrm_dst *xdst,
278 struct net_device *dev); 278 struct net_device *dev,
279 struct flowi *fl);
279}; 280};
280 281
281extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo); 282extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 67107d63c1cd..e4a1483fba77 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -91,11 +91,12 @@ static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
91 return 0; 91 return 0;
92} 92}
93 93
94static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) 94static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
95 struct flowi *fl)
95{ 96{
96 struct rtable *rt = (struct rtable *)xdst->route; 97 struct rtable *rt = (struct rtable *)xdst->route;
97 98
98 xdst->u.rt.fl = rt->fl; 99 xdst->u.rt.fl = *fl;
99 100
100 xdst->u.dst.dev = dev; 101 xdst->u.dst.dev = dev;
101 dev_hold(dev); 102 dev_hold(dev);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index dbdc696f5fc5..ae181651c75a 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -116,7 +116,8 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
116 return 0; 116 return 0;
117} 117}
118 118
119static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) 119static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
120 struct flowi *fl)
120{ 121{
121 struct rt6_info *rt = (struct rt6_info*)xdst->route; 122 struct rt6_info *rt = (struct rt6_info*)xdst->route;
122 123
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 34a5ef8316e7..843e066649cb 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1372,7 +1372,8 @@ static inline int xfrm_init_path(struct xfrm_dst *path, struct dst_entry *dst,
1372 return err; 1372 return err;
1373} 1373}
1374 1374
1375static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) 1375static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
1376 struct flowi *fl)
1376{ 1377{
1377 struct xfrm_policy_afinfo *afinfo = 1378 struct xfrm_policy_afinfo *afinfo =
1378 xfrm_policy_get_afinfo(xdst->u.dst.ops->family); 1379 xfrm_policy_get_afinfo(xdst->u.dst.ops->family);
@@ -1381,7 +1382,7 @@ static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
1381 if (!afinfo) 1382 if (!afinfo)
1382 return -EINVAL; 1383 return -EINVAL;
1383 1384
1384 err = afinfo->fill_dst(xdst, dev); 1385 err = afinfo->fill_dst(xdst, dev, fl);
1385 1386
1386 xfrm_policy_put_afinfo(afinfo); 1387 xfrm_policy_put_afinfo(afinfo);
1387 1388
@@ -1486,7 +1487,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
1486 for (dst_prev = dst0; dst_prev != dst; dst_prev = dst_prev->child) { 1487 for (dst_prev = dst0; dst_prev != dst; dst_prev = dst_prev->child) {
1487 struct xfrm_dst *xdst = (struct xfrm_dst *)dst_prev; 1488 struct xfrm_dst *xdst = (struct xfrm_dst *)dst_prev;
1488 1489
1489 err = xfrm_fill_dst(xdst, dev); 1490 err = xfrm_fill_dst(xdst, dev, fl);
1490 if (err) 1491 if (err)
1491 goto free_dst; 1492 goto free_dst;
1492 1493