aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/xfrm4_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/xfrm4_policy.c')
-rw-r--r--net/ipv4/xfrm4_policy.c27
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}