summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/xfrm4_policy.c13
-rw-r--r--net/ipv6/xfrm6_policy.c15
2 files changed, 19 insertions, 9 deletions
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index c40a71b74dba..d903c8bdffcd 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -153,14 +153,21 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
dst_prev = *dst_p;
i = 0;
+ err = -ENODEV;
for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
x->u.rt.fl = *fl;
dst_prev->xfrm = xfrm[i++];
dst_prev->dev = rt->u.dst.dev;
- if (rt->u.dst.dev)
- dev_hold(rt->u.dst.dev);
+ if (!rt->u.dst.dev)
+ goto error;
+ dev_hold(rt->u.dst.dev);
+
+ x->u.rt.idev = in_dev_get(rt->u.dst.dev);
+ if (!x->u.rt.idev)
+ goto error;
+
dst_prev->obsolete = -1;
dst_prev->flags |= DST_HOST;
dst_prev->lastuse = jiffies;
@@ -181,8 +188,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
x->u.rt.rt_dst = rt0->rt_dst;
x->u.rt.rt_gateway = rt0->rt_gateway;
x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
- x->u.rt.idev = rt0->idev;
- in_dev_hold(rt0->idev);
header_len -= x->u.dst.xfrm->props.header_len;
trailer_len -= x->u.dst.xfrm->props.trailer_len;
}
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 89432279d3a0..77dc3651437e 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -123,7 +123,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
}
};
int i;
- int err = 0;
+ int err;
int header_len = 0;
int trailer_len = 0;
@@ -201,13 +201,20 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
dst_prev = *dst_p;
i = 0;
+ err = -ENODEV;
for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
dst_prev->xfrm = xfrm[i++];
dst_prev->dev = rt->u.dst.dev;
- if (rt->u.dst.dev)
- dev_hold(rt->u.dst.dev);
+ if (!rt->u.dst.dev)
+ goto error;
+ dev_hold(rt->u.dst.dev);
+
+ x->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev);
+ if (!x->u.rt6.rt6i_idev)
+ goto error;
+
dst_prev->obsolete = -1;
dst_prev->flags |= DST_HOST;
dst_prev->lastuse = jiffies;
@@ -226,8 +233,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway));
x->u.rt6.rt6i_dst = rt0->rt6i_dst;
x->u.rt6.rt6i_src = rt0->rt6i_src;
- x->u.rt6.rt6i_idev = rt0->rt6i_idev;
- in6_dev_hold(rt0->rt6i_idev);
header_len -= x->u.dst.xfrm->props.header_len;
trailer_len -= x->u.dst.xfrm->props.trailer_len;
}