return 0;
}
+void link_drop(Link *link) {
+ if (!link || link->state == LINK_STATE_LINGER)
+ return;
+
+ link->state = LINK_STATE_LINGER;
+
+ log_debug_link(link, "link removed");
+
+ link_unref(link);
+
+ return;
+}
+
static int link_enter_configured(Link *link) {
assert(link);
assert(link->state == LINK_STATE_SETTING_ROUTES);
static void link_enter_failed(Link *link) {
assert(link);
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return;
log_warning_link(link, "failed");
int r;
assert(link->route_messages > 0);
- assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
- link->state == LINK_STATE_SETTING_ROUTES ||
- link->state == LINK_STATE_FAILED);
+ assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
+ LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
+ LINK_STATE_LINGER));
link->route_messages --;
- if (link->state == LINK_STATE_FAILED) {
+ if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
link_unref(link);
return 1;
}
link->state = LINK_STATE_SETTING_ROUTES;
if (!link->network->static_routes && !link->dhcp_lease &&
- (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
+ (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
return link_enter_configured(link);
log_debug_link(link, "setting routes");
assert(link);
assert(link->ifname);
- if (link->state == LINK_STATE_FAILED) {
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
link_unref(link);
return 1;
}
assert(link);
assert(link->ifname);
assert(link->addr_messages > 0);
- assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
+ assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
+ LINK_STATE_FAILED, LINK_STATE_LINGER));
link->addr_messages --;
- if (link->state == LINK_STATE_FAILED) {
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
link_unref(link);
return 1;
}
assert(link);
assert(link->ifname);
- if (link->state == LINK_STATE_FAILED) {
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
link_unref(link);
return 1;
}
assert(link);
assert(link->ifname);
- if (link->state == LINK_STATE_FAILED) {
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
link_unref(link);
return 1;
}
assert(link);
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
+ return 1;
+ }
+
r = sd_bus_message_get_errno(m);
if (r < 0)
log_warning("Could not set hostname: %s", strerror(-r));
assert(link);
assert(link->ifname);
- if (link->state == LINK_STATE_FAILED) {
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
link_unref(link);
return 1;
}
assert(link->network);
assert(link->manager);
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return;
switch (event) {
assert(link->network);
assert(link->manager);
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return;
+
switch(event) {
case IPV4LL_EVENT_STOP:
case IPV4LL_EVENT_CONFLICT:
assert(link);
- if (link->state == LINK_STATE_FAILED) {
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
link_unref(link);
return 1;
}
int r;
assert(link);
- assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
+ assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
+ LINK_STATE_LINGER));
assert(link->network);
link->enslaving --;
- if (link->state == LINK_STATE_FAILED) {
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
link_unref(link);
return 1;
}
hashmap_isempty(link->network->macvlans))
return link_enslaved(link);
- if (link->network->bridge) {
+ if (link->network->bond) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%s: enslaving by '%s'",
- link->ifname, link->network->bridge->name,
- NETDEV(link->network->bridge),
+ link->ifname, link->network->bond->name,
+ NETDEV(link->network->bond),
NULL);
- r = netdev_enslave(link->network->bridge, link, &enslave_handler);
+ r = netdev_enslave(link->network->bond, link, &enslave_handler);
if (r < 0) {
log_struct_link(LOG_WARNING, link,
"MESSAGE=%s: could not enslave by '%s': %s",
- link->ifname, link->network->bridge->name, strerror(-r),
- NETDEV(link->network->bridge),
+ link->ifname, link->network->bond->name, strerror(-r),
+ NETDEV(link->network->bond),
NULL);
link_enter_failed(link);
return r;
link->enslaving ++;
}
- if (link->network->bond) {
+ if (link->network->bridge) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%s: enslaving by '%s'",
- link->ifname, link->network->bond->name,
- NETDEV(link->network->bond),
+ link->ifname, link->network->bridge->name,
+ NETDEV(link->network->bridge),
NULL);
- r = netdev_enslave(link->network->bond, link, &enslave_handler);
+ r = netdev_enslave(link->network->bridge, link, &enslave_handler);
if (r < 0) {
log_struct_link(LOG_WARNING, link,
"MESSAGE=%s: could not enslave by '%s': %s",
- link->ifname, link->network->bond->name, strerror(-r),
- NETDEV(link->network->bond),
+ link->ifname, link->network->bridge->name, strerror(-r),
+ NETDEV(link->network->bridge),
NULL);
link_enter_failed(link);
return r;
assert(link->ifname);
assert(m);
+ if (link->state == LINK_STATE_LINGER) {
+ link_ref(link);
+ log_info_link(link, "link readded");
+ link->state = LINK_STATE_ENSLAVING;
+ }
+
r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
if (r >= 0 && !streq(ifname, link->ifname)) {
log_info_link(link, "renamed to %s", ifname);
if (r < 0)
return r;
+ if (link->state == LINK_STATE_LINGER) {
+ unlink(link->state_file);
+ return 0;
+ }
+
admin_state = link_state_to_string(link->state);
assert(admin_state);
[LINK_STATE_CONFIGURED] = "configured",
[LINK_STATE_UNMANAGED] = "unmanaged",
[LINK_STATE_FAILED] = "failed",
+ [LINK_STATE_LINGER] = "linger",
};
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);