mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 08:46:46 +00:00
vxlan: introduce vxlan_fdb_parse
which will be reused by vxlan_fdb_delete Signed-off-by: Mike Rapoport <mike.rapoport@ravellosystems.com> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
This commit is contained in:
parent
a5e7c10a7e
commit
f0b074be7b
1 changed files with 51 additions and 32 deletions
|
@ -518,13 +518,60 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
|
||||||
call_rcu(&f->rcu, vxlan_fdb_free);
|
call_rcu(&f->rcu, vxlan_fdb_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
|
||||||
|
__be32 *ip, __be16 *port, u32 *vni, u32 *ifindex)
|
||||||
|
{
|
||||||
|
struct net *net = dev_net(vxlan->dev);
|
||||||
|
|
||||||
|
if (tb[NDA_DST]) {
|
||||||
|
if (nla_len(tb[NDA_DST]) != sizeof(__be32))
|
||||||
|
return -EAFNOSUPPORT;
|
||||||
|
|
||||||
|
*ip = nla_get_be32(tb[NDA_DST]);
|
||||||
|
} else {
|
||||||
|
*ip = htonl(INADDR_ANY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[NDA_PORT]) {
|
||||||
|
if (nla_len(tb[NDA_PORT]) != sizeof(__be16))
|
||||||
|
return -EINVAL;
|
||||||
|
*port = nla_get_be16(tb[NDA_PORT]);
|
||||||
|
} else {
|
||||||
|
*port = vxlan->dst_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[NDA_VNI]) {
|
||||||
|
if (nla_len(tb[NDA_VNI]) != sizeof(u32))
|
||||||
|
return -EINVAL;
|
||||||
|
*vni = nla_get_u32(tb[NDA_VNI]);
|
||||||
|
} else {
|
||||||
|
*vni = vxlan->default_dst.remote_vni;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[NDA_IFINDEX]) {
|
||||||
|
struct net_device *tdev;
|
||||||
|
|
||||||
|
if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
|
||||||
|
return -EINVAL;
|
||||||
|
*ifindex = nla_get_u32(tb[NDA_IFINDEX]);
|
||||||
|
tdev = dev_get_by_index(net, *ifindex);
|
||||||
|
if (!tdev)
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
dev_put(tdev);
|
||||||
|
} else {
|
||||||
|
*ifindex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add static entry (via netlink) */
|
/* Add static entry (via netlink) */
|
||||||
static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
const unsigned char *addr, u16 flags)
|
const unsigned char *addr, u16 flags)
|
||||||
{
|
{
|
||||||
struct vxlan_dev *vxlan = netdev_priv(dev);
|
struct vxlan_dev *vxlan = netdev_priv(dev);
|
||||||
struct net *net = dev_net(vxlan->dev);
|
/* struct net *net = dev_net(vxlan->dev); */
|
||||||
__be32 ip;
|
__be32 ip;
|
||||||
__be16 port;
|
__be16 port;
|
||||||
u32 vni, ifindex;
|
u32 vni, ifindex;
|
||||||
|
@ -539,37 +586,9 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||||
if (tb[NDA_DST] == NULL)
|
if (tb[NDA_DST] == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (nla_len(tb[NDA_DST]) != sizeof(__be32))
|
err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
|
||||||
return -EAFNOSUPPORT;
|
if (err)
|
||||||
|
return err;
|
||||||
ip = nla_get_be32(tb[NDA_DST]);
|
|
||||||
|
|
||||||
if (tb[NDA_PORT]) {
|
|
||||||
if (nla_len(tb[NDA_PORT]) != sizeof(__be16))
|
|
||||||
return -EINVAL;
|
|
||||||
port = nla_get_be16(tb[NDA_PORT]);
|
|
||||||
} else
|
|
||||||
port = vxlan->dst_port;
|
|
||||||
|
|
||||||
if (tb[NDA_VNI]) {
|
|
||||||
if (nla_len(tb[NDA_VNI]) != sizeof(u32))
|
|
||||||
return -EINVAL;
|
|
||||||
vni = nla_get_u32(tb[NDA_VNI]);
|
|
||||||
} else
|
|
||||||
vni = vxlan->default_dst.remote_vni;
|
|
||||||
|
|
||||||
if (tb[NDA_IFINDEX]) {
|
|
||||||
struct net_device *tdev;
|
|
||||||
|
|
||||||
if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
|
|
||||||
return -EINVAL;
|
|
||||||
ifindex = nla_get_u32(tb[NDA_IFINDEX]);
|
|
||||||
tdev = dev_get_by_index(net, ifindex);
|
|
||||||
if (!tdev)
|
|
||||||
return -EADDRNOTAVAIL;
|
|
||||||
dev_put(tdev);
|
|
||||||
} else
|
|
||||||
ifindex = 0;
|
|
||||||
|
|
||||||
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_create(vxlan, addr, ip, ndm->ndm_state, flags,
|
||||||
|
|
Loading…
Reference in a new issue