]> git.karo-electronics.de Git - linux-beck.git/commitdiff
vxlan: simplify vxlan xmit
authorpravin shelar <pshelar@ovn.org>
Mon, 14 Nov 2016 04:43:57 +0000 (20:43 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 15 Nov 2016 17:16:13 +0000 (12:16 -0500)
Existing vxlan xmit function handles two distinct cases.
1. vxlan net device
2. vxlan lwt device.
By seperating initialization these two cases the egress path
looks better.

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>
drivers/net/vxlan.c

index 3f952cfc5a2c3038b0d7d79e572c383fa8375105..d536a9340cd5874c76ae4f427ff527d3d48fb520 100644 (file)
@@ -1980,8 +1980,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
        struct dst_cache *dst_cache;
        struct ip_tunnel_info *info;
        struct vxlan_dev *vxlan = netdev_priv(dev);
-       struct sock *sk;
-       const struct iphdr *old_iph;
+       const struct iphdr *old_iph = ip_hdr(skb);
        union vxlan_addr *dst;
        union vxlan_addr remote_ip, local_ip;
        union vxlan_addr *src;
@@ -1990,7 +1989,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
        __be16 src_port = 0, dst_port;
        struct dst_entry *ndst = NULL;
        __be32 vni, label;
-       __be16 df = 0;
        __u8 tos, ttl;
        int err;
        u32 flags = vxlan->flags;
@@ -2000,19 +1998,40 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
        info = skb_tunnel_info(skb);
 
        if (rdst) {
+               dst = &rdst->remote_ip;
+               if (vxlan_addr_any(dst)) {
+                       if (did_rsc) {
+                               /* short-circuited back to local bridge */
+                               vxlan_encap_bypass(skb, vxlan, vxlan);
+                               return;
+                       }
+                       goto drop;
+               }
+
                dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
                vni = rdst->remote_vni;
-               dst = &rdst->remote_ip;
                src = &vxlan->cfg.saddr;
                dst_cache = &rdst->dst_cache;
+               md->gbp = skb->mark;
+               ttl = vxlan->cfg.ttl;
+               if (!ttl && vxlan_addr_multicast(dst))
+                       ttl = 1;
+
+               tos = vxlan->cfg.tos;
+               if (tos == 1)
+                       tos = ip_tunnel_get_dsfield(old_iph, skb);
+
+               if (dst->sa.sa_family == AF_INET)
+                       udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM_TX);
+               else
+                       udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
+               label = vxlan->cfg.label;
        } else {
                if (!info) {
                        WARN_ONCE(1, "%s: Missing encapsulation instructions\n",
                                  dev->name);
                        goto drop;
                }
-               dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
-               vni = tunnel_id_to_key32(info->key.tun_id);
                remote_ip.sa.sa_family = ip_tunnel_info_af(info);
                if (remote_ip.sa.sa_family == AF_INET) {
                        remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
@@ -2022,48 +2041,24 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        local_ip.sin6.sin6_addr = info->key.u.ipv6.src;
                }
                dst = &remote_ip;
+               dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
+               vni = tunnel_id_to_key32(info->key.tun_id);
                src = &local_ip;
                dst_cache = &info->dst_cache;
-       }
-
-       if (vxlan_addr_any(dst)) {
-               if (did_rsc) {
-                       /* short-circuited back to local bridge */
-                       vxlan_encap_bypass(skb, vxlan, vxlan);
-                       return;
-               }
-               goto drop;
-       }
-
-       old_iph = ip_hdr(skb);
-
-       ttl = vxlan->cfg.ttl;
-       if (!ttl && vxlan_addr_multicast(dst))
-               ttl = 1;
-
-       tos = vxlan->cfg.tos;
-       if (tos == 1)
-               tos = ip_tunnel_get_dsfield(old_iph, skb);
-
-       label = vxlan->cfg.label;
-       src_port = udp_flow_src_port(dev_net(dev), skb, vxlan->cfg.port_min,
-                                    vxlan->cfg.port_max, true);
-
-       if (info) {
+               if (info->options_len)
+                       md = ip_tunnel_info_opts(info);
                ttl = info->key.ttl;
                tos = info->key.tos;
                label = info->key.label;
                udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM);
-
-               if (info->options_len)
-                       md = ip_tunnel_info_opts(info);
-       } else {
-               md->gbp = skb->mark;
        }
+       src_port = udp_flow_src_port(dev_net(dev), skb, vxlan->cfg.port_min,
+                                    vxlan->cfg.port_max, true);
 
        if (dst->sa.sa_family == AF_INET) {
                struct vxlan_sock *sock4 = rcu_dereference(vxlan->vn4_sock);
                struct rtable *rt;
+               __be16 df = 0;
 
                rt = vxlan_get_route(vxlan, dev, sock4, skb,
                                     rdst ? rdst->remote_ifindex : 0, tos,
@@ -2073,7 +2068,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                if (IS_ERR(rt))
                        goto tx_error;
 
-               sk = sock4->sock->sk;
                /* Bypass encapsulation if the destination is local */
                if (!info) {
                        err = encap_bypass_if_local(skb, dev, vxlan, dst,
@@ -2081,7 +2075,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                                                    rt->rt_flags);
                        if (err)
                                return;
-                       udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM_TX);
                } else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT) {
                        df = htons(IP_DF);
                }
@@ -2094,7 +2087,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                if (err < 0)
                        goto tx_error;
 
-               udp_tunnel_xmit_skb(rt, sk, skb, src->sin.sin_addr.s_addr,
+               udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, src->sin.sin_addr.s_addr,
                                    dst->sin.sin_addr.s_addr, tos, ttl, df,
                                    src_port, dst_port, xnet, !udp_sum);
 #if IS_ENABLED(CONFIG_IPV6)
@@ -2110,7 +2103,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        ndst = NULL;
                        goto tx_error;
                }
-               sk = sock6->sock->sk;
 
                if (!info) {
                        u32 rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
@@ -2120,7 +2112,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                                                    rt6i_flags);
                        if (err)
                                return;
-                       udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
                }
 
                tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
@@ -2131,13 +2122,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                if (err < 0)
                        goto tx_error;
 
-               udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
+               udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev,
                                     &src->sin6.sin6_addr,
                                     &dst->sin6.sin6_addr, tos, ttl,
                                     label, src_port, dst_port, !udp_sum);
 #endif
        }
-
        return;
 
 drop: