Skip to content

Commit 272d96a

Browse files
pshelardavem330
authored andcommitted
net: vxlan: lwt: Use source ip address during route lookup.
LWT user can specify destination as well as source ip address for given tunnel endpoint. But vxlan is ignoring given source ip address. Following patch uses both ip address to route the tunnel packet. This consistent with other LWT implementations, like GENEVE and GRE. Fixes: ee122c7 ("vxlan: Flow based tunneling"). Signed-off-by: Pravin B Shelar <[email protected]> Acked-by: Jiri Benc <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent da1b419 commit 272d96a

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

drivers/net/vxlan.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,7 +1811,7 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan,
18111811
fl4.flowi4_mark = skb->mark;
18121812
fl4.flowi4_proto = IPPROTO_UDP;
18131813
fl4.daddr = daddr;
1814-
fl4.saddr = vxlan->cfg.saddr.sin.sin_addr.s_addr;
1814+
fl4.saddr = *saddr;
18151815

18161816
rt = ip_route_output_key(vxlan->net, &fl4);
18171817
if (!IS_ERR(rt)) {
@@ -1847,7 +1847,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
18471847
memset(&fl6, 0, sizeof(fl6));
18481848
fl6.flowi6_oif = oif;
18491849
fl6.daddr = *daddr;
1850-
fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr;
1850+
fl6.saddr = *saddr;
18511851
fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label);
18521852
fl6.flowi6_mark = skb->mark;
18531853
fl6.flowi6_proto = IPPROTO_UDP;
@@ -1920,7 +1920,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
19201920
struct rtable *rt = NULL;
19211921
const struct iphdr *old_iph;
19221922
union vxlan_addr *dst;
1923-
union vxlan_addr remote_ip;
1923+
union vxlan_addr remote_ip, local_ip;
1924+
union vxlan_addr *src;
19241925
struct vxlan_metadata _md;
19251926
struct vxlan_metadata *md = &_md;
19261927
__be16 src_port = 0, dst_port;
@@ -1938,6 +1939,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
19381939
dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
19391940
vni = rdst->remote_vni;
19401941
dst = &rdst->remote_ip;
1942+
src = &vxlan->cfg.saddr;
19411943
dst_cache = &rdst->dst_cache;
19421944
} else {
19431945
if (!info) {
@@ -1948,11 +1950,15 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
19481950
dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
19491951
vni = vxlan_tun_id_to_vni(info->key.tun_id);
19501952
remote_ip.sa.sa_family = ip_tunnel_info_af(info);
1951-
if (remote_ip.sa.sa_family == AF_INET)
1953+
if (remote_ip.sa.sa_family == AF_INET) {
19521954
remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
1953-
else
1955+
local_ip.sin.sin_addr.s_addr = info->key.u.ipv4.src;
1956+
} else {
19541957
remote_ip.sin6.sin6_addr = info->key.u.ipv6.dst;
1958+
local_ip.sin6.sin6_addr = info->key.u.ipv6.src;
1959+
}
19551960
dst = &remote_ip;
1961+
src = &local_ip;
19561962
dst_cache = &info->dst_cache;
19571963
}
19581964

@@ -1992,15 +1998,14 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
19921998
}
19931999

19942000
if (dst->sa.sa_family == AF_INET) {
1995-
__be32 saddr;
1996-
19972001
if (!vxlan->vn4_sock)
19982002
goto drop;
19992003
sk = vxlan->vn4_sock->sock->sk;
20002004

20012005
rt = vxlan_get_route(vxlan, skb,
20022006
rdst ? rdst->remote_ifindex : 0, tos,
2003-
dst->sin.sin_addr.s_addr, &saddr,
2007+
dst->sin.sin_addr.s_addr,
2008+
&src->sin.sin_addr.s_addr,
20042009
dst_cache, info);
20052010
if (IS_ERR(rt)) {
20062011
netdev_dbg(dev, "no route to %pI4\n",
@@ -2043,13 +2048,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
20432048
if (err < 0)
20442049
goto xmit_tx_error;
20452050

2046-
udp_tunnel_xmit_skb(rt, sk, skb, saddr,
2051+
udp_tunnel_xmit_skb(rt, sk, skb, src->sin.sin_addr.s_addr,
20472052
dst->sin.sin_addr.s_addr, tos, ttl, df,
20482053
src_port, dst_port, xnet, !udp_sum);
20492054
#if IS_ENABLED(CONFIG_IPV6)
20502055
} else {
20512056
struct dst_entry *ndst;
2052-
struct in6_addr saddr;
20532057
u32 rt6i_flags;
20542058

20552059
if (!vxlan->vn6_sock)
@@ -2058,7 +2062,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
20582062

20592063
ndst = vxlan6_get_route(vxlan, skb,
20602064
rdst ? rdst->remote_ifindex : 0, tos,
2061-
label, &dst->sin6.sin6_addr, &saddr,
2065+
label, &dst->sin6.sin6_addr,
2066+
&src->sin6.sin6_addr,
20622067
dst_cache, info);
20632068
if (IS_ERR(ndst)) {
20642069
netdev_dbg(dev, "no route to %pI6\n",
@@ -2104,7 +2109,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
21042109
return;
21052110
}
21062111
udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
2107-
&saddr, &dst->sin6.sin6_addr, tos, ttl,
2112+
&src->sin6.sin6_addr,
2113+
&dst->sin6.sin6_addr, tos, ttl,
21082114
label, src_port, dst_port, !udp_sum);
21092115
#endif
21102116
}

0 commit comments

Comments
 (0)