net: bridge: mdb: push notifications in __br_mdb_add/del
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Mon, 7 Sep 2020 09:56:11 +0000 (12:56 +0300)
committerJakub Kicinski <kuba@kernel.org>
Mon, 7 Sep 2020 20:16:35 +0000 (13:16 -0700)
This change is in preparation for using the mdb port group entries when
sending a notification, so their full state and additional attributes can
be filled in.

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/bridge/br_mdb.c

index 9dc12ce..24f6ccf 100644 (file)
@@ -681,7 +681,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
 }
 
 static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
-                           struct br_ip *group, unsigned char state)
+                           struct br_ip *group, struct br_mdb_entry *entry)
 {
        struct net_bridge_mdb_entry *mp;
        struct net_bridge_port_group *p;
@@ -700,12 +700,13 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
        /* host join */
        if (!port) {
                /* don't allow any flags for host-joined groups */
-               if (state)
+               if (entry->state)
                        return -EINVAL;
                if (mp->host_joined)
                        return -EEXIST;
 
                br_multicast_host_join(mp, false);
+               __br_mdb_notify(br->dev, NULL, entry, RTM_NEWMDB);
 
                return 0;
        }
@@ -719,13 +720,14 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
                        break;
        }
 
-       p = br_multicast_new_port_group(port, group, *pp, state, NULL,
+       p = br_multicast_new_port_group(port, group, *pp, entry->state, NULL,
                                        MCAST_EXCLUDE);
        if (unlikely(!p))
                return -ENOMEM;
        rcu_assign_pointer(*pp, p);
-       if (state == MDB_TEMPORARY)
+       if (entry->state == MDB_TEMPORARY)
                mod_timer(&p->timer, now + br->multicast_membership_interval);
+       __br_mdb_notify(br->dev, port, entry, RTM_NEWMDB);
 
        return 0;
 }
@@ -754,7 +756,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
        __mdb_entry_to_br_ip(entry, &ip);
 
        spin_lock_bh(&br->multicast_lock);
-       ret = br_mdb_add_group(br, p, &ip, entry->state);
+       ret = br_mdb_add_group(br, p, &ip, entry);
        spin_unlock_bh(&br->multicast_lock);
        return ret;
 }
@@ -799,12 +801,9 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh,
                        err = __br_mdb_add(net, br, entry);
                        if (err)
                                break;
-                       __br_mdb_notify(dev, p, entry, RTM_NEWMDB);
                }
        } else {
                err = __br_mdb_add(net, br, entry);
-               if (!err)
-                       __br_mdb_notify(dev, p, entry, RTM_NEWMDB);
        }
 
        return err;
@@ -832,6 +831,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
        if (entry->ifindex == mp->br->dev->ifindex && mp->host_joined) {
                br_multicast_host_leave(mp, false);
                err = 0;
+               __br_mdb_notify(br->dev, NULL, entry, RTM_DELMDB);
                if (!mp->ports && netif_running(br->dev))
                        mod_timer(&mp->timer, jiffies);
                goto unlock;
@@ -894,13 +894,9 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
                list_for_each_entry(v, &vg->vlan_list, vlist) {
                        entry->vid = v->vid;
                        err = __br_mdb_del(br, entry);
-                       if (!err)
-                               __br_mdb_notify(dev, p, entry, RTM_DELMDB);
                }
        } else {
                err = __br_mdb_del(br, entry);
-               if (!err)
-                       __br_mdb_notify(dev, p, entry, RTM_DELMDB);
        }
 
        return err;