networkd: link - introduce LINGER state and link_drop()
We need the LINGER state in case we still have references to the link after it has been dropped.
This commit is contained in:
parent
2cc7e981af
commit
370e9930c3
|
@ -154,6 +154,19 @@ int link_get(Manager *m, int ifindex, Link **ret) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void link_drop(Link *link) {
|
||||||
|
if (!link || link->state == LINK_STATE_LINGER)
|
||||||
|
return;
|
||||||
|
|
||||||
|
link->state = LINK_STATE_LINGER;
|
||||||
|
|
||||||
|
log_debug_link(link, "dropped");
|
||||||
|
|
||||||
|
link_unref(link);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static int link_enter_configured(Link *link) {
|
static int link_enter_configured(Link *link) {
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->state == LINK_STATE_SETTING_ROUTES);
|
assert(link->state == LINK_STATE_SETTING_ROUTES);
|
||||||
|
@ -213,7 +226,7 @@ static int link_stop_clients(Link *link) {
|
||||||
static void link_enter_failed(Link *link) {
|
static void link_enter_failed(Link *link) {
|
||||||
assert(link);
|
assert(link);
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED)
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
log_warning_link(link, "failed");
|
log_warning_link(link, "failed");
|
||||||
|
@ -230,13 +243,13 @@ static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(link->route_messages > 0);
|
assert(link->route_messages > 0);
|
||||||
assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
|
assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
|
||||||
link->state == LINK_STATE_SETTING_ROUTES ||
|
LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
|
||||||
link->state == LINK_STATE_FAILED);
|
LINK_STATE_LINGER));
|
||||||
|
|
||||||
link->route_messages --;
|
link->route_messages --;
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED) {
|
if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
|
||||||
link_unref(link);
|
link_unref(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -272,7 +285,7 @@ static int link_enter_set_routes(Link *link) {
|
||||||
link->state = LINK_STATE_SETTING_ROUTES;
|
link->state = LINK_STATE_SETTING_ROUTES;
|
||||||
|
|
||||||
if (!link->network->static_routes && !link->dhcp_lease &&
|
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);
|
return link_enter_configured(link);
|
||||||
|
|
||||||
log_debug_link(link, "setting routes");
|
log_debug_link(link, "setting routes");
|
||||||
|
@ -401,7 +414,7 @@ static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata)
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->ifname);
|
assert(link->ifname);
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED) {
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
|
||||||
link_unref(link);
|
link_unref(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -427,11 +440,12 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->ifname);
|
assert(link->ifname);
|
||||||
assert(link->addr_messages > 0);
|
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 --;
|
link->addr_messages --;
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED) {
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
|
||||||
link_unref(link);
|
link_unref(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -577,7 +591,7 @@ static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userd
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->ifname);
|
assert(link->ifname);
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED) {
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
|
||||||
link_unref(link);
|
link_unref(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -603,7 +617,7 @@ static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdat
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->ifname);
|
assert(link->ifname);
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED) {
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
|
||||||
link_unref(link);
|
link_unref(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -627,6 +641,11 @@ static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
|
||||||
|
|
||||||
assert(link);
|
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);
|
r = sd_bus_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning("Could not set hostname: %s", strerror(-r));
|
log_warning("Could not set hostname: %s", strerror(-r));
|
||||||
|
@ -682,7 +701,7 @@ static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->ifname);
|
assert(link->ifname);
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED) {
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
|
||||||
link_unref(link);
|
link_unref(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -933,7 +952,7 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||||
assert(link->network);
|
assert(link->network);
|
||||||
assert(link->manager);
|
assert(link->manager);
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED)
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -1128,6 +1147,9 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
|
||||||
assert(link->network);
|
assert(link->network);
|
||||||
assert(link->manager);
|
assert(link->manager);
|
||||||
|
|
||||||
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||||
|
return;
|
||||||
|
|
||||||
switch(event) {
|
switch(event) {
|
||||||
case IPV4LL_EVENT_STOP:
|
case IPV4LL_EVENT_STOP:
|
||||||
case IPV4LL_EVENT_CONFLICT:
|
case IPV4LL_EVENT_CONFLICT:
|
||||||
|
@ -1335,7 +1357,7 @@ static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||||
|
|
||||||
assert(link);
|
assert(link);
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED) {
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
|
||||||
link_unref(link);
|
link_unref(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1417,12 +1439,13 @@ static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(link);
|
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);
|
assert(link->network);
|
||||||
|
|
||||||
link->enslaving --;
|
link->enslaving --;
|
||||||
|
|
||||||
if (link->state == LINK_STATE_FAILED) {
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
|
||||||
link_unref(link);
|
link_unref(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1784,6 +1807,11 @@ int link_save(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (link->state == LINK_STATE_LINGER) {
|
||||||
|
unlink(link->state_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
admin_state = link_state_to_string(link->state);
|
admin_state = link_state_to_string(link->state);
|
||||||
assert(admin_state);
|
assert(admin_state);
|
||||||
|
|
||||||
|
@ -1837,6 +1865,7 @@ static const char* const link_state_table[_LINK_STATE_MAX] = {
|
||||||
[LINK_STATE_CONFIGURED] = "configured",
|
[LINK_STATE_CONFIGURED] = "configured",
|
||||||
[LINK_STATE_UNMANAGED] = "unmanaged",
|
[LINK_STATE_UNMANAGED] = "unmanaged",
|
||||||
[LINK_STATE_FAILED] = "failed",
|
[LINK_STATE_FAILED] = "failed",
|
||||||
|
[LINK_STATE_LINGER] = "linger",
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
|
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
|
||||||
|
|
|
@ -114,6 +114,8 @@ void netdev_drop(NetDev *netdev) {
|
||||||
|
|
||||||
netdev->state = NETDEV_STATE_LINGER;
|
netdev->state = NETDEV_STATE_LINGER;
|
||||||
|
|
||||||
|
log_debug_netdev(netdev, "dropped");
|
||||||
|
|
||||||
netdev_cancel_callbacks(netdev);
|
netdev_cancel_callbacks(netdev);
|
||||||
|
|
||||||
netdev_unref(netdev);
|
netdev_unref(netdev);
|
||||||
|
|
|
@ -195,6 +195,7 @@ typedef enum LinkState {
|
||||||
LINK_STATE_CONFIGURED,
|
LINK_STATE_CONFIGURED,
|
||||||
LINK_STATE_UNMANAGED,
|
LINK_STATE_UNMANAGED,
|
||||||
LINK_STATE_FAILED,
|
LINK_STATE_FAILED,
|
||||||
|
LINK_STATE_LINGER,
|
||||||
_LINK_STATE_MAX,
|
_LINK_STATE_MAX,
|
||||||
_LINK_STATE_INVALID = -1
|
_LINK_STATE_INVALID = -1
|
||||||
} LinkState;
|
} LinkState;
|
||||||
|
@ -370,6 +371,7 @@ Link *link_unref(Link *link);
|
||||||
Link *link_ref(Link *link);
|
Link *link_ref(Link *link);
|
||||||
int link_get(Manager *m, int ifindex, Link **ret);
|
int link_get(Manager *m, int ifindex, Link **ret);
|
||||||
int link_add(Manager *manager, sd_rtnl_message *message, Link **ret);
|
int link_add(Manager *manager, sd_rtnl_message *message, Link **ret);
|
||||||
|
void link_drop(Link *link);
|
||||||
|
|
||||||
int link_update(Link *link, sd_rtnl_message *message);
|
int link_update(Link *link, sd_rtnl_message *message);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue