aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoopa Prabhu <roopa@cumulusnetworks.com>2018-07-20 16:21:02 -0400
committerDavid S. Miller <davem@davemloft.net>2018-07-22 13:52:37 -0400
commit7431016b107c95cb5b2014aa1901fcb115f746bc (patch)
treeee1a1c54f2e5cc8c75238c863a6600db583adcc7
parent5025f7f7d506fba9b39e7fe8ca10f6f34cb9bc2d (diff)
vxlan: add new fdb alloc and create helpers
- Add new vxlan_fdb_alloc helper - rename existing vxlan_fdb_create into vxlan_fdb_update: because it really creates or updates an existing fdb entry - move new fdb creation into a separate vxlan_fdb_create Main motivation for this change is to introduce the ability to decouple vxlan fdb creation and notify, used in a later patch. Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/vxlan.c91
1 files changed, 62 insertions, 29 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index f6bb1d54d4bd..c8d5bfffadef 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -636,9 +636,62 @@ static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
636 return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr)); 636 return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr));
637} 637}
638 638
639/* Add new entry to forwarding table -- assumes lock held */ 639static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan,
640 const u8 *mac, __u16 state,
641 __be32 src_vni, __u8 ndm_flags)
642{
643 struct vxlan_fdb *f;
644
645 f = kmalloc(sizeof(*f), GFP_ATOMIC);
646 if (!f)
647 return NULL;
648 f->state = state;
649 f->flags = ndm_flags;
650 f->updated = f->used = jiffies;
651 f->vni = src_vni;
652 INIT_LIST_HEAD(&f->remotes);
653 memcpy(f->eth_addr, mac, ETH_ALEN);
654
655 return f;
656}
657
640static int vxlan_fdb_create(struct vxlan_dev *vxlan, 658static int vxlan_fdb_create(struct vxlan_dev *vxlan,
641 const u8 *mac, union vxlan_addr *ip, 659 const u8 *mac, union vxlan_addr *ip,
660 __u16 state, __be16 port, __be32 src_vni,
661 __be32 vni, __u32 ifindex, __u8 ndm_flags,
662 struct vxlan_fdb **fdb)
663{
664 struct vxlan_rdst *rd = NULL;
665 struct vxlan_fdb *f;
666 int rc;
667
668 if (vxlan->cfg.addrmax &&
669 vxlan->addrcnt >= vxlan->cfg.addrmax)
670 return -ENOSPC;
671
672 netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip);
673 f = vxlan_fdb_alloc(vxlan, mac, state, src_vni, ndm_flags);
674 if (!f)
675 return -ENOMEM;
676
677 rc = vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
678 if (rc < 0) {
679 kfree(f);
680 return rc;
681 }
682
683 ++vxlan->addrcnt;
684 hlist_add_head_rcu(&f->hlist,
685 vxlan_fdb_head(vxlan, mac, src_vni));
686
687 *fdb = f;
688
689 return 0;
690}
691
692/* Add new entry to forwarding table -- assumes lock held */
693static int vxlan_fdb_update(struct vxlan_dev *vxlan,
694 const u8 *mac, union vxlan_addr *ip,
642 __u16 state, __u16 flags, 695 __u16 state, __u16 flags,
643 __be16 port, __be32 src_vni, __be32 vni, 696 __be16 port, __be32 src_vni, __be32 vni,
644 __u32 ifindex, __u8 ndm_flags) 697 __u32 ifindex, __u8 ndm_flags)
@@ -687,37 +740,17 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
687 if (!(flags & NLM_F_CREATE)) 740 if (!(flags & NLM_F_CREATE))
688 return -ENOENT; 741 return -ENOENT;
689 742
690 if (vxlan->cfg.addrmax &&
691 vxlan->addrcnt >= vxlan->cfg.addrmax)
692 return -ENOSPC;
693
694 /* Disallow replace to add a multicast entry */ 743 /* Disallow replace to add a multicast entry */
695 if ((flags & NLM_F_REPLACE) && 744 if ((flags & NLM_F_REPLACE) &&
696 (is_multicast_ether_addr(mac) || is_zero_ether_addr(mac))) 745 (is_multicast_ether_addr(mac) || is_zero_ether_addr(mac)))
697 return -EOPNOTSUPP; 746 return -EOPNOTSUPP;
698 747
699 netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip); 748 netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip);
700 f = kmalloc(sizeof(*f), GFP_ATOMIC); 749 rc = vxlan_fdb_create(vxlan, mac, ip, state, port, src_vni,
701 if (!f) 750 vni, ifindex, ndm_flags, &f);
702 return -ENOMEM; 751 if (rc < 0)
703
704 notify = 1;
705 f->state = state;
706 f->flags = ndm_flags;
707 f->updated = f->used = jiffies;
708 f->vni = src_vni;
709 INIT_LIST_HEAD(&f->remotes);
710 memcpy(f->eth_addr, mac, ETH_ALEN);
711
712 rc = vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
713 if (rc < 0) {
714 kfree(f);
715 return rc; 752 return rc;
716 } 753 notify = 1;
717
718 ++vxlan->addrcnt;
719 hlist_add_head_rcu(&f->hlist,
720 vxlan_fdb_head(vxlan, mac, src_vni));
721 } 754 }
722 755
723 if (notify) { 756 if (notify) {
@@ -863,7 +896,7 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
863 return -EAFNOSUPPORT; 896 return -EAFNOSUPPORT;
864 897
865 spin_lock_bh(&vxlan->hash_lock); 898 spin_lock_bh(&vxlan->hash_lock);
866 err = vxlan_fdb_create(vxlan, addr, &ip, ndm->ndm_state, flags, 899 err = vxlan_fdb_update(vxlan, addr, &ip, ndm->ndm_state, flags,
867 port, src_vni, vni, ifindex, ndm->ndm_flags); 900 port, src_vni, vni, ifindex, ndm->ndm_flags);
868 spin_unlock_bh(&vxlan->hash_lock); 901 spin_unlock_bh(&vxlan->hash_lock);
869 902
@@ -1006,7 +1039,7 @@ static bool vxlan_snoop(struct net_device *dev,
1006 1039
1007 /* close off race between vxlan_flush and incoming packets */ 1040 /* close off race between vxlan_flush and incoming packets */
1008 if (netif_running(dev)) 1041 if (netif_running(dev))
1009 vxlan_fdb_create(vxlan, src_mac, src_ip, 1042 vxlan_fdb_update(vxlan, src_mac, src_ip,
1010 NUD_REACHABLE, 1043 NUD_REACHABLE,
1011 NLM_F_EXCL|NLM_F_CREATE, 1044 NLM_F_EXCL|NLM_F_CREATE,
1012 vxlan->cfg.dst_port, 1045 vxlan->cfg.dst_port,
@@ -3170,7 +3203,7 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev,
3170 3203
3171 /* create an fdb entry for a valid default destination */ 3204 /* create an fdb entry for a valid default destination */
3172 if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) { 3205 if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) {
3173 err = vxlan_fdb_create(vxlan, all_zeros_mac, 3206 err = vxlan_fdb_update(vxlan, all_zeros_mac,
3174 &vxlan->default_dst.remote_ip, 3207 &vxlan->default_dst.remote_ip,
3175 NUD_REACHABLE | NUD_PERMANENT, 3208 NUD_REACHABLE | NUD_PERMANENT,
3176 NLM_F_EXCL | NLM_F_CREATE, 3209 NLM_F_EXCL | NLM_F_CREATE,
@@ -3450,7 +3483,7 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
3450 old_dst.remote_ifindex, 0); 3483 old_dst.remote_ifindex, 0);
3451 3484
3452 if (!vxlan_addr_any(&dst->remote_ip)) { 3485 if (!vxlan_addr_any(&dst->remote_ip)) {
3453 err = vxlan_fdb_create(vxlan, all_zeros_mac, 3486 err = vxlan_fdb_update(vxlan, all_zeros_mac,
3454 &dst->remote_ip, 3487 &dst->remote_ip,
3455 NUD_REACHABLE | NUD_PERMANENT, 3488 NUD_REACHABLE | NUD_PERMANENT,
3456 NLM_F_CREATE | NLM_F_APPEND, 3489 NLM_F_CREATE | NLM_F_APPEND,