vxlan driver has bypass for local vxlan traffic, but that
depends on information about all VNIs on local system in
vxlan driver. This is not available in case of LWT.
Therefore following patch disable encap bypass for LWT
vxlan traffic.

Reported-by: Jakub Libosvar <jlibo...@redhat.com>
Signed-off-by: Pravin B Shelar <pshe...@ovn.org>
---
This patch is for testing only. I am planing on sending fix
for upstream vxlan soon.
---
 datapath/linux/compat/vxlan.c | 71 ++++++++++++++++++++++---------------------
 1 file changed, 37 insertions(+), 34 deletions(-)

diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
index 6d77527..d17a30d 100644
--- a/datapath/linux/compat/vxlan.c
+++ b/datapath/linux/compat/vxlan.c
@@ -1109,23 +1109,23 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct 
net_device *dev,
                }
 
                /* Bypass encapsulation if the destination is local */
-               if (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) {
+                       if (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;
+                       }
                        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);
 
                tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
@@ -1142,7 +1142,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct 
net_device *dev,
        } else {
                struct dst_entry *ndst;
                struct in6_addr saddr;
-               u32 rt6i_flags;
 
                if (!vxlan->vn6_sock)
                        goto drop;
@@ -1167,24 +1166,28 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct 
net_device *dev,
                        goto tx_error;
                }
 
-               /* Bypass encapsulation if the destination is local */
-               rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
-               if (rt6i_flags & RTF_LOCAL &&
-                   !(rt6i_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) {
-                       struct vxlan_dev *dst_vxlan;
-
-                       dst_release(ndst);
-                       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) {
+                       u32 rt6i_flags;
+
+                       rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
+
+                       /* Bypass encapsulation if the destination is local */
+                       if (rt6i_flags & RTF_LOCAL &&
+                           !(rt6i_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) {
+                               struct vxlan_dev *dst_vxlan;
+
+                               dst_release(ndst);
+                               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;
+                       }
                        udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
+               }
 
                tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
                ttl = ttl ? : ip6_dst_hoplimit(ndst);
-- 
1.8.3.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to