From c8bae3637212daad992323d4b2a253c3949c9777 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 15 Oct 2020 07:24:17 +0900 Subject: [PATCH 1/8] libsystemd-network: do not request each daemon exist in sd_xxx_stop() --- src/libsystemd-network/sd-dhcp-client.c | 5 +++-- src/libsystemd-network/sd-dhcp-server.c | 3 ++- src/libsystemd-network/sd-dhcp6-client.c | 3 ++- src/libsystemd-network/sd-ipv4acd.c | 3 ++- src/libsystemd-network/sd-ipv4ll.c | 3 ++- src/libsystemd-network/sd-lldp.c | 3 ++- src/libsystemd-network/sd-ndisc.c | 3 ++- src/libsystemd-network/sd-radv.c | 3 ++- 8 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 6eb3c1b7a0..53c4350874 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -2135,9 +2135,10 @@ int sd_dhcp_client_send_decline(sd_dhcp_client *client) { } int sd_dhcp_client_stop(sd_dhcp_client *client) { - DHCP_CLIENT_DONT_DESTROY(client); + if (!client) + return 0; - assert_return(client, -EINVAL); + DHCP_CLIENT_DONT_DESTROY(client); client_stop(client, SD_DHCP_CLIENT_EVENT_STOP); client->state = DHCP_STATE_STOPPED; diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index a34a55919e..9022aefccb 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -225,7 +225,8 @@ sd_event *sd_dhcp_server_get_event(sd_dhcp_server *server) { } int sd_dhcp_server_stop(sd_dhcp_server *server) { - assert_return(server, -EINVAL); + if (!server) + return 0; server->receive_message = sd_event_source_unref(server->receive_message); diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index e1dbdaff4e..6d27c4685e 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -1676,7 +1676,8 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { } int sd_dhcp6_client_stop(sd_dhcp6_client *client) { - assert_return(client, -EINVAL); + if (!client) + return 0; client_stop(client, SD_DHCP6_CLIENT_EVENT_STOP); diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index ecd91cd927..ff333914e9 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -144,7 +144,8 @@ static void ipv4acd_client_notify(sd_ipv4acd *acd, int event) { int sd_ipv4acd_stop(sd_ipv4acd *acd) { IPv4ACDState old_state; - assert_return(acd, -EINVAL); + if (!acd) + return 0; old_state = acd->state; diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index 4f4d9ebe87..293a4644a2 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -89,7 +89,8 @@ int sd_ipv4ll_new(sd_ipv4ll **ret) { } int sd_ipv4ll_stop(sd_ipv4ll *ll) { - assert_return(ll, -EINVAL); + if (!ll) + return 0; return sd_ipv4acd_stop(ll->acd); } diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c index b0a11fe20b..e536f90d19 100644 --- a/src/libsystemd-network/sd-lldp.c +++ b/src/libsystemd-network/sd-lldp.c @@ -276,7 +276,8 @@ fail: } _public_ int sd_lldp_stop(sd_lldp *lldp) { - assert_return(lldp, -EINVAL); + if (!lldp) + return 0; if (lldp->fd < 0) return 0; diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 9922203ac4..92e772d352 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -321,7 +321,8 @@ static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata } _public_ int sd_ndisc_stop(sd_ndisc *nd) { - assert_return(nd, -EINVAL); + if (!nd) + return 0; if (nd->fd < 0) return 0; diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c index 016808667c..9656d7c969 100644 --- a/src/libsystemd-network/sd-radv.c +++ b/src/libsystemd-network/sd-radv.c @@ -353,7 +353,8 @@ fail: _public_ int sd_radv_stop(sd_radv *ra) { int r; - assert_return(ra, -EINVAL); + if (!ra) + return 0; if (ra->state == SD_RADV_STATE_IDLE) return 0; From 84add3cd2b4b590d993b04b83aaedd20439ea4b2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 15 Oct 2020 07:38:45 +0900 Subject: [PATCH 2/8] network: drop conditions to check existence of each engine --- src/network/networkd-address.c | 3 --- src/network/networkd-dhcp4.c | 3 +-- src/network/networkd-link.c | 48 +++++++++++++--------------------- 3 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index a6f8bcac14..61ed499500 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1443,9 +1443,6 @@ int ipv4_dad_stop(Link *link) { assert(link); SET_FOREACH(address, link->addresses) { - if (!address->acd) - continue; - k = sd_ipv4acd_stop(address->acd); if (k < 0 && r >= 0) r = k; diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 2920e615f3..24501c13da 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -563,8 +563,7 @@ static int dhcp_lease_lost(Link *link) { link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease); link_dirty(link); - if (link->dhcp_acd) - (void) sd_ipv4acd_stop(link->dhcp_acd); + (void) sd_ipv4acd_stop(link->dhcp_acd); return r; } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 928e883dcc..87ea5514b3 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -617,49 +617,39 @@ int link_stop_clients(Link *link, bool may_keep_dhcp) { (link->manager->restarting || FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP_ON_STOP)); - if (link->dhcp_client && !keep_dhcp) { + if (!keep_dhcp) { k = sd_dhcp_client_stop(link->dhcp_client); if (k < 0) r = log_link_warning_errno(link, k, "Could not stop DHCPv4 client: %m"); } - if (link->dhcp_acd) { - k = sd_ipv4acd_stop(link->dhcp_acd); - if (k < 0) - r = log_link_warning_errno(link, k, "Could not stop IPv4 ACD client for DHCPv4: %m"); - } + k = sd_ipv4acd_stop(link->dhcp_acd); + if (k < 0) + r = log_link_warning_errno(link, k, "Could not stop IPv4 ACD client for DHCPv4: %m"); - if (link->ipv4ll) { - k = sd_ipv4ll_stop(link->ipv4ll); - if (k < 0) - r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m"); - } + k = sd_ipv4ll_stop(link->ipv4ll); + if (k < 0) + r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m"); k = ipv4_dad_stop(link); if (k < 0) r = log_link_warning_errno(link, k, "Could not stop IPv4 ACD client: %m"); - if (link->dhcp6_client) { - k = sd_dhcp6_client_stop(link->dhcp6_client); - if (k < 0) - r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m"); - } + k = sd_dhcp6_client_stop(link->dhcp6_client); + if (k < 0) + r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m"); k = dhcp6_pd_remove(link); if (k < 0) r = log_link_warning_errno(link, k, "Could not remove DHCPv6 PD addresses and routes: %m"); - if (link->ndisc) { - k = sd_ndisc_stop(link->ndisc); - if (k < 0) - r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m"); - } + k = sd_ndisc_stop(link->ndisc); + if (k < 0) + r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m"); - if (link->radv) { - k = sd_radv_stop(link->radv); - if (k < 0) - r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m"); - } + k = sd_radv_stop(link->radv); + if (k < 0) + r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m"); link_lldp_emit_stop(link); return r; @@ -2094,8 +2084,7 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for if (r < 0) return r; - if (link->dhcp_server) - (void) sd_dhcp_server_stop(link->dhcp_server); + (void) sd_dhcp_server_stop(link->dhcp_server); r = link_drop_config(link); if (r < 0) @@ -2547,8 +2536,7 @@ static int link_carrier_lost(Link *link) { return r; } - if (link->dhcp_server) - (void) sd_dhcp_server_stop(link->dhcp_server); + (void) sd_dhcp_server_stop(link->dhcp_server); r = link_drop_config(link); if (r < 0) From c6a7531e0eb7930beee6103ca42640aa62f18f10 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 15 Oct 2020 07:39:40 +0900 Subject: [PATCH 3/8] network: voidify sd_ipv4acd_stop() at one place --- src/network/networkd-address.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 61ed499500..d006199ab0 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1341,7 +1341,7 @@ static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) { assert_not_reached("Invalid IPv4ACD event."); } - sd_ipv4acd_stop(acd); + (void) sd_ipv4acd_stop(acd); return; } From a391901eb2184413fa10a37f1635bf2092ac7b8e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 15 Oct 2020 07:39:55 +0900 Subject: [PATCH 4/8] network: drop unnecessary conditions sd_ipv4acd_stop() and sd_ipv4ll_stop() are idempotent. --- src/network/networkd-address.c | 8 +++----- src/network/networkd-ipv4ll.c | 8 +++----- src/network/networkd-radv.c | 8 +++----- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index d006199ab0..0b269a1ba1 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1402,11 +1402,9 @@ static int ipv4_dad_update_mac_one(Address *address) { running = sd_ipv4acd_is_running(address->acd); - if (running) { - r = sd_ipv4acd_stop(address->acd); - if (r < 0) - return r; - } + r = sd_ipv4acd_stop(address->acd); + if (r < 0) + return r; r = sd_ipv4acd_set_mac(address->acd, &address->link->mac); if (r < 0) diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index 03f29e3b66..3be395e1ad 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -207,11 +207,9 @@ int ipv4ll_update_mac(Link *link) { restart = sd_ipv4ll_is_running(link->ipv4ll) > 0; - if (restart) { - r = sd_ipv4ll_stop(link->ipv4ll); - if (r < 0) - return r; - } + r = sd_ipv4ll_stop(link->ipv4ll); + if (r < 0) + return r; r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac); if (r < 0) diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c index 1167f2865f..bb80e91b6c 100644 --- a/src/network/networkd-radv.c +++ b/src/network/networkd-radv.c @@ -697,11 +697,9 @@ int radv_update_mac(Link *link) { restart = sd_radv_is_running(link->radv); - if (restart) { - r = sd_radv_stop(link->radv); - if (r < 0) - return r; - } + r = sd_radv_stop(link->radv); + if (r < 0) + return r; r = sd_radv_set_mac(link->radv, &link->mac); if (r < 0) From 2a99eed02c6bd5a7ca1ee0d75f6b39e7f6383e19 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 15 Oct 2020 07:56:27 +0900 Subject: [PATCH 5/8] network: stop DHCPv4 server in link_stop_clients() Then, rename link_stop_clients() -> link_stop_engines(). --- src/network/networkd-link.c | 16 ++++++++-------- src/network/networkd-link.h | 2 +- src/network/networkd-manager.c | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 87ea5514b3..d0cc3aafbd 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -605,7 +605,7 @@ static void link_enter_unmanaged(Link *link) { link_dirty(link); } -int link_stop_clients(Link *link, bool may_keep_dhcp) { +int link_stop_engines(Link *link, bool may_keep_dhcp) { int r = 0, k; assert(link); @@ -627,6 +627,10 @@ int link_stop_clients(Link *link, bool may_keep_dhcp) { if (k < 0) r = log_link_warning_errno(link, k, "Could not stop IPv4 ACD client for DHCPv4: %m"); + k = sd_dhcp_server_stop(link->dhcp_server); + if (k < 0) + r = log_link_warning_errno(link, k, "Could not stop DHCPv4 server: %m"); + k = sd_ipv4ll_stop(link->ipv4ll); if (k < 0) r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m"); @@ -665,7 +669,7 @@ void link_enter_failed(Link *link) { link_set_state(link, LINK_STATE_FAILED); - (void) link_stop_clients(link, false); + (void) link_stop_engines(link, false); link_dirty(link); } @@ -2080,12 +2084,10 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for log_link_info(link, "Re-configuring with %s", network->filename); /* Dropping old .network file */ - r = link_stop_clients(link, false); + r = link_stop_engines(link, false); if (r < 0) return r; - (void) sd_dhcp_server_stop(link->dhcp_server); - r = link_drop_config(link); if (r < 0) return r; @@ -2530,14 +2532,12 @@ static int link_carrier_lost(Link *link) { if (link->setting_mtu) return 0; - r = link_stop_clients(link, false); + r = link_stop_engines(link, false); if (r < 0) { link_enter_failed(link); return r; } - (void) sd_dhcp_server_stop(link->dhcp_server); - r = link_drop_config(link); if (r < 0) return r; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 6e435796e5..a7ae2645f9 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -231,7 +231,7 @@ int link_set_mtu(Link *link, uint32_t mtu); bool link_ipv4ll_enabled(Link *link, AddressFamily mask); -int link_stop_clients(Link *link, bool may_keep_dhcp); +int link_stop_engines(Link *link, bool may_keep_dhcp); const char* link_state_to_string(LinkState s) _const_; LinkState link_state_from_string(const char *s) _pure_; diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 2cd6830072..b5aba1f1dc 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -864,7 +864,7 @@ void manager_free(Manager *m) { free(m->state_file); HASHMAP_FOREACH(link, m->links) - (void) link_stop_clients(link, true); + (void) link_stop_engines(link, true); m->dhcp6_prefixes = hashmap_free_with_destructor(m->dhcp6_prefixes, dhcp6_pd_free); m->dhcp6_pd_prefixes = set_free_with_destructor(m->dhcp6_pd_prefixes, dhcp6_pd_free); From 9cc65242d76d6f23bdf0a1d3ddc014a25abf57b0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 15 Oct 2020 07:57:33 +0900 Subject: [PATCH 6/8] network: also stop LLDP client in link_stop_engines() --- src/network/networkd-link.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index d0cc3aafbd..08b453f0e1 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -631,6 +631,10 @@ int link_stop_engines(Link *link, bool may_keep_dhcp) { if (k < 0) r = log_link_warning_errno(link, k, "Could not stop DHCPv4 server: %m"); + k = sd_lldp_stop(link->lldp); + if (k < 0) + r = log_link_warning_errno(link, k, "Could not stop LLDP: %m"); + k = sd_ipv4ll_stop(link->ipv4ll); if (k < 0) r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m"); From 1c49487284645a2a318f7ab2a7f2606a2cc75d53 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 15 Oct 2020 08:05:25 +0900 Subject: [PATCH 7/8] network: move link_lldp_emit_stop() to link_free_engines() This should not change any behavior. --- src/network/networkd-link.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 08b453f0e1..324128be3c 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -493,8 +493,10 @@ static void link_free_engines(Link *link) { link->dhcp_server = sd_dhcp_server_unref(link->dhcp_server); link->dhcp_client = sd_dhcp_client_unref(link->dhcp_client); link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease); + link->dhcp_acd = sd_ipv4acd_unref(link->dhcp_acd); link->lldp = sd_lldp_unref(link->lldp); + link_lldp_emit_stop(link); ndisc_flush(link); @@ -503,7 +505,6 @@ static void link_free_engines(Link *link) { link->dhcp6_lease = sd_dhcp6_lease_unref(link->dhcp6_lease); link->ndisc = sd_ndisc_unref(link->ndisc); link->radv = sd_radv_unref(link->radv); - link->dhcp_acd = sd_ipv4acd_unref(link->dhcp_acd); } static Link *link_free(Link *link) { @@ -538,7 +539,6 @@ static Link *link_free(Link *link) { link->dhcp6_pd_addresses_old = set_free(link->dhcp6_pd_addresses_old); link->ndisc_addresses = set_free(link->ndisc_addresses); - link_lldp_emit_stop(link); link_free_engines(link); free(link->lease_file); free(link->lldp_file); From 7abe175c007ce08be5f89d002b7e498c951f4537 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 15 Oct 2020 08:11:29 +0900 Subject: [PATCH 8/8] network: also unref IPv4 ACD clients in Address objects This should not change any behavior, as currently link_free_engines() is always called after all addresses are dropped. But the function may be used in other places in the future. So, let's also stop the clients. --- src/network/networkd-address.c | 9 +++++++++ src/network/networkd-address.h | 1 + src/network/networkd-link.c | 2 ++ 3 files changed, 12 insertions(+) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 0b269a1ba1..636812b556 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1449,6 +1449,15 @@ int ipv4_dad_stop(Link *link) { return r; } +void ipv4_dad_unref(Link *link) { + Address *address; + + assert(link); + + SET_FOREACH(address, link->addresses) + address->acd = sd_ipv4acd_unref(address->acd); +} + int config_parse_broadcast( const char *unit, const char *filename, diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index c0552979c5..0104747d9a 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -65,6 +65,7 @@ int link_drop_foreign_addresses(Link *link); int link_serialize_addresses(Link *link, FILE *f); int link_deserialize_addresses(Link *link, const char *addresses); +void ipv4_dad_unref(Link *link); int ipv4_dad_stop(Link *link); int ipv4_dad_update_mac(Link *link); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 324128be3c..4229e1f973 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -505,6 +505,8 @@ static void link_free_engines(Link *link) { link->dhcp6_lease = sd_dhcp6_lease_unref(link->dhcp6_lease); link->ndisc = sd_ndisc_unref(link->ndisc); link->radv = sd_radv_unref(link->radv); + + ipv4_dad_unref(link); } static Link *link_free(Link *link) {