Commit 7431016b authored by Roopa Prabhu's avatar Roopa Prabhu Committed by David S. Miller

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: default avatarRoopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5025f7f7
...@@ -636,8 +636,61 @@ static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) ...@@ -636,8 +636,61 @@ static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr)); return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr));
} }
/* Add new entry to forwarding table -- assumes lock held */ static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan,
const u8 *mac, __u16 state,
__be32 src_vni, __u8 ndm_flags)
{
struct vxlan_fdb *f;
f = kmalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
return NULL;
f->state = state;
f->flags = ndm_flags;
f->updated = f->used = jiffies;
f->vni = src_vni;
INIT_LIST_HEAD(&f->remotes);
memcpy(f->eth_addr, mac, ETH_ALEN);
return f;
}
static int vxlan_fdb_create(struct vxlan_dev *vxlan, static int vxlan_fdb_create(struct vxlan_dev *vxlan,
const u8 *mac, union vxlan_addr *ip,
__u16 state, __be16 port, __be32 src_vni,
__be32 vni, __u32 ifindex, __u8 ndm_flags,
struct vxlan_fdb **fdb)
{
struct vxlan_rdst *rd = NULL;
struct vxlan_fdb *f;
int rc;
if (vxlan->cfg.addrmax &&
vxlan->addrcnt >= vxlan->cfg.addrmax)
return -ENOSPC;
netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip);
f = vxlan_fdb_alloc(vxlan, mac, state, src_vni, ndm_flags);
if (!f)
return -ENOMEM;
rc = vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
if (rc < 0) {
kfree(f);
return rc;
}
++vxlan->addrcnt;
hlist_add_head_rcu(&f->hlist,
vxlan_fdb_head(vxlan, mac, src_vni));
*fdb = f;
return 0;
}
/* Add new entry to forwarding table -- assumes lock held */
static int vxlan_fdb_update(struct vxlan_dev *vxlan,
const u8 *mac, union vxlan_addr *ip, const u8 *mac, union vxlan_addr *ip,
__u16 state, __u16 flags, __u16 state, __u16 flags,
__be16 port, __be32 src_vni, __be32 vni, __be16 port, __be32 src_vni, __be32 vni,
...@@ -687,37 +740,17 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, ...@@ -687,37 +740,17 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
if (!(flags & NLM_F_CREATE)) if (!(flags & NLM_F_CREATE))
return -ENOENT; return -ENOENT;
if (vxlan->cfg.addrmax &&
vxlan->addrcnt >= vxlan->cfg.addrmax)
return -ENOSPC;
/* Disallow replace to add a multicast entry */ /* Disallow replace to add a multicast entry */
if ((flags & NLM_F_REPLACE) && if ((flags & NLM_F_REPLACE) &&
(is_multicast_ether_addr(mac) || is_zero_ether_addr(mac))) (is_multicast_ether_addr(mac) || is_zero_ether_addr(mac)))
return -EOPNOTSUPP; return -EOPNOTSUPP;
netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip); netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip);
f = kmalloc(sizeof(*f), GFP_ATOMIC); rc = vxlan_fdb_create(vxlan, mac, ip, state, port, src_vni,
if (!f) vni, ifindex, ndm_flags, &f);
return -ENOMEM; if (rc < 0)
notify = 1;
f->state = state;
f->flags = ndm_flags;
f->updated = f->used = jiffies;
f->vni = src_vni;
INIT_LIST_HEAD(&f->remotes);
memcpy(f->eth_addr, mac, ETH_ALEN);
rc = vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
if (rc < 0) {
kfree(f);
return rc; return rc;
} notify = 1;
++vxlan->addrcnt;
hlist_add_head_rcu(&f->hlist,
vxlan_fdb_head(vxlan, mac, src_vni));
} }
if (notify) { if (notify) {
...@@ -863,7 +896,7 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], ...@@ -863,7 +896,7 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
spin_lock_bh(&vxlan->hash_lock); spin_lock_bh(&vxlan->hash_lock);
err = vxlan_fdb_create(vxlan, addr, &ip, ndm->ndm_state, flags, err = vxlan_fdb_update(vxlan, addr, &ip, ndm->ndm_state, flags,
port, src_vni, vni, ifindex, ndm->ndm_flags); port, src_vni, vni, ifindex, ndm->ndm_flags);
spin_unlock_bh(&vxlan->hash_lock); spin_unlock_bh(&vxlan->hash_lock);
...@@ -1006,7 +1039,7 @@ static bool vxlan_snoop(struct net_device *dev, ...@@ -1006,7 +1039,7 @@ static bool vxlan_snoop(struct net_device *dev,
/* close off race between vxlan_flush and incoming packets */ /* close off race between vxlan_flush and incoming packets */
if (netif_running(dev)) if (netif_running(dev))
vxlan_fdb_create(vxlan, src_mac, src_ip, vxlan_fdb_update(vxlan, src_mac, src_ip,
NUD_REACHABLE, NUD_REACHABLE,
NLM_F_EXCL|NLM_F_CREATE, NLM_F_EXCL|NLM_F_CREATE,
vxlan->cfg.dst_port, vxlan->cfg.dst_port,
...@@ -3170,7 +3203,7 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev, ...@@ -3170,7 +3203,7 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev,
/* create an fdb entry for a valid default destination */ /* create an fdb entry for a valid default destination */
if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) { if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) {
err = vxlan_fdb_create(vxlan, all_zeros_mac, err = vxlan_fdb_update(vxlan, all_zeros_mac,
&vxlan->default_dst.remote_ip, &vxlan->default_dst.remote_ip,
NUD_REACHABLE | NUD_PERMANENT, NUD_REACHABLE | NUD_PERMANENT,
NLM_F_EXCL | NLM_F_CREATE, NLM_F_EXCL | NLM_F_CREATE,
...@@ -3450,7 +3483,7 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], ...@@ -3450,7 +3483,7 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
old_dst.remote_ifindex, 0); old_dst.remote_ifindex, 0);
if (!vxlan_addr_any(&dst->remote_ip)) { if (!vxlan_addr_any(&dst->remote_ip)) {
err = vxlan_fdb_create(vxlan, all_zeros_mac, err = vxlan_fdb_update(vxlan, all_zeros_mac,
&dst->remote_ip, &dst->remote_ip,
NUD_REACHABLE | NUD_PERMANENT, NUD_REACHABLE | NUD_PERMANENT,
NLM_F_CREATE | NLM_F_APPEND, NLM_F_CREATE | NLM_F_APPEND,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment