Commit cc8d308c authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[XFRM]: Always reroute in tunnel mode

Tunnel mode packets are rerouted if the tunnel destination
address is different from the original destination address,
otherwise the old route is used. This is inconsistent, the
old route might have been selected for a given output device
or using routing by tos/fwmark. Always choose a new route
in tunnel mode.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 54060547
...@@ -74,6 +74,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -74,6 +74,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
for (i = 0; i < nx; i++) { for (i = 0; i < nx; i++) {
struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops); struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops);
struct xfrm_dst *xdst; struct xfrm_dst *xdst;
int tunnel = 0;
if (unlikely(dst1 == NULL)) { if (unlikely(dst1 == NULL)) {
err = -ENOBUFS; err = -ENOBUFS;
...@@ -97,11 +98,12 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -97,11 +98,12 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
if (xfrm[i]->props.mode) { if (xfrm[i]->props.mode) {
remote = xfrm[i]->id.daddr.a4; remote = xfrm[i]->id.daddr.a4;
local = xfrm[i]->props.saddr.a4; local = xfrm[i]->props.saddr.a4;
tunnel = 1;
} }
header_len += xfrm[i]->props.header_len; header_len += xfrm[i]->props.header_len;
trailer_len += xfrm[i]->props.trailer_len; trailer_len += xfrm[i]->props.trailer_len;
if (remote != fl_tunnel.fl4_dst) { if (tunnel) {
fl_tunnel.fl4_src = local; fl_tunnel.fl4_src = local;
fl_tunnel.fl4_dst = remote; fl_tunnel.fl4_dst = remote;
err = xfrm_dst_lookup((struct xfrm_dst **)&rt, err = xfrm_dst_lookup((struct xfrm_dst **)&rt,
......
...@@ -91,6 +91,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -91,6 +91,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
for (i = 0; i < nx; i++) { for (i = 0; i < nx; i++) {
struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops); struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops);
struct xfrm_dst *xdst; struct xfrm_dst *xdst;
int tunnel = 0;
if (unlikely(dst1 == NULL)) { if (unlikely(dst1 == NULL)) {
err = -ENOBUFS; err = -ENOBUFS;
...@@ -114,11 +115,12 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -114,11 +115,12 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
if (xfrm[i]->props.mode) { if (xfrm[i]->props.mode) {
remote = (struct in6_addr*)&xfrm[i]->id.daddr; remote = (struct in6_addr*)&xfrm[i]->id.daddr;
local = (struct in6_addr*)&xfrm[i]->props.saddr; local = (struct in6_addr*)&xfrm[i]->props.saddr;
tunnel = 1;
} }
header_len += xfrm[i]->props.header_len; header_len += xfrm[i]->props.header_len;
trailer_len += xfrm[i]->props.trailer_len; trailer_len += xfrm[i]->props.trailer_len;
if (!ipv6_addr_equal(remote, &fl_tunnel.fl6_dst)) { if (tunnel) {
ipv6_addr_copy(&fl_tunnel.fl6_dst, remote); ipv6_addr_copy(&fl_tunnel.fl6_dst, remote);
ipv6_addr_copy(&fl_tunnel.fl6_src, local); ipv6_addr_copy(&fl_tunnel.fl6_src, local);
err = xfrm_dst_lookup((struct xfrm_dst **) &rt, err = xfrm_dst_lookup((struct xfrm_dst **) &rt,
......
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