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;
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;
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;
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;
}
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;
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;
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,