mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
vxlan: simplify RTF_LOCAL handling.
Avoid code duplicate code for handling RTF_LOCAL routes. Signed-off-by: Pravin B Shelar <pshelar@ovn.org> Acked-by: Jiri Benc <jbenc@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
655c3de165
commit
fee1fad7c7
1 changed files with 51 additions and 34 deletions
|
@ -1940,6 +1940,40 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
|
|||
}
|
||||
}
|
||||
|
||||
static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev,
|
||||
struct vxlan_dev *vxlan, union vxlan_addr *daddr,
|
||||
__be32 dst_port, __be32 vni, struct dst_entry *dst,
|
||||
u32 rt_flags)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
/* IPv6 rt-flags are checked against RTF_LOCAL, but the value of
|
||||
* RTF_LOCAL is equal to RTCF_LOCAL. So to keep code simple
|
||||
* we can use RTCF_LOCAL which works for ipv4 and ipv6 route entry.
|
||||
*/
|
||||
BUILD_BUG_ON(RTCF_LOCAL != RTF_LOCAL);
|
||||
#endif
|
||||
/* Bypass encapsulation if the destination is local */
|
||||
if (rt_flags & RTCF_LOCAL &&
|
||||
!(rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) {
|
||||
struct vxlan_dev *dst_vxlan;
|
||||
|
||||
dst_release(dst);
|
||||
dst_vxlan = vxlan_find_vni(vxlan->net, vni,
|
||||
daddr->sa.sa_family, dst_port,
|
||||
vxlan->flags);
|
||||
if (!dst_vxlan) {
|
||||
dev->stats.tx_errors++;
|
||||
kfree_skb(skb);
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||
struct vxlan_rdst *rdst, bool did_rsc)
|
||||
{
|
||||
|
@ -2038,27 +2072,19 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
|
|||
dst_cache, info);
|
||||
if (IS_ERR(rt))
|
||||
goto tx_error;
|
||||
|
||||
sk = sock4->sock->sk;
|
||||
|
||||
/* Bypass encapsulation if the destination is local */
|
||||
if (!info && rt->rt_flags & RTCF_LOCAL &&
|
||||
!(rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) {
|
||||
struct vxlan_dev *dst_vxlan;
|
||||
|
||||
ip_rt_put(rt);
|
||||
dst_vxlan = vxlan_find_vni(vxlan->net, vni,
|
||||
dst->sa.sa_family, dst_port,
|
||||
vxlan->flags);
|
||||
if (!dst_vxlan)
|
||||
goto tx_error;
|
||||
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info)
|
||||
if (!info) {
|
||||
err = encap_bypass_if_local(skb, dev, vxlan, dst,
|
||||
dst_port, vni, &rt->dst,
|
||||
rt->rt_flags);
|
||||
if (err)
|
||||
return;
|
||||
udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM_TX);
|
||||
else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT)
|
||||
} else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT) {
|
||||
df = htons(IP_DF);
|
||||
}
|
||||
|
||||
ndst = &rt->dst;
|
||||
tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
|
||||
|
@ -2074,7 +2100,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
|
|||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
} else {
|
||||
struct vxlan_sock *sock6 = rcu_dereference(vxlan->vn6_sock);
|
||||
u32 rt6i_flags;
|
||||
|
||||
ndst = vxlan6_get_route(vxlan, dev, sock6, skb,
|
||||
rdst ? rdst->remote_ifindex : 0, tos,
|
||||
|
@ -2087,24 +2112,16 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
|
|||
}
|
||||
sk = sock6->sock->sk;
|
||||
|
||||
/* Bypass encapsulation if the destination is local */
|
||||
rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
|
||||
if (!info && rt6i_flags & RTF_LOCAL &&
|
||||
!(rt6i_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) {
|
||||
struct vxlan_dev *dst_vxlan;
|
||||
if (!info) {
|
||||
u32 rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
|
||||
|
||||
dst_vxlan = vxlan_find_vni(vxlan->net, vni,
|
||||
dst->sa.sa_family, dst_port,
|
||||
vxlan->flags);
|
||||
if (!dst_vxlan)
|
||||
goto tx_error;
|
||||
dst_release(ndst);
|
||||
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info)
|
||||
err = encap_bypass_if_local(skb, dev, vxlan, dst,
|
||||
dst_port, vni, ndst,
|
||||
rt6i_flags);
|
||||
if (err)
|
||||
return;
|
||||
udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
|
||||
}
|
||||
|
||||
tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
|
||||
ttl = ttl ? : ip6_dst_hoplimit(ndst);
|
||||
|
|
Loading…
Reference in a new issue