aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Russell <brussell@brocade.com>2017-02-24 12:47:11 -0500
committerDavid S. Miller <davem@davemloft.net>2017-02-24 13:36:24 -0500
commit1158632b5a2dcce0786c1b1b99654e81cc867981 (patch)
tree26189ec44a8a0f60e880985a9bfb7fc1c3b89896
parent7dcdf941cdc96692ab99fd790c8cc68945514851 (diff)
vxlan: don't allow overwrite of config src addr
When using IPv6 transport and a default dst, a pointer to the configured source address is passed into the route lookup. If no source address is configured, then the value is overwritten. IPv6 route lookup ignores egress ifindex match if the source address is set, so if egress ifindex match is desired, the source address must be passed as any. The overwrite breaks this for subsequent lookups. Avoid this by copying the configured address to an existing stack variable and pass a pointer to that instead. Fixes: 272d96a5ab10 ("net: vxlan: lwt: Use source ip address during route lookup.") Signed-off-by: Brian Russell <brussell@brocade.com> Acked-by: Jiri Benc <jbenc@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/vxlan.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 268c2a12e61d..b7911994112a 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2035,7 +2035,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2035 const struct iphdr *old_iph = ip_hdr(skb); 2035 const struct iphdr *old_iph = ip_hdr(skb);
2036 union vxlan_addr *dst; 2036 union vxlan_addr *dst;
2037 union vxlan_addr remote_ip, local_ip; 2037 union vxlan_addr remote_ip, local_ip;
2038 union vxlan_addr *src;
2039 struct vxlan_metadata _md; 2038 struct vxlan_metadata _md;
2040 struct vxlan_metadata *md = &_md; 2039 struct vxlan_metadata *md = &_md;
2041 __be16 src_port = 0, dst_port; 2040 __be16 src_port = 0, dst_port;
@@ -2062,7 +2061,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2062 2061
2063 dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port; 2062 dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
2064 vni = (rdst->remote_vni) ? : default_vni; 2063 vni = (rdst->remote_vni) ? : default_vni;
2065 src = &vxlan->cfg.saddr; 2064 local_ip = vxlan->cfg.saddr;
2066 dst_cache = &rdst->dst_cache; 2065 dst_cache = &rdst->dst_cache;
2067 md->gbp = skb->mark; 2066 md->gbp = skb->mark;
2068 ttl = vxlan->cfg.ttl; 2067 ttl = vxlan->cfg.ttl;
@@ -2095,7 +2094,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2095 dst = &remote_ip; 2094 dst = &remote_ip;
2096 dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port; 2095 dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
2097 vni = tunnel_id_to_key32(info->key.tun_id); 2096 vni = tunnel_id_to_key32(info->key.tun_id);
2098 src = &local_ip;
2099 dst_cache = &info->dst_cache; 2097 dst_cache = &info->dst_cache;
2100 if (info->options_len) 2098 if (info->options_len)
2101 md = ip_tunnel_info_opts(info); 2099 md = ip_tunnel_info_opts(info);
@@ -2115,7 +2113,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2115 rt = vxlan_get_route(vxlan, dev, sock4, skb, 2113 rt = vxlan_get_route(vxlan, dev, sock4, skb,
2116 rdst ? rdst->remote_ifindex : 0, tos, 2114 rdst ? rdst->remote_ifindex : 0, tos,
2117 dst->sin.sin_addr.s_addr, 2115 dst->sin.sin_addr.s_addr,
2118 &src->sin.sin_addr.s_addr, 2116 &local_ip.sin.sin_addr.s_addr,
2119 dst_port, src_port, 2117 dst_port, src_port,
2120 dst_cache, info); 2118 dst_cache, info);
2121 if (IS_ERR(rt)) { 2119 if (IS_ERR(rt)) {
@@ -2142,7 +2140,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2142 if (err < 0) 2140 if (err < 0)
2143 goto tx_error; 2141 goto tx_error;
2144 2142
2145 udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, src->sin.sin_addr.s_addr, 2143 udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, local_ip.sin.sin_addr.s_addr,
2146 dst->sin.sin_addr.s_addr, tos, ttl, df, 2144 dst->sin.sin_addr.s_addr, tos, ttl, df,
2147 src_port, dst_port, xnet, !udp_sum); 2145 src_port, dst_port, xnet, !udp_sum);
2148#if IS_ENABLED(CONFIG_IPV6) 2146#if IS_ENABLED(CONFIG_IPV6)
@@ -2152,7 +2150,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2152 ndst = vxlan6_get_route(vxlan, dev, sock6, skb, 2150 ndst = vxlan6_get_route(vxlan, dev, sock6, skb,
2153 rdst ? rdst->remote_ifindex : 0, tos, 2151 rdst ? rdst->remote_ifindex : 0, tos,
2154 label, &dst->sin6.sin6_addr, 2152 label, &dst->sin6.sin6_addr,
2155 &src->sin6.sin6_addr, 2153 &local_ip.sin6.sin6_addr,
2156 dst_port, src_port, 2154 dst_port, src_port,
2157 dst_cache, info); 2155 dst_cache, info);
2158 if (IS_ERR(ndst)) { 2156 if (IS_ERR(ndst)) {
@@ -2180,7 +2178,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2180 goto tx_error; 2178 goto tx_error;
2181 2179
2182 udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, 2180 udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev,
2183 &src->sin6.sin6_addr, 2181 &local_ip.sin6.sin6_addr,
2184 &dst->sin6.sin6_addr, tos, ttl, 2182 &dst->sin6.sin6_addr, tos, ttl,
2185 label, src_port, dst_port, !udp_sum); 2183 label, src_port, dst_port, !udp_sum);
2186#endif 2184#endif