aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar stephen hemminger <stephen@networkplumber.org> 2013-06-17 12:09:58 -0700
committerGravatar David S. Miller <davem@davemloft.net> 2013-06-17 15:55:46 -0700
commit26a41ae604381c5cc0caf1c3261ca6b298b5fe69 (patch)
tree011b32f24b97a5f5d5aa1fb7b97c8583bd90d634
parentvxlan: fix race between flush and incoming learning (diff)
downloadlinux-26a41ae604381c5cc0caf1c3261ca6b298b5fe69.tar.gz
linux-26a41ae604381c5cc0caf1c3261ca6b298b5fe69.tar.bz2
linux-26a41ae604381c5cc0caf1c3261ca6b298b5fe69.zip
vxlan: only migrate dynamic FDB entries
Only migrate dynamic forwarding table entries, don't modify static entries. If packet received from incorrect source IP address assume it is an imposter and drop it. This patch applies only to -net, a different patch would be needed for earlier kernels since the NTF_SELF flag was introduced with 3.10. Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/vxlan.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 577a069a6dde..15a73ec42c64 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -565,8 +565,9 @@ skip:
/* Watch incoming packets to learn mapping between Ethernet address
* and Tunnel endpoint.
+ * Return true if packet is bogus and should be droppped.
*/
-static void vxlan_snoop(struct net_device *dev,
+static bool vxlan_snoop(struct net_device *dev,
__be32 src_ip, const u8 *src_mac)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
@@ -575,7 +576,11 @@ static void vxlan_snoop(struct net_device *dev,
f = vxlan_find_mac(vxlan, src_mac);
if (likely(f)) {
if (likely(f->remote.remote_ip == src_ip))
- return;
+ return false;
+
+ /* Don't migrate static entries, drop packets */
+ if (!(f->flags & NTF_SELF))
+ return true;
if (net_ratelimit())
netdev_info(dev,
@@ -598,6 +603,8 @@ static void vxlan_snoop(struct net_device *dev,
0, NTF_SELF);
spin_unlock(&vxlan->hash_lock);
}
+
+ return false;
}
@@ -729,8 +736,9 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
vxlan->dev->dev_addr) == 0)
goto drop;
- if (vxlan->flags & VXLAN_F_LEARN)
- vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source);
+ if ((vxlan->flags & VXLAN_F_LEARN) &&
+ vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source))
+ goto drop;
__skb_tunnel_rx(skb, vxlan->dev);
skb_reset_network_header(skb);