mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
ndo_fdb_add: Add a parameter to report whether notification was sent
Currently when FDB entries are added to or deleted from a VXLAN netdevice, the VXLAN driver emits one notification, including the VXLAN-specific attributes. The core however always sends a notification as well, a generic one. Thus two notifications are unnecessarily sent for these operations. A similar situation comes up with bridge driver, which also emits notifications on its own: # ip link add name vx type vxlan id 1000 dstport 4789 # bridge monitor fdb & [1] 1981693 # bridge fdb add de:ad:be:ef:13:37 dev vx self dst 192.0.2.1 de:ad:be:ef:13:37 dev vx dst 192.0.2.1 self permanent de:ad:be:ef:13:37 dev vx self permanent In order to prevent this duplicity, add a paremeter to ndo_fdb_add, bool *notified. The flag is primed to false, and if the callee sends a notification on its own, it sets it to true, thus informing the core that it should not generate another notification. Signed-off-by: Petr Machata <petrm@nvidia.com> Reviewed-by: Amit Cohen <amcohen@nvidia.com> Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/cbf6ae8195e85cbf922f8058ce4eba770f3b71ed.1731589511.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
2a8ce470c5
commit
4b42fbc6bd
@ -13095,12 +13095,13 @@ static int i40e_get_phys_port_id(struct net_device *netdev,
|
||||
* @addr: the MAC address entry being added
|
||||
* @vid: VLAN ID
|
||||
* @flags: instructions from stack about fdb operation
|
||||
* @notified: whether notification was emitted
|
||||
* @extack: netlink extended ack, unused currently
|
||||
*/
|
||||
static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
struct net_device *dev,
|
||||
const unsigned char *addr, u16 vid,
|
||||
u16 flags,
|
||||
u16 flags, bool *notified,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct i40e_netdev_priv *np = netdev_priv(dev);
|
||||
|
@ -6125,12 +6125,14 @@ ice_set_tx_maxrate(struct net_device *netdev, int queue_index, u32 maxrate)
|
||||
* @addr: the MAC address entry being added
|
||||
* @vid: VLAN ID
|
||||
* @flags: instructions from stack about fdb operation
|
||||
* @notified: whether notification was emitted
|
||||
* @extack: netlink extended ack
|
||||
*/
|
||||
static int
|
||||
ice_fdb_add(struct ndmsg *ndm, struct nlattr __always_unused *tb[],
|
||||
struct net_device *dev, const unsigned char *addr, u16 vid,
|
||||
u16 flags, struct netlink_ext_ack __always_unused *extack)
|
||||
u16 flags, bool *notified,
|
||||
struct netlink_ext_ack __always_unused *extack)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -2486,7 +2486,7 @@ static int igb_set_features(struct net_device *netdev,
|
||||
static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
struct net_device *dev,
|
||||
const unsigned char *addr, u16 vid,
|
||||
u16 flags,
|
||||
u16 flags, bool *notified,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
/* guarantee we can provide a unique filter for the unicast address */
|
||||
|
@ -9954,7 +9954,7 @@ static int ixgbe_set_features(struct net_device *netdev,
|
||||
static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
struct net_device *dev,
|
||||
const unsigned char *addr, u16 vid,
|
||||
u16 flags,
|
||||
u16 flags, bool *notified,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
/* guarantee we can provide a unique filter for the unicast address */
|
||||
|
@ -730,7 +730,7 @@ static void ocelot_get_stats64(struct net_device *dev,
|
||||
static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
struct net_device *dev,
|
||||
const unsigned char *addr,
|
||||
u16 vid, u16 flags,
|
||||
u16 vid, u16 flags, bool *notified,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct ocelot_port_private *priv = netdev_priv(dev);
|
||||
|
@ -394,7 +394,7 @@ static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
struct net_device *netdev,
|
||||
const unsigned char *addr, u16 vid, u16 flags,
|
||||
struct netlink_ext_ack *extack)
|
||||
bool *notified, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct qlcnic_adapter *adapter = netdev_priv(netdev);
|
||||
int err = 0;
|
||||
|
@ -1024,7 +1024,7 @@ static int macvlan_vlan_rx_kill_vid(struct net_device *dev,
|
||||
static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
struct net_device *dev,
|
||||
const unsigned char *addr, u16 vid,
|
||||
u16 flags,
|
||||
u16 flags, bool *notified,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct macvlan_dev *vlan = netdev_priv(dev);
|
||||
|
@ -1241,7 +1241,7 @@ static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
|
||||
static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
struct net_device *dev,
|
||||
const unsigned char *addr, u16 vid, u16 flags,
|
||||
struct netlink_ext_ack *extack)
|
||||
bool *notified, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct vxlan_dev *vxlan = netdev_priv(dev);
|
||||
/* struct net *net = dev_net(vxlan->dev); */
|
||||
@ -1277,6 +1277,9 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
nhid, true, extack);
|
||||
spin_unlock_bh(&vxlan->hash_lock[hash_index]);
|
||||
|
||||
if (!err)
|
||||
*notified = true;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1248,8 +1248,10 @@ struct netdev_net_notifier {
|
||||
* int (*ndo_fdb_add)(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
* struct net_device *dev,
|
||||
* const unsigned char *addr, u16 vid, u16 flags,
|
||||
* struct netlink_ext_ack *extack);
|
||||
* bool *notified, struct netlink_ext_ack *extack);
|
||||
* Adds an FDB entry to dev for addr.
|
||||
* Callee shall set *notified to true if it sent any appropriate
|
||||
* notification(s). Otherwise core will send a generic one.
|
||||
* int (*ndo_fdb_del)(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
* struct net_device *dev,
|
||||
* const unsigned char *addr, u16 vid)
|
||||
@ -1525,6 +1527,7 @@ struct net_device_ops {
|
||||
const unsigned char *addr,
|
||||
u16 vid,
|
||||
u16 flags,
|
||||
bool *notified,
|
||||
struct netlink_ext_ack *extack);
|
||||
int (*ndo_fdb_del)(struct ndmsg *ndm,
|
||||
struct nlattr *tb[],
|
||||
|
@ -1152,7 +1152,7 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
|
||||
static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br,
|
||||
struct net_bridge_port *p, const unsigned char *addr,
|
||||
u16 nlh_flags, u16 vid, struct nlattr *nfea_tb[],
|
||||
struct netlink_ext_ack *extack)
|
||||
bool *notified, struct netlink_ext_ack *extack)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
@ -1183,6 +1183,8 @@ static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br,
|
||||
spin_unlock_bh(&br->hash_lock);
|
||||
}
|
||||
|
||||
if (!err)
|
||||
*notified = true;
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1195,7 +1197,7 @@ static const struct nla_policy br_nda_fdb_pol[NFEA_MAX + 1] = {
|
||||
int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
struct net_device *dev,
|
||||
const unsigned char *addr, u16 vid, u16 nlh_flags,
|
||||
struct netlink_ext_ack *extack)
|
||||
bool *notified, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nlattr *nfea_tb[NFEA_MAX + 1], *attr;
|
||||
struct net_bridge_vlan_group *vg;
|
||||
@ -1258,10 +1260,10 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
|
||||
/* VID was specified, so use it. */
|
||||
err = __br_fdb_add(ndm, br, p, addr, nlh_flags, vid, nfea_tb,
|
||||
extack);
|
||||
notified, extack);
|
||||
} else {
|
||||
err = __br_fdb_add(ndm, br, p, addr, nlh_flags, 0, nfea_tb,
|
||||
extack);
|
||||
notified, extack);
|
||||
if (err || !vg || !vg->num_vlans)
|
||||
goto out;
|
||||
|
||||
@ -1273,7 +1275,7 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||
if (!br_vlan_should_use(v))
|
||||
continue;
|
||||
err = __br_fdb_add(ndm, br, p, addr, nlh_flags, v->vid,
|
||||
nfea_tb, extack);
|
||||
nfea_tb, notified, extack);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
@ -858,7 +858,7 @@ int br_fdb_delete_bulk(struct nlmsghdr *nlh, struct net_device *dev,
|
||||
struct netlink_ext_ack *extack);
|
||||
int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev,
|
||||
const unsigned char *addr, u16 vid, u16 nlh_flags,
|
||||
struct netlink_ext_ack *extack);
|
||||
bool *notified, struct netlink_ext_ack *extack);
|
||||
int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
||||
struct net_device *dev, struct net_device *fdev, int *idx);
|
||||
int br_fdb_get(struct sk_buff *skb, struct nlattr *tb[], struct net_device *dev,
|
||||
|
@ -4578,9 +4578,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
netif_is_bridge_port(dev)) {
|
||||
struct net_device *br_dev = netdev_master_upper_dev_get(dev);
|
||||
const struct net_device_ops *ops = br_dev->netdev_ops;
|
||||
bool notified = false;
|
||||
|
||||
err = ops->ndo_fdb_add(ndm, tb, dev, addr, vid,
|
||||
nlh->nlmsg_flags, extack);
|
||||
nlh->nlmsg_flags, ¬ified, extack);
|
||||
if (err)
|
||||
goto out;
|
||||
else
|
||||
@ -4589,16 +4590,18 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
|
||||
/* Embedded bridge, macvlan, and any other device support */
|
||||
if ((ndm->ndm_flags & NTF_SELF)) {
|
||||
bool notified = false;
|
||||
|
||||
if (dev->netdev_ops->ndo_fdb_add)
|
||||
err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
|
||||
vid,
|
||||
nlh->nlmsg_flags,
|
||||
extack);
|
||||
¬ified, extack);
|
||||
else
|
||||
err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
|
||||
nlh->nlmsg_flags);
|
||||
|
||||
if (!err) {
|
||||
if (!err && !notified) {
|
||||
rtnl_fdb_notify(dev, addr, vid, RTM_NEWNEIGH,
|
||||
ndm->ndm_state);
|
||||
ndm->ndm_flags &= ~NTF_SELF;
|
||||
|
Loading…
Reference in New Issue
Block a user