diff options
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 13 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 15 |
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 | |||
153 | 153 | ||
154 | dst_prev = *dst_p; | 154 | dst_prev = *dst_p; |
155 | i = 0; | 155 | i = 0; |
156 | err = -ENODEV; | ||
156 | for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { | 157 | for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { |
157 | struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; | 158 | struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; |
158 | x->u.rt.fl = *fl; | 159 | x->u.rt.fl = *fl; |
159 | 160 | ||
160 | dst_prev->xfrm = xfrm[i++]; | 161 | dst_prev->xfrm = xfrm[i++]; |
161 | dst_prev->dev = rt->u.dst.dev; | 162 | dst_prev->dev = rt->u.dst.dev; |
162 | if (rt->u.dst.dev) | 163 | if (!rt->u.dst.dev) |
163 | dev_hold(rt->u.dst.dev); | 164 | goto error; |
165 | dev_hold(rt->u.dst.dev); | ||
166 | |||
167 | x->u.rt.idev = in_dev_get(rt->u.dst.dev); | ||
168 | if (!x->u.rt.idev) | ||
169 | goto error; | ||
170 | |||
164 | dst_prev->obsolete = -1; | 171 | dst_prev->obsolete = -1; |
165 | dst_prev->flags |= DST_HOST; | 172 | dst_prev->flags |= DST_HOST; |
166 | dst_prev->lastuse = jiffies; | 173 | dst_prev->lastuse = jiffies; |
@@ -181,8 +188,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
181 | x->u.rt.rt_dst = rt0->rt_dst; | 188 | x->u.rt.rt_dst = rt0->rt_dst; |
182 | x->u.rt.rt_gateway = rt0->rt_gateway; | 189 | x->u.rt.rt_gateway = rt0->rt_gateway; |
183 | x->u.rt.rt_spec_dst = rt0->rt_spec_dst; | 190 | x->u.rt.rt_spec_dst = rt0->rt_spec_dst; |
184 | x->u.rt.idev = rt0->idev; | ||
185 | in_dev_hold(rt0->idev); | ||
186 | header_len -= x->u.dst.xfrm->props.header_len; | 191 | header_len -= x->u.dst.xfrm->props.header_len; |
187 | trailer_len -= x->u.dst.xfrm->props.trailer_len; | 192 | trailer_len -= x->u.dst.xfrm->props.trailer_len; |
188 | } | 193 | } |
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 | |||
123 | } | 123 | } |
124 | }; | 124 | }; |
125 | int i; | 125 | int i; |
126 | int err = 0; | 126 | int err; |
127 | int header_len = 0; | 127 | int header_len = 0; |
128 | int trailer_len = 0; | 128 | int trailer_len = 0; |
129 | 129 | ||
@@ -201,13 +201,20 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
201 | 201 | ||
202 | dst_prev = *dst_p; | 202 | dst_prev = *dst_p; |
203 | i = 0; | 203 | i = 0; |
204 | err = -ENODEV; | ||
204 | for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { | 205 | for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { |
205 | struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; | 206 | struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; |
206 | 207 | ||
207 | dst_prev->xfrm = xfrm[i++]; | 208 | dst_prev->xfrm = xfrm[i++]; |
208 | dst_prev->dev = rt->u.dst.dev; | 209 | dst_prev->dev = rt->u.dst.dev; |
209 | if (rt->u.dst.dev) | 210 | if (!rt->u.dst.dev) |
210 | dev_hold(rt->u.dst.dev); | 211 | goto error; |
212 | dev_hold(rt->u.dst.dev); | ||
213 | |||
214 | x->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev); | ||
215 | if (!x->u.rt6.rt6i_idev) | ||
216 | goto error; | ||
217 | |||
211 | dst_prev->obsolete = -1; | 218 | dst_prev->obsolete = -1; |
212 | dst_prev->flags |= DST_HOST; | 219 | dst_prev->flags |= DST_HOST; |
213 | dst_prev->lastuse = jiffies; | 220 | dst_prev->lastuse = jiffies; |
@@ -226,8 +233,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
226 | memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); | 233 | memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); |
227 | x->u.rt6.rt6i_dst = rt0->rt6i_dst; | 234 | x->u.rt6.rt6i_dst = rt0->rt6i_dst; |
228 | x->u.rt6.rt6i_src = rt0->rt6i_src; | 235 | x->u.rt6.rt6i_src = rt0->rt6i_src; |
229 | x->u.rt6.rt6i_idev = rt0->rt6i_idev; | ||
230 | in6_dev_hold(rt0->rt6i_idev); | ||
231 | header_len -= x->u.dst.xfrm->props.header_len; | 236 | header_len -= x->u.dst.xfrm->props.header_len; |
232 | trailer_len -= x->u.dst.xfrm->props.trailer_len; | 237 | trailer_len -= x->u.dst.xfrm->props.trailer_len; |
233 | } | 238 | } |