diff options
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r-- | drivers/net/vxlan.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index da4e3d6632f6..c0dda6fc0921 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -1811,7 +1811,7 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan, | |||
1811 | fl4.flowi4_mark = skb->mark; | 1811 | fl4.flowi4_mark = skb->mark; |
1812 | fl4.flowi4_proto = IPPROTO_UDP; | 1812 | fl4.flowi4_proto = IPPROTO_UDP; |
1813 | fl4.daddr = daddr; | 1813 | fl4.daddr = daddr; |
1814 | fl4.saddr = vxlan->cfg.saddr.sin.sin_addr.s_addr; | 1814 | fl4.saddr = *saddr; |
1815 | 1815 | ||
1816 | rt = ip_route_output_key(vxlan->net, &fl4); | 1816 | rt = ip_route_output_key(vxlan->net, &fl4); |
1817 | if (!IS_ERR(rt)) { | 1817 | if (!IS_ERR(rt)) { |
@@ -1847,7 +1847,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, | |||
1847 | memset(&fl6, 0, sizeof(fl6)); | 1847 | memset(&fl6, 0, sizeof(fl6)); |
1848 | fl6.flowi6_oif = oif; | 1848 | fl6.flowi6_oif = oif; |
1849 | fl6.daddr = *daddr; | 1849 | fl6.daddr = *daddr; |
1850 | fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr; | 1850 | fl6.saddr = *saddr; |
1851 | fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label); | 1851 | fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label); |
1852 | fl6.flowi6_mark = skb->mark; | 1852 | fl6.flowi6_mark = skb->mark; |
1853 | fl6.flowi6_proto = IPPROTO_UDP; | 1853 | fl6.flowi6_proto = IPPROTO_UDP; |
@@ -1920,7 +1920,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
1920 | struct rtable *rt = NULL; | 1920 | struct rtable *rt = NULL; |
1921 | const struct iphdr *old_iph; | 1921 | const struct iphdr *old_iph; |
1922 | union vxlan_addr *dst; | 1922 | union vxlan_addr *dst; |
1923 | union vxlan_addr remote_ip; | 1923 | union vxlan_addr remote_ip, local_ip; |
1924 | union vxlan_addr *src; | ||
1924 | struct vxlan_metadata _md; | 1925 | struct vxlan_metadata _md; |
1925 | struct vxlan_metadata *md = &_md; | 1926 | struct vxlan_metadata *md = &_md; |
1926 | __be16 src_port = 0, dst_port; | 1927 | __be16 src_port = 0, dst_port; |
@@ -1938,6 +1939,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
1938 | dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port; | 1939 | dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port; |
1939 | vni = rdst->remote_vni; | 1940 | vni = rdst->remote_vni; |
1940 | dst = &rdst->remote_ip; | 1941 | dst = &rdst->remote_ip; |
1942 | src = &vxlan->cfg.saddr; | ||
1941 | dst_cache = &rdst->dst_cache; | 1943 | dst_cache = &rdst->dst_cache; |
1942 | } else { | 1944 | } else { |
1943 | if (!info) { | 1945 | if (!info) { |
@@ -1948,11 +1950,15 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
1948 | dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port; | 1950 | dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port; |
1949 | vni = vxlan_tun_id_to_vni(info->key.tun_id); | 1951 | vni = vxlan_tun_id_to_vni(info->key.tun_id); |
1950 | remote_ip.sa.sa_family = ip_tunnel_info_af(info); | 1952 | 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) { |
1952 | remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst; | 1954 | 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 { | ||
1954 | remote_ip.sin6.sin6_addr = info->key.u.ipv6.dst; | 1957 | remote_ip.sin6.sin6_addr = info->key.u.ipv6.dst; |
1958 | local_ip.sin6.sin6_addr = info->key.u.ipv6.src; | ||
1959 | } | ||
1955 | dst = &remote_ip; | 1960 | dst = &remote_ip; |
1961 | src = &local_ip; | ||
1956 | dst_cache = &info->dst_cache; | 1962 | dst_cache = &info->dst_cache; |
1957 | } | 1963 | } |
1958 | 1964 | ||
@@ -1992,15 +1998,14 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
1992 | } | 1998 | } |
1993 | 1999 | ||
1994 | if (dst->sa.sa_family == AF_INET) { | 2000 | if (dst->sa.sa_family == AF_INET) { |
1995 | __be32 saddr; | ||
1996 | |||
1997 | if (!vxlan->vn4_sock) | 2001 | if (!vxlan->vn4_sock) |
1998 | goto drop; | 2002 | goto drop; |
1999 | sk = vxlan->vn4_sock->sock->sk; | 2003 | sk = vxlan->vn4_sock->sock->sk; |
2000 | 2004 | ||
2001 | rt = vxlan_get_route(vxlan, skb, | 2005 | rt = vxlan_get_route(vxlan, skb, |
2002 | rdst ? rdst->remote_ifindex : 0, tos, | 2006 | 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, | ||
2004 | dst_cache, info); | 2009 | dst_cache, info); |
2005 | if (IS_ERR(rt)) { | 2010 | if (IS_ERR(rt)) { |
2006 | netdev_dbg(dev, "no route to %pI4\n", | 2011 | netdev_dbg(dev, "no route to %pI4\n", |
@@ -2017,7 +2022,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
2017 | } | 2022 | } |
2018 | 2023 | ||
2019 | /* Bypass encapsulation if the destination is local */ | 2024 | /* Bypass encapsulation if the destination is local */ |
2020 | if (rt->rt_flags & RTCF_LOCAL && | 2025 | if (!info && rt->rt_flags & RTCF_LOCAL && |
2021 | !(rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) { | 2026 | !(rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) { |
2022 | struct vxlan_dev *dst_vxlan; | 2027 | struct vxlan_dev *dst_vxlan; |
2023 | 2028 | ||
@@ -2043,13 +2048,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
2043 | if (err < 0) | 2048 | if (err < 0) |
2044 | goto xmit_tx_error; | 2049 | goto xmit_tx_error; |
2045 | 2050 | ||
2046 | udp_tunnel_xmit_skb(rt, sk, skb, saddr, | 2051 | udp_tunnel_xmit_skb(rt, sk, skb, src->sin.sin_addr.s_addr, |
2047 | dst->sin.sin_addr.s_addr, tos, ttl, df, | 2052 | dst->sin.sin_addr.s_addr, tos, ttl, df, |
2048 | src_port, dst_port, xnet, !udp_sum); | 2053 | src_port, dst_port, xnet, !udp_sum); |
2049 | #if IS_ENABLED(CONFIG_IPV6) | 2054 | #if IS_ENABLED(CONFIG_IPV6) |
2050 | } else { | 2055 | } else { |
2051 | struct dst_entry *ndst; | 2056 | struct dst_entry *ndst; |
2052 | struct in6_addr saddr; | ||
2053 | u32 rt6i_flags; | 2057 | u32 rt6i_flags; |
2054 | 2058 | ||
2055 | if (!vxlan->vn6_sock) | 2059 | if (!vxlan->vn6_sock) |
@@ -2058,7 +2062,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
2058 | 2062 | ||
2059 | ndst = vxlan6_get_route(vxlan, skb, | 2063 | ndst = vxlan6_get_route(vxlan, skb, |
2060 | rdst ? rdst->remote_ifindex : 0, tos, | 2064 | rdst ? rdst->remote_ifindex : 0, tos, |
2061 | label, &dst->sin6.sin6_addr, &saddr, | 2065 | label, &dst->sin6.sin6_addr, |
2066 | &src->sin6.sin6_addr, | ||
2062 | dst_cache, info); | 2067 | dst_cache, info); |
2063 | if (IS_ERR(ndst)) { | 2068 | if (IS_ERR(ndst)) { |
2064 | netdev_dbg(dev, "no route to %pI6\n", | 2069 | netdev_dbg(dev, "no route to %pI6\n", |
@@ -2077,7 +2082,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
2077 | 2082 | ||
2078 | /* Bypass encapsulation if the destination is local */ | 2083 | /* Bypass encapsulation if the destination is local */ |
2079 | rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags; | 2084 | rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags; |
2080 | if (rt6i_flags & RTF_LOCAL && | 2085 | if (!info && rt6i_flags & RTF_LOCAL && |
2081 | !(rt6i_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) { | 2086 | !(rt6i_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) { |
2082 | struct vxlan_dev *dst_vxlan; | 2087 | struct vxlan_dev *dst_vxlan; |
2083 | 2088 | ||
@@ -2104,7 +2109,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
2104 | return; | 2109 | return; |
2105 | } | 2110 | } |
2106 | udp_tunnel6_xmit_skb(ndst, sk, skb, dev, | 2111 | 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, | ||
2108 | label, src_port, dst_port, !udp_sum); | 2114 | label, src_port, dst_port, !udp_sum); |
2109 | #endif | 2115 | #endif |
2110 | } | 2116 | } |