mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
115 lines
3.2 KiB
Diff
115 lines
3.2 KiB
Diff
From: pravin shelar <pshelar@ovn.org>
|
|
Date: Sun, 13 Nov 2016 20:43:56 -0800
|
|
Subject: [PATCH] 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>
|
|
---
|
|
|
|
--- a/drivers/net/vxlan.c
|
|
+++ b/drivers/net/vxlan.c
|
|
@@ -1946,6 +1946,40 @@ static void vxlan_encap_bypass(struct sk
|
|
}
|
|
}
|
|
|
|
+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)
|
|
{
|
|
@@ -2059,18 +2093,12 @@ static void vxlan_xmit_one(struct sk_buf
|
|
}
|
|
|
|
/* 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) {
|
|
+ err = encap_bypass_if_local(skb, dev, vxlan, dst,
|
|
+ dst_port, vni, &rt->dst,
|
|
+ rt->rt_flags);
|
|
+ if (err)
|
|
+ return;
|
|
}
|
|
|
|
/* Reset the skb_iif to Tunnels interface index */
|
|
@@ -2096,7 +2124,6 @@ static void vxlan_xmit_one(struct sk_buf
|
|
} else {
|
|
struct dst_entry *ndst;
|
|
struct in6_addr saddr;
|
|
- u32 rt6i_flags;
|
|
|
|
if (!vxlan->vn6_sock)
|
|
goto drop;
|
|
@@ -2121,19 +2148,14 @@ static void vxlan_xmit_one(struct sk_buf
|
|
}
|
|
|
|
/* 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;
|
|
+ if (!info) {
|
|
+ u32 rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
|
|
|
|
- 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;
|
|
+ err = encap_bypass_if_local(skb, dev, vxlan, dst,
|
|
+ dst_port, vni, ndst,
|
|
+ rt6i_flags);
|
|
+ if (err)
|
|
+ return;
|
|
}
|
|
|
|
if (info) {
|