提交 0770b53b 编写于 作者: P pravin shelar 提交者: David S. Miller

vxlan: simplify vxlan xmit

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: NPravin B Shelar <pshelar@ovn.org>
Acked-by: NJiri Benc <jbenc@redhat.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 fee1fad7
...@@ -1980,8 +1980,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ...@@ -1980,8 +1980,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
struct dst_cache *dst_cache; struct dst_cache *dst_cache;
struct ip_tunnel_info *info; struct ip_tunnel_info *info;
struct vxlan_dev *vxlan = netdev_priv(dev); struct vxlan_dev *vxlan = netdev_priv(dev);
struct sock *sk; const struct iphdr *old_iph = ip_hdr(skb);
const struct iphdr *old_iph;
union vxlan_addr *dst; union vxlan_addr *dst;
union vxlan_addr remote_ip, local_ip; union vxlan_addr remote_ip, local_ip;
union vxlan_addr *src; union vxlan_addr *src;
...@@ -1990,7 +1989,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ...@@ -1990,7 +1989,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
__be16 src_port = 0, dst_port; __be16 src_port = 0, dst_port;
struct dst_entry *ndst = NULL; struct dst_entry *ndst = NULL;
__be32 vni, label; __be32 vni, label;
__be16 df = 0;
__u8 tos, ttl; __u8 tos, ttl;
int err; int err;
u32 flags = vxlan->flags; u32 flags = vxlan->flags;
...@@ -2000,19 +1998,40 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ...@@ -2000,19 +1998,40 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
info = skb_tunnel_info(skb); info = skb_tunnel_info(skb);
if (rdst) { 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; dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
vni = rdst->remote_vni; vni = rdst->remote_vni;
dst = &rdst->remote_ip;
src = &vxlan->cfg.saddr; src = &vxlan->cfg.saddr;
dst_cache = &rdst->dst_cache; 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 { } else {
if (!info) { if (!info) {
WARN_ONCE(1, "%s: Missing encapsulation instructions\n", WARN_ONCE(1, "%s: Missing encapsulation instructions\n",
dev->name); dev->name);
goto drop; 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); remote_ip.sa.sa_family = ip_tunnel_info_af(info);
if (remote_ip.sa.sa_family == AF_INET) { if (remote_ip.sa.sa_family == AF_INET) {
remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst; 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, ...@@ -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; local_ip.sin6.sin6_addr = info->key.u.ipv6.src;
} }
dst = &remote_ip; 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; src = &local_ip;
dst_cache = &info->dst_cache; dst_cache = &info->dst_cache;
} if (info->options_len)
md = ip_tunnel_info_opts(info);
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) {
ttl = info->key.ttl; ttl = info->key.ttl;
tos = info->key.tos; tos = info->key.tos;
label = info->key.label; label = info->key.label;
udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM); 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) { if (dst->sa.sa_family == AF_INET) {
struct vxlan_sock *sock4 = rcu_dereference(vxlan->vn4_sock); struct vxlan_sock *sock4 = rcu_dereference(vxlan->vn4_sock);
struct rtable *rt; struct rtable *rt;
__be16 df = 0;
rt = vxlan_get_route(vxlan, dev, sock4, skb, rt = vxlan_get_route(vxlan, dev, sock4, skb,
rdst ? rdst->remote_ifindex : 0, tos, rdst ? rdst->remote_ifindex : 0, tos,
...@@ -2073,7 +2068,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ...@@ -2073,7 +2068,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
if (IS_ERR(rt)) if (IS_ERR(rt))
goto tx_error; goto tx_error;
sk = sock4->sock->sk;
/* Bypass encapsulation if the destination is local */ /* Bypass encapsulation if the destination is local */
if (!info) { if (!info) {
err = encap_bypass_if_local(skb, dev, vxlan, dst, 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, ...@@ -2081,7 +2075,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
rt->rt_flags); rt->rt_flags);
if (err) if (err)
return; 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); df = htons(IP_DF);
} }
...@@ -2094,7 +2087,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ...@@ -2094,7 +2087,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
if (err < 0) if (err < 0)
goto tx_error; 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, dst->sin.sin_addr.s_addr, tos, ttl, df,
src_port, dst_port, xnet, !udp_sum); src_port, dst_port, xnet, !udp_sum);
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
...@@ -2110,7 +2103,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ...@@ -2110,7 +2103,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
ndst = NULL; ndst = NULL;
goto tx_error; goto tx_error;
} }
sk = sock6->sock->sk;
if (!info) { if (!info) {
u32 rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags; 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, ...@@ -2120,7 +2112,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
rt6i_flags); rt6i_flags);
if (err) if (err)
return; return;
udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
} }
tos = ip_tunnel_ecn_encap(tos, old_iph, skb); 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, ...@@ -2131,13 +2122,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
if (err < 0) if (err < 0)
goto tx_error; 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, &src->sin6.sin6_addr,
&dst->sin6.sin6_addr, tos, ttl, &dst->sin6.sin6_addr, tos, ttl,
label, src_port, dst_port, !udp_sum); label, src_port, dst_port, !udp_sum);
#endif #endif
} }
return; return;
drop: drop:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册