net: rtnetlink notify events for FDB NTF_SELF adds and deletes
It is useful to be able to monitor for FDB events in user space. This patch adds support to generate netlink events when a change is made to a device supporting the FDB ops. This brings embedded switches inline with the SW net/bridge which triggers events on FDB updates as well. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d83b060360
commit
3ff661c38c
|
@ -2011,6 +2011,33 @@ nla_put_failure:
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline size_t rtnl_fdb_nlmsg_size(void)
|
||||||
|
{
|
||||||
|
return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, int type)
|
||||||
|
{
|
||||||
|
struct net *net = dev_net(dev);
|
||||||
|
struct sk_buff *skb;
|
||||||
|
int err = -ENOBUFS;
|
||||||
|
|
||||||
|
skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC);
|
||||||
|
if (!skb)
|
||||||
|
goto errout;
|
||||||
|
|
||||||
|
err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF);
|
||||||
|
if (err < 0) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
|
||||||
|
return;
|
||||||
|
errout:
|
||||||
|
rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
|
||||||
|
}
|
||||||
|
|
||||||
static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
|
static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
|
||||||
{
|
{
|
||||||
struct net *net = sock_net(skb->sk);
|
struct net *net = sock_net(skb->sk);
|
||||||
|
@ -2067,8 +2094,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
|
||||||
err = dev->netdev_ops->ndo_fdb_add(ndm, dev, addr,
|
err = dev->netdev_ops->ndo_fdb_add(ndm, dev, addr,
|
||||||
nlh->nlmsg_flags);
|
nlh->nlmsg_flags);
|
||||||
|
|
||||||
if (!err)
|
if (!err) {
|
||||||
|
rtnl_fdb_notify(dev, addr, RTM_NEWNEIGH);
|
||||||
ndm->ndm_flags &= ~NTF_SELF;
|
ndm->ndm_flags &= ~NTF_SELF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
@ -2125,8 +2154,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
|
||||||
if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) {
|
if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) {
|
||||||
err = dev->netdev_ops->ndo_fdb_del(ndm, dev, addr);
|
err = dev->netdev_ops->ndo_fdb_del(ndm, dev, addr);
|
||||||
|
|
||||||
if (!err)
|
if (!err) {
|
||||||
|
rtnl_fdb_notify(dev, addr, RTM_DELNEIGH);
|
||||||
ndm->ndm_flags &= ~NTF_SELF;
|
ndm->ndm_flags &= ~NTF_SELF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Reference in New Issue