diff options
Diffstat (limited to 'net/ipv4/xfrm4_policy.c')
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 27 |
1 files changed, 8 insertions, 19 deletions
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 329825ca68fe..cc86fb110dd8 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -117,7 +117,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
117 | header_len += xfrm[i]->props.header_len; | 117 | header_len += xfrm[i]->props.header_len; |
118 | trailer_len += xfrm[i]->props.trailer_len; | 118 | trailer_len += xfrm[i]->props.trailer_len; |
119 | 119 | ||
120 | if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) { | 120 | if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { |
121 | unsigned short encap_family = xfrm[i]->props.family; | 121 | unsigned short encap_family = xfrm[i]->props.family; |
122 | switch (encap_family) { | 122 | switch (encap_family) { |
123 | case AF_INET: | 123 | case AF_INET: |
@@ -151,7 +151,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
151 | i = 0; | 151 | i = 0; |
152 | for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { | 152 | for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { |
153 | struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; | 153 | struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; |
154 | struct xfrm_state_afinfo *afinfo; | ||
155 | x->u.rt.fl = *fl; | 154 | x->u.rt.fl = *fl; |
156 | 155 | ||
157 | dst_prev->xfrm = xfrm[i++]; | 156 | dst_prev->xfrm = xfrm[i++]; |
@@ -169,27 +168,17 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
169 | /* Copy neighbout for reachability confirmation */ | 168 | /* Copy neighbout for reachability confirmation */ |
170 | dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); | 169 | dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); |
171 | dst_prev->input = rt->u.dst.input; | 170 | dst_prev->input = rt->u.dst.input; |
172 | /* XXX: When IPv6 module can be unloaded, we should manage reference | 171 | dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output; |
173 | * to xfrm6_output in afinfo->output. Miyazawa | 172 | if (rt0->peer) |
174 | * */ | 173 | atomic_inc(&rt0->peer->refcnt); |
175 | afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family); | 174 | x->u.rt.peer = rt0->peer; |
176 | if (!afinfo) { | ||
177 | dst = *dst_p; | ||
178 | err = -EAFNOSUPPORT; | ||
179 | goto error; | ||
180 | } | ||
181 | dst_prev->output = afinfo->output; | ||
182 | xfrm_state_put_afinfo(afinfo); | ||
183 | if (dst_prev->xfrm->props.family == AF_INET && rt->peer) | ||
184 | atomic_inc(&rt->peer->refcnt); | ||
185 | x->u.rt.peer = rt->peer; | ||
186 | /* Sheit... I remember I did this right. Apparently, | 175 | /* Sheit... I remember I did this right. Apparently, |
187 | * it was magically lost, so this code needs audit */ | 176 | * it was magically lost, so this code needs audit */ |
188 | x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); | 177 | x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); |
189 | x->u.rt.rt_type = rt->rt_type; | 178 | x->u.rt.rt_type = rt0->rt_type; |
190 | x->u.rt.rt_src = rt0->rt_src; | 179 | x->u.rt.rt_src = rt0->rt_src; |
191 | x->u.rt.rt_dst = rt0->rt_dst; | 180 | x->u.rt.rt_dst = rt0->rt_dst; |
192 | x->u.rt.rt_gateway = rt->rt_gateway; | 181 | x->u.rt.rt_gateway = rt0->rt_gateway; |
193 | x->u.rt.rt_spec_dst = rt0->rt_spec_dst; | 182 | x->u.rt.rt_spec_dst = rt0->rt_spec_dst; |
194 | x->u.rt.idev = rt0->idev; | 183 | x->u.rt.idev = rt0->idev; |
195 | in_dev_hold(rt0->idev); | 184 | in_dev_hold(rt0->idev); |
@@ -291,7 +280,7 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) | |||
291 | 280 | ||
292 | if (likely(xdst->u.rt.idev)) | 281 | if (likely(xdst->u.rt.idev)) |
293 | in_dev_put(xdst->u.rt.idev); | 282 | in_dev_put(xdst->u.rt.idev); |
294 | if (dst->xfrm && dst->xfrm->props.family == AF_INET && likely(xdst->u.rt.peer)) | 283 | if (likely(xdst->u.rt.peer)) |
295 | inet_putpeer(xdst->u.rt.peer); | 284 | inet_putpeer(xdst->u.rt.peer); |
296 | xfrm_dst_destroy(xdst); | 285 | xfrm_dst_destroy(xdst); |
297 | } | 286 | } |