diff options
author | Paolo Abeni <pabeni@redhat.com> | 2016-11-16 10:26:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-17 12:08:56 -0500 |
commit | b5c2d49544e5930c96e2632a7eece3f4325a1888 (patch) | |
tree | 47308967f61f4da7e80a1fcfc5ddc19a78b73a63 | |
parent | 30563f933a27eb9f9391a0e531dffde5182e422a (diff) |
ip6_tunnel: disable caching when the traffic class is inherited
If an ip6 tunnel is configured to inherit the traffic class from
the inner header, the dst_cache must be disabled or it will foul
the policy routing.
The issue is apprently there since at leat Linux-2.6.12-rc2.
Reported-by: Liam McBirnie <liam.mcbirnie@boeing.com>
Cc: Liam McBirnie <liam.mcbirnie@boeing.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 87784560dc46..0a4759b89da2 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1034,6 +1034,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, | |||
1034 | int mtu; | 1034 | int mtu; |
1035 | unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen; | 1035 | unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen; |
1036 | unsigned int max_headroom = psh_hlen; | 1036 | unsigned int max_headroom = psh_hlen; |
1037 | bool use_cache = false; | ||
1037 | u8 hop_limit; | 1038 | u8 hop_limit; |
1038 | int err = -1; | 1039 | int err = -1; |
1039 | 1040 | ||
@@ -1066,7 +1067,15 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, | |||
1066 | 1067 | ||
1067 | memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); | 1068 | memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); |
1068 | neigh_release(neigh); | 1069 | neigh_release(neigh); |
1069 | } else if (!fl6->flowi6_mark) | 1070 | } else if (!(t->parms.flags & |
1071 | (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) { | ||
1072 | /* enable the cache only only if the routing decision does | ||
1073 | * not depend on the current inner header value | ||
1074 | */ | ||
1075 | use_cache = true; | ||
1076 | } | ||
1077 | |||
1078 | if (use_cache) | ||
1070 | dst = dst_cache_get(&t->dst_cache); | 1079 | dst = dst_cache_get(&t->dst_cache); |
1071 | 1080 | ||
1072 | if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) | 1081 | if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) |
@@ -1150,7 +1159,7 @@ route_lookup: | |||
1150 | if (t->encap.type != TUNNEL_ENCAP_NONE) | 1159 | if (t->encap.type != TUNNEL_ENCAP_NONE) |
1151 | goto tx_err_dst_release; | 1160 | goto tx_err_dst_release; |
1152 | } else { | 1161 | } else { |
1153 | if (!fl6->flowi6_mark && ndst) | 1162 | if (use_cache && ndst) |
1154 | dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr); | 1163 | dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr); |
1155 | } | 1164 | } |
1156 | skb_dst_set(skb, dst); | 1165 | skb_dst_set(skb, dst); |