mirror of
https://github.com/systemd/systemd.git
synced 2025-03-25 18:50:18 +03:00
Merge pull request #21737 from yuwata/network-wait-dsa-master-up
network: wait for DSA master up
This commit is contained in:
commit
402b81ffd8
@ -2550,6 +2550,23 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
|
||||
if (r < 0)
|
||||
log_link_debug_errno(link, r, "Failed to get driver, continuing without: %m");
|
||||
|
||||
if (streq_ptr(link->driver, "dsa")) {
|
||||
uint32_t dsa_master_ifindex;
|
||||
|
||||
r = sd_netlink_message_read_u32(message, IFLA_LINK, &dsa_master_ifindex);
|
||||
if (r < 0) {
|
||||
dsa_master_ifindex = 0;
|
||||
if (r != -ENODATA)
|
||||
log_link_warning_errno(link, r, "rtnl: failed to read ifindex of the DSA master interface, ignoring: %m");
|
||||
} else if (dsa_master_ifindex > INT_MAX) {
|
||||
dsa_master_ifindex = 0;
|
||||
log_link_warning(link, "rtnl: received too large DSA master ifindex (%"PRIu32" > INT_MAX), ignoring.",
|
||||
dsa_master_ifindex);
|
||||
}
|
||||
|
||||
link->dsa_master_ifindex = (int) dsa_master_ifindex;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(link);
|
||||
return 0;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ typedef struct Link {
|
||||
|
||||
int ifindex;
|
||||
int master_ifindex;
|
||||
int dsa_master_ifindex;
|
||||
char *ifname;
|
||||
char **alternative_names;
|
||||
char *kind;
|
||||
|
@ -948,7 +948,42 @@ int link_configure_mtu(Link *link) {
|
||||
return link_request_to_set_mtu(link, mtu);
|
||||
}
|
||||
|
||||
static int link_up_or_down_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, bool up, bool check_ready) {
|
||||
static int link_up_dsa_slave(Link *link) {
|
||||
Link *master;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
/* For older kernels (specifically, older than 9d5ef190e5615a7b63af89f88c4106a5bc127974, kernel-5.12),
|
||||
* it is necessary to bring up a DSA slave that its master interface is already up. And bringing up
|
||||
* the slave fails with -ENETDOWN. So, let's bring up the master even if it is not managed by us,
|
||||
* and try to bring up the slave after the master becomes up. */
|
||||
|
||||
if (link->dsa_master_ifindex <= 0)
|
||||
return 0;
|
||||
|
||||
if (!streq_ptr(link->driver, "dsa"))
|
||||
return 0;
|
||||
|
||||
if (link_get_by_index(link->manager, link->dsa_master_ifindex, &master) < 0)
|
||||
return 0;
|
||||
|
||||
if (master->state == LINK_STATE_UNMANAGED) {
|
||||
/* If the DSA master interface is unmanaged, then it will never become up.
|
||||
* Let's request to bring up the master. */
|
||||
r = link_request_to_bring_up_or_down(master, /* up = */ true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = link_request_to_bring_up_or_down(link, /* up = */ true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_up_or_down_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, bool up, bool on_activate) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -958,10 +993,19 @@ static int link_up_or_down_handler_internal(sd_netlink *rtnl, sd_netlink_message
|
||||
goto on_error;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0)
|
||||
log_link_message_warning_errno(link, m, r, up ?
|
||||
"Could not bring up interface, ignoring" :
|
||||
"Could not bring down interface, ignoring");
|
||||
if (r == -ENETDOWN && up && link_up_dsa_slave(link) > 0)
|
||||
log_link_message_debug_errno(link, m, r, "Could not bring up dsa slave, retrying again after dsa master becomes up");
|
||||
else if (r < 0) {
|
||||
const char *error_msg;
|
||||
|
||||
error_msg = up ?
|
||||
(on_activate ? "Could not bring up interface" : "Could not bring up interface, ignoring") :
|
||||
(on_activate ? "Could not bring down interface" : "Could not bring down interface, ignoring");
|
||||
|
||||
log_link_message_warning_errno(link, m, r, error_msg);
|
||||
if (on_activate)
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
r = link_call_getlink(link, get_link_update_flag_handler);
|
||||
if (r < 0) {
|
||||
@ -969,7 +1013,7 @@ static int link_up_or_down_handler_internal(sd_netlink *rtnl, sd_netlink_message
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
if (check_ready) {
|
||||
if (on_activate) {
|
||||
link->activated = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
@ -984,19 +1028,19 @@ on_error:
|
||||
}
|
||||
|
||||
static int link_activate_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
return link_up_or_down_handler_internal(rtnl, m, link, true, true);
|
||||
return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ true, /* on_activate = */ true);
|
||||
}
|
||||
|
||||
static int link_activate_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
return link_up_or_down_handler_internal(rtnl, m, link, false, true);
|
||||
return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ false, /* on_activate = */ true);
|
||||
}
|
||||
|
||||
static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
return link_up_or_down_handler_internal(rtnl, m, link, true, false);
|
||||
return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ true, /* on_activate = */ false);
|
||||
}
|
||||
|
||||
static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
return link_up_or_down_handler_internal(rtnl, m, link, false, false);
|
||||
return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ false, /* on_activate = */ false);
|
||||
}
|
||||
|
||||
static const char *up_or_down(bool up) {
|
||||
@ -1123,9 +1167,21 @@ int link_request_to_activate(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool link_is_ready_to_bring_up_or_down(Link *link) {
|
||||
static bool link_is_ready_to_bring_up_or_down(Link *link, bool up) {
|
||||
assert(link);
|
||||
|
||||
if (up && link->dsa_master_ifindex > 0) {
|
||||
Link *master;
|
||||
|
||||
/* The master inteface must be up. See comments in link_up_dsa_slave(). */
|
||||
|
||||
if (link_get_by_index(link->manager, link->dsa_master_ifindex, &master) < 0)
|
||||
return false;
|
||||
|
||||
if (!FLAGS_SET(master->flags, IFF_UP))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (link->state == LINK_STATE_UNMANAGED)
|
||||
return true;
|
||||
|
||||
@ -1153,7 +1209,7 @@ int request_process_link_up_or_down(Request *req) {
|
||||
link = req->link;
|
||||
up = PTR_TO_INT(req->userdata);
|
||||
|
||||
if (!link_is_ready_to_bring_up_or_down(link))
|
||||
if (!link_is_ready_to_bring_up_or_down(link, up))
|
||||
return 0;
|
||||
|
||||
r = link_up_or_down(link, up, req->netlink_handler);
|
||||
|
Loading…
x
Reference in New Issue
Block a user