Commit 37dedf02 authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[IPSEC]: Fix ref counting in __xfrmN_bundle_create().

parent bc368e8f
...@@ -90,7 +90,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -90,7 +90,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
goto error; goto error;
} }
dst1->xfrm = xfrm[i];
if (!dst) if (!dst)
dst = dst1; dst = dst1;
else { else {
...@@ -120,10 +119,12 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -120,10 +119,12 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
dst_hold(&rt->u.dst); dst_hold(&rt->u.dst);
} }
dst_prev->child = &rt->u.dst; dst_prev->child = &rt->u.dst;
i = 0;
for (dst_prev = dst; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { for (dst_prev = dst; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
x->u.rt.fl = *fl; x->u.rt.fl = *fl;
dst_prev->xfrm = xfrm[i++];
dst_prev->dev = rt->u.dst.dev; dst_prev->dev = rt->u.dst.dev;
if (rt->u.dst.dev) if (rt->u.dst.dev)
dev_hold(rt->u.dst.dev); dev_hold(rt->u.dst.dev);
......
...@@ -107,7 +107,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -107,7 +107,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
goto error; goto error;
} }
dst1->xfrm = xfrm[i];
if (!dst) if (!dst)
dst = dst1; dst = dst1;
else { else {
...@@ -139,9 +138,11 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -139,9 +138,11 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
dst_hold(&rt->u.dst); dst_hold(&rt->u.dst);
} }
dst_prev->child = &rt->u.dst; dst_prev->child = &rt->u.dst;
i = 0;
for (dst_prev = dst; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { for (dst_prev = dst; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
dst_prev->xfrm = xfrm[i++];
dst_prev->dev = rt->u.dst.dev; dst_prev->dev = rt->u.dst.dev;
if (rt->u.dst.dev) if (rt->u.dst.dev)
dev_hold(rt->u.dst.dev); dev_hold(rt->u.dst.dev);
......
...@@ -1017,6 +1017,8 @@ static int stale_bundle(struct dst_entry *dst) ...@@ -1017,6 +1017,8 @@ static int stale_bundle(struct dst_entry *dst)
static void xfrm_dst_destroy(struct dst_entry *dst) static void xfrm_dst_destroy(struct dst_entry *dst)
{ {
if (!dst->xfrm)
return;
xfrm_state_put(dst->xfrm); xfrm_state_put(dst->xfrm);
dst->xfrm = NULL; dst->xfrm = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment