aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/vxlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r--drivers/net/vxlan.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 8111565c35fc..f6dce13c8f89 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -603,18 +603,22 @@ skip:
603 603
604/* Watch incoming packets to learn mapping between Ethernet address 604/* Watch incoming packets to learn mapping between Ethernet address
605 * and Tunnel endpoint. 605 * and Tunnel endpoint.
606 * Return true if packet is bogus and should be droppped.
606 */ 607 */
607static void vxlan_snoop(struct net_device *dev, 608static bool vxlan_snoop(struct net_device *dev,
608 __be32 src_ip, const u8 *src_mac) 609 __be32 src_ip, const u8 *src_mac)
609{ 610{
610 struct vxlan_dev *vxlan = netdev_priv(dev); 611 struct vxlan_dev *vxlan = netdev_priv(dev);
611 struct vxlan_fdb *f; 612 struct vxlan_fdb *f;
612 int err;
613 613
614 f = vxlan_find_mac(vxlan, src_mac); 614 f = vxlan_find_mac(vxlan, src_mac);
615 if (likely(f)) { 615 if (likely(f)) {
616 if (likely(f->remote.remote_ip == src_ip)) 616 if (likely(f->remote.remote_ip == src_ip))
617 return; 617 return false;
618
619 /* Don't migrate static entries, drop packets */
620 if (f->state & NUD_NOARP)
621 return true;
618 622
619 if (net_ratelimit()) 623 if (net_ratelimit())
620 netdev_info(dev, 624 netdev_info(dev,
@@ -626,14 +630,19 @@ static void vxlan_snoop(struct net_device *dev,
626 } else { 630 } else {
627 /* learned new entry */ 631 /* learned new entry */
628 spin_lock(&vxlan->hash_lock); 632 spin_lock(&vxlan->hash_lock);
629 err = vxlan_fdb_create(vxlan, src_mac, src_ip, 633
630 NUD_REACHABLE, 634 /* close off race between vxlan_flush and incoming packets */
631 NLM_F_EXCL|NLM_F_CREATE, 635 if (netif_running(dev))
632 vxlan->dst_port, 636 vxlan_fdb_create(vxlan, src_mac, src_ip,
633 vxlan->default_dst.remote_vni, 637 NUD_REACHABLE,
634 0, NTF_SELF); 638 NLM_F_EXCL|NLM_F_CREATE,
639 vxlan->dst_port,
640 vxlan->default_dst.remote_vni,
641 0, NTF_SELF);
635 spin_unlock(&vxlan->hash_lock); 642 spin_unlock(&vxlan->hash_lock);
636 } 643 }
644
645 return false;
637} 646}
638 647
639 648
@@ -766,8 +775,9 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
766 vxlan->dev->dev_addr) == 0) 775 vxlan->dev->dev_addr) == 0)
767 goto drop; 776 goto drop;
768 777
769 if (vxlan->flags & VXLAN_F_LEARN) 778 if ((vxlan->flags & VXLAN_F_LEARN) &&
770 vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source); 779 vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source))
780 goto drop;
771 781
772 __skb_tunnel_rx(skb, vxlan->dev); 782 __skb_tunnel_rx(skb, vxlan->dev);
773 skb_reset_network_header(skb); 783 skb_reset_network_header(skb);
@@ -1190,9 +1200,11 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
1190 struct sk_buff *skb1; 1200 struct sk_buff *skb1;
1191 1201
1192 skb1 = skb_clone(skb, GFP_ATOMIC); 1202 skb1 = skb_clone(skb, GFP_ATOMIC);
1193 rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc); 1203 if (skb1) {
1194 if (rc == NETDEV_TX_OK) 1204 rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc);
1195 rc = rc1; 1205 if (rc == NETDEV_TX_OK)
1206 rc = rc1;
1207 }
1196 } 1208 }
1197 1209
1198 rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc); 1210 rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc);