return 1;
}
-static int link_reconfigure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, bool force) {
+static int link_reconfigure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, bool force, bool update_wifi) {
+ bool link_was_lower_up;
int r;
+ assert(link);
+
+ link_was_lower_up = link->flags & IFF_LOWER_UP;
+
r = link_getlink_handler_internal(rtnl, m, link, "Failed to update link state");
if (r <= 0)
return r;
+ if (update_wifi && link_was_lower_up && link->flags & IFF_LOWER_UP) {
+ /* If the interface's L1 was not up, then wifi_get_info() is already called in
+ * link_update_flags(). So, it is not necessary to re-call here. */
+ r = wifi_get_info(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return 0;
+ }
+ }
+
r = link_reconfigure_impl(link, force);
- if (r < 0)
+ if (r < 0) {
link_enter_failed(link);
+ return 0;
+ }
- return 0;
+ return r;
}
static int link_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- return link_reconfigure_handler_internal(rtnl, m, link, false);
+ return link_reconfigure_handler_internal(rtnl, m, link, /* force = */ false, /* update_wifi = */ false);
}
static int link_force_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- return link_reconfigure_handler_internal(rtnl, m, link, true);
+ return link_reconfigure_handler_internal(rtnl, m, link, /* force = */ true, /* update_wifi = */ false);
}
-int link_reconfigure(Link *link, bool force) {
+static int link_reconfigure_after_sleep_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
+ assert(link);
+
+ r = link_reconfigure_handler_internal(rtnl, m, link, /* force = */ false, /* update_wifi = */ true);
+ if (r != 0)
+ return r;
+
+ /* r == 0 means an error occurs, the link is unmanaged, or the matching network file is unchanged. */
+ if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
+ return 0;
+
+ /* re-request static configs, and restart engines. */
+ r = link_stop_engines(link, false);
+ if (r < 0) {
+ link_enter_failed(link);
+ return 0;
+ }
+
+ r = link_acquire_dynamic_conf(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return 0;
+ }
+
+ r = link_request_static_configs(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return 0;
+ }
+
+ return 0;
+}
+
+static int link_reconfigure_internal(Link *link, link_netlink_message_handler_t callback) {
+ int r;
+
+ assert(link);
+ assert(callback);
+
/* When link in pending or initialized state, then link_configure() will be called. To prevent
* the function from being called multiple times simultaneously, refuse to reconfigure the
* interface in these cases. */
if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_INITIALIZED, LINK_STATE_LINGER))
return 0; /* 0 means no-op. */
- r = link_call_getlink(link, force ? link_force_reconfigure_handler : link_reconfigure_handler);
+ r = link_call_getlink(link, callback);
if (r < 0)
return r;
return 1; /* 1 means the interface will be reconfigured. */
}
+int link_reconfigure(Link *link, bool force) {
+ return link_reconfigure_internal(link, force ? link_force_reconfigure_handler : link_reconfigure_handler);
+}
+
+int link_reconfigure_after_sleep(Link *link) {
+ return link_reconfigure_internal(link, link_reconfigure_after_sleep_handler);
+}
+
static int link_initialized_and_synced(Link *link) {
Network *network;
int r;
return 0;
}
-int link_carrier_reset(Link *link) {
- int r;
-
- assert(link);
-
- if (!link_has_carrier(link))
- return 0;
-
- r = link_carrier_lost(link);
- if (r < 0)
- return r;
-
- r = link_carrier_gained(link);
- if (r < 0)
- return r;
-
- log_link_info(link, "Reset carrier");
- return 0;
-}
-
static int link_admin_state_up(Link *link) {
int r;