]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: configure bridge MDB entries after bridge has carrier
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 15 Sep 2020 07:20:36 +0000 (16:20 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 16 Sep 2020 15:04:22 +0000 (00:04 +0900)
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-mdb.c
src/network/networkd-mdb.h

index 4ab003280a38b2d0c527148ff1ec24641bb0ee5b..4194dcb1bbbd5e8b09192afb1764f697aacaa4bf 100644 (file)
@@ -1157,6 +1157,11 @@ void link_check_ready(Link *link) {
                 return;
         }
 
+        if (!link->bridge_mdb_configured) {
+                log_link_debug(link, "%s(): Bridge MDB is not configured.", __func__);
+                return;
+        }
+
         if (link_has_carrier(link) || !link->network->configure_without_carrier) {
                 bool has_ndisc_address = false;
                 NDiscAddress *n;
@@ -1254,22 +1259,6 @@ static int link_set_bridge_fdb(Link *link) {
         return 0;
 }
 
-static int link_set_bridge_mdb(Link *link) {
-        MdbEntry *mdb_entry;
-        int r;
-
-        if (!link->network)
-                return 0;
-
-        LIST_FOREACH(static_mdb_entries, mdb_entry, link->network->static_mdb_entries) {
-                r = mdb_entry_configure(link, mdb_entry);
-                if (r < 0)
-                        return log_link_error_errno(link, r, "Failed to add entry to multicast group database: %m");
-        }
-
-        return 0;
-}
-
 static int static_address_ready_callback(Address *address) {
         Address *a;
         Link *link;
@@ -1402,6 +1391,10 @@ static int link_request_set_addresses(Link *link) {
         if (r < 0)
                 return r;
 
+        r = link_set_bridge_mdb(link);
+        if (r < 0)
+                return r;
+
         r = link_request_set_neighbors(link);
         if (r < 0)
                 return r;
@@ -3923,9 +3916,24 @@ static int link_carrier_gained(Link *link) {
         if (r < 0)
                 return r;
 
-        r = link_set_bridge_mdb(link);
-        if (r < 0)
-                return r;
+        if (!link->bridge_mdb_configured) {
+                r = link_set_bridge_mdb(link);
+                if (r < 0)
+                        return r;
+        }
+
+        if (streq_ptr(link->kind, "bridge")) {
+                Link *slave;
+
+                SET_FOREACH(slave, link->slaves) {
+                        if (slave->bridge_mdb_configured)
+                                continue;
+
+                        r = link_set_bridge_mdb(slave);
+                        if (r < 0)
+                                link_enter_failed(slave);
+                }
+        }
 
         return 0;
 }
index a0c5661149fee4d1e40d17b8831bbdd2a1fe5e8e..1550db8a23926edfd0f485300d063099812cd4de 100644 (file)
@@ -85,6 +85,7 @@ typedef struct Link {
         unsigned tc_messages;
         unsigned sr_iov_messages;
         unsigned enslaving;
+        unsigned bridge_mdb_messages;
 
         Set *addresses;
         Set *addresses_foreign;
@@ -124,6 +125,7 @@ typedef struct Link {
         bool setting_mtu:1;
         bool setting_genmode:1;
         bool ipv6_mtu_set:1;
+        bool bridge_mdb_configured:1;
 
         LIST_HEAD(Address, pool_addresses);
 
index fa9daa3472dbd81b2462a307c8b09d2ca9789bb4..5d400c3a287b4f74ca03f557e14f8bd4d51fb4bc 100644 (file)
@@ -94,6 +94,9 @@ static int set_mdb_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
         int r;
 
         assert(link);
+        assert(link->bridge_mdb_messages > 0);
+
+        link->bridge_mdb_messages--;
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
@@ -105,11 +108,16 @@ static int set_mdb_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
                 return 1;
         }
 
+        if (link->bridge_mdb_messages == 0) {
+                link->bridge_mdb_configured = true;
+                link_check_ready(link);
+        }
+
         return 1;
 }
 
 /* send a request to the kernel to add an MDB entry */
-int mdb_entry_configure(Link *link, MdbEntry *mdb_entry) {
+static int mdb_entry_configure(Link *link, MdbEntry *mdb_entry) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         struct br_mdb_entry entry;
         int r;
@@ -159,6 +167,49 @@ int mdb_entry_configure(Link *link, MdbEntry *mdb_entry) {
         return 1;
 }
 
+int link_set_bridge_mdb(Link *link) {
+        MdbEntry *mdb_entry;
+        Link *master;
+        int r;
+
+        assert(link);
+
+        link->bridge_mdb_configured = false;
+
+        if (!link->network)
+                return 0;
+
+        if (!link->network->bridge) {
+                link->bridge_mdb_configured = true;
+                return 0;
+        }
+
+        if (!link_has_carrier(link))
+                return log_link_debug(link, "Link does not have carrier yet, setting MDB entries later.");
+
+        r = link_get(link->manager, link->network->bridge->ifindex, &master);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Failed to get Link object for Bridge=%s", link->network->bridge->ifname);
+
+        if (!link_has_carrier(master))
+                return log_link_debug(link, "Bridge interface %s does not have carrier yet, setting MDB entries later.", link->network->bridge->ifname);
+
+        LIST_FOREACH(static_mdb_entries, mdb_entry, link->network->static_mdb_entries) {
+                r = mdb_entry_configure(link, mdb_entry);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Failed to add MDB entry to multicast group database: %m");
+
+                link->bridge_mdb_messages++;
+        }
+
+        if (link->bridge_mdb_messages == 0) {
+                link->bridge_mdb_configured = true;
+                link_check_ready(link);
+        }
+
+        return 0;
+}
+
 /* parse the VLAN Id from config files. */
 int config_parse_mdb_vlan_id(
                 const char *unit,
index 9ac8a18188a72a1d8c27d932a47c45df2666fb83..d46ab4a50e0ecee0d6490508aeb40cf6e559eca2 100644 (file)
@@ -24,7 +24,7 @@ struct MdbEntry {
 
 int mdb_entry_verify(MdbEntry *mdb_entry);
 MdbEntry *mdb_entry_free(MdbEntry *mdb_entry);
-int mdb_entry_configure(Link *link, MdbEntry *mdb_entry);
+int link_set_bridge_mdb(Link *link);
 
 DEFINE_NETWORK_SECTION_FUNCTIONS(MdbEntry, mdb_entry_free);