From f6bdbd9e00ceb51dd23af584d9c6b4f61f6fa71f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 4 Oct 2018 03:20:35 +0900 Subject: [PATCH 01/15] sd-netlink: fix error handling in sd_netlink_call_async() --- src/libsystemd/sd-netlink/sd-netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index 08b5707351..678f36c377 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -542,7 +542,7 @@ int sd_netlink_call_async(sd_netlink *nl, if (c->timeout != 0) { r = prioq_put(nl->reply_callbacks_prioq, c, &c->prioq_idx); - if (r > 0) { + if (r < 0) { c->timeout = 0; sd_netlink_call_async_cancel(nl, c->serial); return r; From 2fea60901da26ac354cde806d8ef8fb5170eec26 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 4 Oct 2018 03:21:52 +0900 Subject: [PATCH 02/15] sd-netlink: use structured initializers --- src/libsystemd/sd-netlink/sd-netlink.c | 35 ++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index 678f36c377..da5c0b0c3d 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -21,17 +21,23 @@ static int sd_netlink_new(sd_netlink **ret) { assert_return(ret, -EINVAL); - rtnl = new0(sd_netlink, 1); + rtnl = new(sd_netlink, 1); if (!rtnl) return -ENOMEM; - rtnl->n_ref = REFCNT_INIT; - rtnl->fd = -1; - rtnl->sockaddr.nl.nl_family = AF_NETLINK; - rtnl->original_pid = getpid_cached(); - rtnl->protocol = -1; + *rtnl = (sd_netlink) { + .n_ref = REFCNT_INIT, + .fd = -1, + .sockaddr.nl.nl_family = AF_NETLINK, + .original_pid = getpid_cached(), + .protocol = -1, - LIST_HEAD_INIT(rtnl->match_callbacks); + /* Change notification responses have sequence 0, so we must + * start our request sequence numbers at 1, or we may confuse our + * responses with notifications from the kernel */ + .serial = 1, + + }; /* We guarantee that the read buffer has at least space for * a message header */ @@ -39,11 +45,6 @@ static int sd_netlink_new(sd_netlink **ret) { sizeof(struct nlmsghdr), sizeof(uint8_t))) return -ENOMEM; - /* Change notification responses have sequence 0, so we must - * start our request sequence numbers at 1, or we may confuse our - * responses with notifications from the kernel */ - rtnl->serial = 1; - *ret = TAKE_PTR(rtnl); return 0; @@ -827,13 +828,15 @@ int sd_netlink_add_match(sd_netlink *rtnl, assert_return(callback, -EINVAL); assert_return(!rtnl_pid_changed(rtnl), -ECHILD); - c = new0(struct match_callback, 1); + c = new(struct match_callback, 1); if (!c) return -ENOMEM; - c->callback = callback; - c->type = type; - c->userdata = userdata; + *c = (struct match_callback) { + .callback = callback, + .type = type, + .userdata = userdata, + }; switch (type) { case RTM_NEWLINK: From 545bab1f0afef57dae233d376035540f2cf7a09b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 6 Oct 2018 13:38:13 +0900 Subject: [PATCH 03/15] sd-netlink: add destroy_callback argument to sd_netlink_call_async() --- src/core/loopback-setup.c | 6 +-- src/libsystemd/sd-netlink/netlink-internal.h | 1 + src/libsystemd/sd-netlink/sd-netlink.c | 57 +++++++++++++------- src/libsystemd/sd-netlink/test-netlink.c | 8 +-- src/network/netdev/bridge.c | 2 +- src/network/netdev/geneve.c | 2 +- src/network/netdev/netdev.c | 6 +-- src/network/networkd-address-label.c | 2 +- src/network/networkd-address.c | 4 +- src/network/networkd-brvlan.c | 2 +- src/network/networkd-fdb.c | 2 +- src/network/networkd-ipv6-proxy-ndp.c | 2 +- src/network/networkd-link.c | 19 +++---- src/network/networkd-route.c | 4 +- src/network/networkd-routing-policy-rule.c | 4 +- src/systemd/sd-netlink.h | 8 +-- 16 files changed, 75 insertions(+), 54 deletions(-) diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c index 835553ec8f..9380d1b09d 100644 --- a/src/core/loopback-setup.c +++ b/src/core/loopback-setup.c @@ -53,7 +53,7 @@ static int start_loopback(sd_netlink *rtnl, struct state *s) { if (r < 0) return r; - r = sd_netlink_call_async(rtnl, req, generic_handler, s, LOOPBACK_SETUP_TIMEOUT_USEC, NULL); + r = sd_netlink_call_async(rtnl, req, generic_handler, NULL, s, LOOPBACK_SETUP_TIMEOUT_USEC, NULL); if (r < 0) return r; @@ -88,7 +88,7 @@ static int add_ipv4_address(sd_netlink *rtnl, struct state *s) { if (r < 0) return r; - r = sd_netlink_call_async(rtnl, req, generic_handler, s, USEC_INFINITY, NULL); + r = sd_netlink_call_async(rtnl, req, generic_handler, NULL, s, USEC_INFINITY, NULL); if (r < 0) return r; @@ -123,7 +123,7 @@ static int add_ipv6_address(sd_netlink *rtnl, struct state *s) { if (r < 0) return r; - r = sd_netlink_call_async(rtnl, req, generic_handler, s, USEC_INFINITY, NULL); + r = sd_netlink_call_async(rtnl, req, generic_handler, NULL, s, USEC_INFINITY, NULL); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 661323e05f..8b56d34220 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -23,6 +23,7 @@ struct reply_callback { usec_t timeout; uint64_t serial; unsigned prioq_idx; + sd_netlink_destroy_t destroy_callback; }; struct match_callback { diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index da5c0b0c3d..6c8740097d 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -148,6 +148,7 @@ int sd_netlink_inc_rcvbuf(sd_netlink *rtnl, size_t size) { } static sd_netlink *netlink_free(sd_netlink *rtnl) { + struct reply_callback *c; struct match_callback *f; unsigned i; @@ -163,7 +164,12 @@ static sd_netlink *netlink_free(sd_netlink *rtnl) { free(rtnl->rbuffer); - hashmap_free_free(rtnl->reply_callbacks); + while ((c = hashmap_steal_first(rtnl->reply_callbacks))) { + if (c->destroy_callback) + c->destroy_callback(c->userdata); + free(c); + } + hashmap_free(rtnl->reply_callbacks); prioq_free(rtnl->reply_callbacks_prioq); sd_event_source_unref(rtnl->io_event_source); @@ -299,6 +305,9 @@ static int process_timeout(sd_netlink *rtnl) { if (r < 0) log_debug_errno(r, "sd-netlink: timedout callback failed: %m"); + if (c->destroy_callback) + c->destroy_callback(c->userdata); + free(c); return 1; @@ -332,6 +341,9 @@ static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) { if (r < 0) log_debug_errno(r, "sd-netlink: callback failed: %m"); + if (c->destroy_callback) + c->destroy_callback(c->userdata); + return 1; } @@ -494,13 +506,15 @@ static int timeout_compare(const void *a, const void *b) { return CMP(x->timeout, y->timeout); } -int sd_netlink_call_async(sd_netlink *nl, - sd_netlink_message *m, - sd_netlink_message_handler_t callback, - void *userdata, - uint64_t usec, - uint32_t *serial) { - struct reply_callback *c; +int sd_netlink_call_async( + sd_netlink *nl, + sd_netlink_message *m, + sd_netlink_message_handler_t callback, + sd_netlink_destroy_t destroy_callback, + void *userdata, + uint64_t usec, + uint32_t *serial) { + _cleanup_free_ struct reply_callback *c = NULL; uint32_t s; int r, k; @@ -519,33 +533,31 @@ int sd_netlink_call_async(sd_netlink *nl, return r; } - c = new0(struct reply_callback, 1); + c = new(struct reply_callback, 1); if (!c) return -ENOMEM; - c->callback = callback; - c->userdata = userdata; - c->timeout = calc_elapse(usec); + *c = (struct reply_callback) { + .callback = callback, + .userdata = userdata, + .timeout = calc_elapse(usec), + .destroy_callback = destroy_callback, + }; k = sd_netlink_send(nl, m, &s); - if (k < 0) { - free(c); + if (k < 0) return k; - } c->serial = s; r = hashmap_put(nl->reply_callbacks, &c->serial, c); - if (r < 0) { - free(c); + if (r < 0) return r; - } if (c->timeout != 0) { r = prioq_put(nl->reply_callbacks_prioq, c, &c->prioq_idx); if (r < 0) { - c->timeout = 0; - sd_netlink_call_async_cancel(nl, c->serial); + (void) hashmap_remove(nl->reply_callbacks, &c->serial); return r; } } @@ -553,6 +565,8 @@ int sd_netlink_call_async(sd_netlink *nl, if (serial) *serial = s; + TAKE_PTR(c); + return k; } @@ -571,6 +585,9 @@ int sd_netlink_call_async_cancel(sd_netlink *nl, uint32_t serial) { if (c->timeout != 0) prioq_remove(nl->reply_callbacks_prioq, c, &c->prioq_idx); + if (c->destroy_callback) + c->destroy_callback(c->userdata); + free(c); return 1; } diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 03773fb936..b0686873c1 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -199,7 +199,7 @@ static void test_event_loop(int ifindex) { assert_se(sd_netlink_open(&rtnl) >= 0); assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); - assert_se(sd_netlink_call_async(rtnl, m, link_handler, ifname, 0, NULL) >= 0); + assert_se(sd_netlink_call_async(rtnl, m, link_handler, NULL, ifname, 0, NULL) >= 0); assert_se(sd_event_default(&event) >= 0); @@ -240,7 +240,7 @@ static void test_async(int ifindex) { assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); - assert_se(sd_netlink_call_async(rtnl, m, link_handler, ifname, 0, &serial) >= 0); + assert_se(sd_netlink_call_async(rtnl, m, link_handler, NULL, ifname, 0, &serial) >= 0); assert_se(sd_netlink_wait(rtnl, 0) >= 0); assert_se(sd_netlink_process(rtnl, &r) >= 0); @@ -259,10 +259,10 @@ static void test_pipe(int ifindex) { assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0); counter++; - assert_se(sd_netlink_call_async(rtnl, m1, pipe_handler, &counter, 0, NULL) >= 0); + assert_se(sd_netlink_call_async(rtnl, m1, pipe_handler, NULL, &counter, 0, NULL) >= 0); counter++; - assert_se(sd_netlink_call_async(rtnl, m2, pipe_handler, &counter, 0, NULL) >= 0); + assert_se(sd_netlink_call_async(rtnl, m2, pipe_handler, NULL, &counter, 0, NULL) >= 0); while (counter > 0) { assert_se(sd_netlink_wait(rtnl, 0) >= 0); diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c index be5914a2fa..3ff7189ca7 100644 --- a/src/network/netdev/bridge.c +++ b/src/network/netdev/bridge.c @@ -129,7 +129,7 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); - r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, netdev, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, NULL, netdev, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); diff --git a/src/network/netdev/geneve.c b/src/network/netdev/geneve.c index 18b6b359f3..ff43f94bd2 100644 --- a/src/network/netdev/geneve.c +++ b/src/network/netdev/geneve.c @@ -135,7 +135,7 @@ static int netdev_geneve_create(NetDev *netdev) { if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); - r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler, netdev, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler, NULL, netdev, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 72c9db7d07..77cbdd0e86 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -229,7 +229,7 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_h if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m"); - r = sd_netlink_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, req, callback, NULL, link, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); @@ -537,13 +537,13 @@ static int netdev_create(NetDev *netdev, Link *link, return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); if (link) { - r = sd_netlink_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, m, callback, NULL, link, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); link_ref(link); } else { - r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler, netdev, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler, NULL, netdev, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c index 4c55442739..92b2c58f6b 100644 --- a/src/network/networkd-address-label.c +++ b/src/network/networkd-address-label.c @@ -112,7 +112,7 @@ int address_label_configure( if (r < 0) return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index b07196b6b9..45e02c76da 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -453,7 +453,7 @@ int address_remove( if (r < 0) return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); @@ -631,7 +631,7 @@ int address_configure( if (r < 0) return r; - r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); if (r < 0) { address_release(address); return log_error_errno(r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-brvlan.c b/src/network/networkd-brvlan.c index 8e8a618e21..fe418b4768 100644 --- a/src/network/networkd-brvlan.c +++ b/src/network/networkd-brvlan.c @@ -195,7 +195,7 @@ int br_vlan_configure(Link *link, uint16_t pvid, uint32_t *br_vid_bitmap, uint32 return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m"); /* send message to the kernel */ - r = sd_netlink_call_async(rtnl, req, set_brvlan_handler, link, 0, NULL); + r = sd_netlink_call_async(rtnl, req, set_brvlan_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c index 11f70723a9..32fcf82bbd 100644 --- a/src/network/networkd-fdb.c +++ b/src/network/networkd-fdb.c @@ -134,7 +134,7 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) { } /* send message to the kernel to update its internal static MAC table. */ - r = sd_netlink_call_async(rtnl, req, set_fdb_handler, link, 0, NULL); + r = sd_netlink_call_async(rtnl, req, set_fdb_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-ipv6-proxy-ndp.c b/src/network/networkd-ipv6-proxy-ndp.c index d5d8b62f5a..7e1c7d6d2e 100644 --- a/src/network/networkd-ipv6-proxy-ndp.c +++ b/src/network/networkd-ipv6-proxy-ndp.c @@ -173,7 +173,7 @@ int ipv6_proxy_ndp_address_configure(Link *link, IPv6ProxyNDPAddress *ipv6_proxy if (r < 0) return rtnl_log_create_error(r); - r = sd_netlink_call_async(rtnl, req, set_ipv6_proxy_ndp_address_handler, link, 0, NULL); + r = sd_netlink_call_async(rtnl, req, set_ipv6_proxy_ndp_address_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index d7f8ad3040..f74308b5ec 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1327,7 +1327,7 @@ int link_set_mtu(Link *link, uint32_t mtu) { if (r < 0) return log_link_error_errno(link, r, "Could not append MTU: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1398,7 +1398,7 @@ static int link_set_flags(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not set link flags: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1473,7 +1473,7 @@ static int link_set_bridge(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, link_set_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1525,7 +1525,7 @@ static int link_bond_set(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1818,7 +1818,7 @@ int link_up(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1843,7 +1843,7 @@ static int link_up_can(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not set link flags: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1932,7 +1932,7 @@ static int link_set_can(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Failed to close netlink container: %m"); - r = sd_netlink_call_async(link->manager->rtnl, m, link_set_handler, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, m, link_set_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1991,7 +1991,7 @@ int link_down(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not set link flags: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, NULL, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -3103,7 +3103,8 @@ int link_initialized(Link *link, sd_device *device) { return r; r = sd_netlink_call_async(link->manager->rtnl, req, - link_initialized_and_synced, link, 0, NULL); + link_initialized_and_synced, + NULL, link, 0, NULL); if (r < 0) return r; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index aa86ce792d..9ebbc4355e 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -439,7 +439,7 @@ int route_remove(Route *route, Link *link, return log_error_errno(r, "Could not append RTA_OIF attribute: %m"); } - r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); @@ -638,7 +638,7 @@ int route_configure( if (r < 0) return log_error_errno(r, "Could not append RTA_METRICS attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index bbab393546..cd9e913ebb 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -370,7 +370,7 @@ int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *lin return log_error_errno(r, "Could not set destination prefix length: %m"); } - r = sd_netlink_call_async(link->manager->rtnl, m, callback, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, m, callback, NULL, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); @@ -538,7 +538,7 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, sd_netlin rule->link = link; - r = sd_netlink_call_async(link->manager->rtnl, m, callback, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, m, callback, NULL, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index 604edb9cfb..01b33c8fc0 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -38,6 +38,7 @@ typedef enum {SD_GENL_ID_CTRL, SD_GENL_WIREGUARD, SD_GENL_FOU} sd_genl_family; /* callback */ typedef int (*sd_netlink_message_handler_t)(sd_netlink *nl, sd_netlink_message *m, void *userdata); +typedef void (*sd_netlink_destroy_t)(void *userdata); /* bus */ int sd_netlink_new_from_netlink(sd_netlink **nl, int fd); @@ -50,11 +51,12 @@ sd_netlink *sd_netlink_unref(sd_netlink *nl); int sd_netlink_send(sd_netlink *nl, sd_netlink_message *message, uint32_t *serial); int sd_netlink_call_async(sd_netlink *nl, sd_netlink_message *message, - sd_netlink_message_handler_t callback, - void *userdata, uint64_t usec, uint32_t *serial); + sd_netlink_message_handler_t callback, + sd_netlink_destroy_t destoy_callback, + void *userdata, uint64_t usec, uint32_t *serial); int sd_netlink_call_async_cancel(sd_netlink *nl, uint32_t serial); int sd_netlink_call(sd_netlink *nl, sd_netlink_message *message, uint64_t timeout, - sd_netlink_message **reply); + sd_netlink_message **reply); int sd_netlink_get_events(sd_netlink *nl); int sd_netlink_get_timeout(sd_netlink *nl, uint64_t *timeout); From 0d0f02cd15fcb7fed2d2b1089fe64641f8b71134 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 4 Oct 2018 03:42:29 +0900 Subject: [PATCH 04/15] test: add tests for destroy callback of asynchronous netlink call --- src/libsystemd/sd-netlink/test-netlink.c | 137 +++++++++++++++++++---- 1 file changed, 114 insertions(+), 23 deletions(-) diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index b0686873c1..710ed0d089 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -5,6 +5,7 @@ #include "sd-netlink.h" +#include "alloc-util.h" #include "ether-addr-util.h" #include "macro.h" #include "missing.h" @@ -177,8 +178,9 @@ static int link_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) assert_se(rtnl); assert_se(m); + assert_se(userdata); - log_info("got link info about %s", ifname); + log_info("%s: got link info about %s", __func__, ifname); free(ifname); assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &data) >= 0); @@ -212,21 +214,6 @@ static void test_event_loop(int ifindex) { assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); } -static int pipe_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - int *counter = userdata; - int r; - - (*counter)--; - - r = sd_netlink_message_get_errno(m); - - log_info_errno(r, "%d left in pipe. got reply: %m", *counter); - - assert_se(r >= 0); - - return 1; -} - static void test_async(int ifindex) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL; @@ -248,6 +235,116 @@ static void test_async(int ifindex) { assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); } +struct test_async_object { + unsigned n_ref; + char *ifname; +}; + +static struct test_async_object *test_async_object_free(struct test_async_object *t) { + assert(t); + + free(t->ifname); + return mfree(t); +} + +DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(struct test_async_object, test_async_object, test_async_object_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct test_async_object *, test_async_object_unref); + +static int link_handler2(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { + struct test_async_object *t = userdata; + const char *data; + + assert_se(rtnl); + assert_se(m); + assert_se(userdata); + + log_info("%s: got link info about %s", __func__, t->ifname); + + assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &data) >= 0); + assert_se(streq(data, "lo")); + + return 1; +} + +static void test_async_object_destroy(void *userdata) { + struct test_async_object *t = userdata; + + assert(userdata); + + log_info("%s: n_ref=%u", __func__, t->n_ref); + test_async_object_unref(t); +} + +static void test_async_destroy_callback(int ifindex) { + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL; + _cleanup_(test_async_object_unrefp) struct test_async_object *t = NULL; + uint32_t serial; + char *ifname; + + assert_se(t = new(struct test_async_object, 1)); + assert_se(ifname = strdup("lo")); + *t = (struct test_async_object) { + .n_ref = 1, + .ifname = ifname, + }; + + assert_se(sd_netlink_open(&rtnl) >= 0); + + /* destroy callback is called after processing message */ + assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); + assert_se(sd_netlink_call_async(rtnl, m, link_handler2, test_async_object_destroy, t, 0, &serial) >= 0); + + assert_se(t->n_ref == 1); + assert_se(test_async_object_ref(t)); + assert_se(t->n_ref == 2); + + assert_se(sd_netlink_wait(rtnl, 0) >= 0); + assert_se(sd_netlink_process(rtnl, &r) == 1); + assert_se(t->n_ref == 1); + + assert_se(!sd_netlink_message_unref(m)); + + /* destroy callback is called when asynchronous call is cancelled */ + assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); + assert_se(sd_netlink_call_async(rtnl, m, link_handler2, test_async_object_destroy, t, 0, &serial) >= 0); + + assert_se(t->n_ref == 1); + assert_se(test_async_object_ref(t)); + assert_se(t->n_ref == 2); + + assert_se(sd_netlink_call_async_cancel(rtnl, serial) >= 0); + assert_se(t->n_ref == 1); + + assert_se(!sd_netlink_message_unref(m)); + + /* destroy callback is also called by sd_netlink_unref() */ + assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); + assert_se(sd_netlink_call_async(rtnl, m, link_handler2, test_async_object_destroy, t, 0, &serial) >= 0); + + assert_se(t->n_ref == 1); + assert_se(test_async_object_ref(t)); + assert_se(t->n_ref == 2); + + assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); + assert_se(t->n_ref == 1); +} + +static int pipe_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { + int *counter = userdata; + int r; + + (*counter)--; + + r = sd_netlink_message_get_errno(m); + + log_info_errno(r, "%d left in pipe. got reply: %m", *counter); + + assert_se(r >= 0); + + return 1; +} + static void test_pipe(int ifindex) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m1 = NULL, *m2 = NULL; @@ -366,31 +463,25 @@ int main(void) { uint16_t type; test_match(); - test_multiple(); assert_se(sd_netlink_open(&rtnl) >= 0); assert_se(rtnl); test_route(rtnl); - test_message(rtnl); - test_container(rtnl); if_loopback = (int) if_nametoindex("lo"); assert_se(if_loopback > 0); test_async(if_loopback); - + test_async_destroy_callback(if_loopback); test_pipe(if_loopback); - test_event_loop(if_loopback); - test_link_configure(rtnl, if_loopback); test_get_addresses(rtnl); - test_message_link_bridge(rtnl); assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, if_loopback) >= 0); From 1046bf9b1a484a086f61f646c0cacc84b571b4e1 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 6 Oct 2018 13:55:19 +0900 Subject: [PATCH 05/15] network: add destroy callbacks for asynchronous netlink calls --- src/network/netdev/bridge.c | 5 +- src/network/netdev/geneve.c | 7 +- src/network/netdev/netdev.c | 45 ++++++------- src/network/netdev/netdev.h | 2 +- src/network/networkd-address-label.c | 3 +- src/network/networkd-address.c | 6 +- src/network/networkd-brvlan.c | 5 +- src/network/networkd-dhcp4.c | 4 +- src/network/networkd-dhcp6.c | 20 +++--- src/network/networkd-fdb.c | 5 +- src/network/networkd-ipv4ll.c | 4 +- src/network/networkd-ipv6-proxy-ndp.c | 5 +- src/network/networkd-link.c | 78 +++++++++++++--------- src/network/networkd-link.h | 4 +- src/network/networkd-manager.c | 25 +++---- src/network/networkd-ndisc.c | 2 +- src/network/networkd-route.c | 6 +- src/network/networkd-routing-policy-rule.c | 10 +-- 18 files changed, 131 insertions(+), 105 deletions(-) diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c index 3ff7189ca7..ce9f75e27b 100644 --- a/src/network/netdev/bridge.c +++ b/src/network/netdev/bridge.c @@ -10,7 +10,7 @@ /* callback for brige netdev's parameter set */ static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(netdev_unrefp) NetDev *netdev = userdata; + NetDev *netdev = userdata; int r; assert(netdev); @@ -129,7 +129,8 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); - r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, NULL, netdev, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, + netdev_netlink_destroy_callback, netdev, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); diff --git a/src/network/netdev/geneve.c b/src/network/netdev/geneve.c index ff43f94bd2..9350f0257a 100644 --- a/src/network/netdev/geneve.c +++ b/src/network/netdev/geneve.c @@ -18,9 +18,10 @@ /* callback for geneve netdev's created without a backing Link */ static int geneve_netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(netdev_unrefp) NetDev *netdev = userdata; + NetDev *netdev = userdata; int r; + assert(netdev); assert(netdev->state != _NETDEV_STATE_INVALID); r = sd_netlink_message_get_errno(m); @@ -135,12 +136,12 @@ static int netdev_geneve_create(NetDev *netdev) { if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); - r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler, NULL, netdev, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler, + netdev_netlink_destroy_callback, netdev, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); netdev_ref(netdev); - netdev->state = NETDEV_STATE_CREATING; log_netdev_debug(netdev, "Creating"); diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 77cbdd0e86..55f24d0fbc 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -99,25 +99,13 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind"); -static void netdev_cancel_callbacks(NetDev *netdev) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; +static void netdev_callbacks_clear(NetDev *netdev) { netdev_join_callback *callback; - if (!netdev || !netdev->manager) + if (!netdev) return; - rtnl_message_new_synthetic_error(netdev->manager->rtnl, -ENODEV, 0, &m); - while ((callback = netdev->callbacks)) { - if (m) { - assert(callback->link); - assert(callback->callback); - assert(netdev->manager); - assert(netdev->manager->rtnl); - - callback->callback(netdev->manager->rtnl, m, callback->link); - } - LIST_REMOVE(callbacks, netdev->callbacks, callback); link_unref(callback->link); free(callback); @@ -127,7 +115,7 @@ static void netdev_cancel_callbacks(NetDev *netdev) { static NetDev *netdev_free(NetDev *netdev) { assert(netdev); - netdev_cancel_callbacks(netdev); + netdev_callbacks_clear(netdev); if (netdev->ifname && netdev->manager) hashmap_remove(netdev->manager->netdevs, netdev->ifname); @@ -161,6 +149,14 @@ static NetDev *netdev_free(NetDev *netdev) { DEFINE_TRIVIAL_REF_UNREF_FUNC(NetDev, netdev, netdev_free); +void netdev_netlink_destroy_callback(void *userdata) { + NetDev *netdev = userdata; + + assert(userdata); + + netdev_unref(netdev); +} + void netdev_drop(NetDev *netdev) { if (!netdev || netdev->state == NETDEV_STATE_LINGER) return; @@ -169,7 +165,7 @@ void netdev_drop(NetDev *netdev) { log_netdev_debug(netdev, "netdev removed"); - netdev_cancel_callbacks(netdev); + netdev_callbacks_clear(netdev); netdev_unref(netdev); @@ -197,7 +193,7 @@ int netdev_get(Manager *manager, const char *name, NetDev **ret) { static int netdev_enter_failed(NetDev *netdev) { netdev->state = NETDEV_STATE_FAILED; - netdev_cancel_callbacks(netdev); + netdev_callbacks_clear(netdev); return 0; } @@ -229,7 +225,8 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_h if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m"); - r = sd_netlink_call_async(netdev->manager->rtnl, req, callback, NULL, link, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, req, callback, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); @@ -274,9 +271,10 @@ static int netdev_enter_ready(NetDev *netdev) { /* callback for netdev's created without a backing Link */ static int netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(netdev_unrefp) NetDev *netdev = userdata; + NetDev *netdev = userdata; int r; + assert(netdev); assert(netdev->state != _NETDEV_STATE_INVALID); r = sd_netlink_message_get_errno(m); @@ -321,8 +319,7 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t call return log_oom(); cb->callback = callback; - cb->link = link; - link_ref(link); + cb->link = link_ref(link); LIST_PREPEND(callbacks, netdev->callbacks, cb); @@ -537,13 +534,15 @@ static int netdev_create(NetDev *netdev, Link *link, return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); if (link) { - r = sd_netlink_call_async(netdev->manager->rtnl, m, callback, NULL, link, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, m, callback, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); link_ref(link); } else { - r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler, NULL, netdev, 0, NULL); + r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler, + netdev_netlink_destroy_callback, netdev, 0, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index 2746de01a0..855eadf9d3 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -150,7 +150,7 @@ void netdev_drop(NetDev *netdev); NetDev *netdev_unref(NetDev *netdev); NetDev *netdev_ref(NetDev *netdev); - +void netdev_netlink_destroy_callback(void *userdata); DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref); int netdev_get(Manager *manager, const char *name, NetDev **ret); diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c index 92b2c58f6b..a0c4be3ef0 100644 --- a/src/network/networkd-address-label.c +++ b/src/network/networkd-address-label.c @@ -112,7 +112,8 @@ int address_label_configure( if (r < 0) return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 45e02c76da..3ffd3fe4ab 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -453,7 +453,8 @@ int address_remove( if (r < 0) return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); @@ -631,7 +632,8 @@ int address_configure( if (r < 0) return r; - r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) { address_release(address); return log_error_errno(r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-brvlan.c b/src/network/networkd-brvlan.c index fe418b4768..3707347a68 100644 --- a/src/network/networkd-brvlan.c +++ b/src/network/networkd-brvlan.c @@ -195,10 +195,13 @@ int br_vlan_configure(Link *link, uint16_t pvid, uint32_t *br_vid_bitmap, uint32 return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m"); /* send message to the kernel */ - r = sd_netlink_call_async(rtnl, req, set_brvlan_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(rtnl, req, set_brvlan_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + link_ref(link); + return 0; } diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 18867d9401..45b784d023 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -17,7 +17,7 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(link); @@ -302,7 +302,7 @@ static int dhcp_lease_lost(Link *link) { static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(link); diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 82f49e5ac0..7071adc0bb 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -102,14 +102,14 @@ static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix, static int dhcp6_route_remove_cb(sd_netlink *nl, sd_netlink_message *m, void *userdata) { - Link *l = userdata; + Link *link = userdata; int r; + assert(link); + r = sd_netlink_message_get_errno(m); if (r < 0) - log_link_debug_errno(l, r, "Received error on unreachable route removal for DHCPv6 delegated subnetl: %m"); - - l = link_unref(l); + log_link_debug_errno(link, r, "Received error on unreachable route removal for DHCPv6 delegated subnetl: %m"); return 0; } @@ -163,7 +163,6 @@ int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link) { continue; } - link = link_ref(link); log_link_debug(link, "Removing unreachable route %s/%u", strnull(buf), pd_prefix_len); @@ -251,14 +250,14 @@ static int dhcp6_pd_prefix_distribute(Link *dhcp6_link, Iterator *i, static int dhcp6_route_add_cb(sd_netlink *nl, sd_netlink_message *m, void *userdata) { - Link *l = userdata; + Link *link = userdata; int r; + assert(link); + r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) - log_link_debug_errno(l, r, "Received error when adding unreachable route for DHCPv6 delegated subnet: %m"); - - l = link_unref(l); + log_link_debug_errno(link, r, "Received error when adding unreachable route for DHCPv6 delegated subnet: %m"); return 0; } @@ -322,7 +321,6 @@ static int dhcp6_lease_pd_prefix_acquired(sd_dhcp6_client *client, Link *link) { route_free(route); continue; } - link = link_ref(link); route_free(route); @@ -412,7 +410,7 @@ int dhcp6_request_prefix_delegation(Link *link) { static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(link); diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c index 32fcf82bbd..5112d91b90 100644 --- a/src/network/networkd-fdb.c +++ b/src/network/networkd-fdb.c @@ -134,10 +134,13 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) { } /* send message to the kernel to update its internal static MAC table. */ - r = sd_netlink_call_async(rtnl, req, set_fdb_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(rtnl, req, set_fdb_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + link_ref(link); + return 0; } diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index ce50a67400..0f333175da 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -52,7 +52,7 @@ static int ipv4ll_address_lost(Link *link) { } static int ipv4ll_route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(link); @@ -73,7 +73,7 @@ static int ipv4ll_route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *u } static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(link); diff --git a/src/network/networkd-ipv6-proxy-ndp.c b/src/network/networkd-ipv6-proxy-ndp.c index 7e1c7d6d2e..1dcdbad0be 100644 --- a/src/network/networkd-ipv6-proxy-ndp.c +++ b/src/network/networkd-ipv6-proxy-ndp.c @@ -173,10 +173,13 @@ int ipv6_proxy_ndp_address_configure(Link *link, IPv6ProxyNDPAddress *ipv6_proxy if (r < 0) return rtnl_log_create_error(r); - r = sd_netlink_call_async(rtnl, req, set_ipv6_proxy_ndp_address_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(rtnl, req, set_ipv6_proxy_ndp_address_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + link_ref(link); + return 0; } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index f74308b5ec..ba15cac468 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -407,6 +407,8 @@ static int link_update_flags(Link *link, sd_netlink_message *m) { return 0; } +DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref); + static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { _cleanup_(link_unrefp) Link *link = NULL; uint16_t type; @@ -549,6 +551,7 @@ static Link *link_free(Link *link) { if (link->manager) { hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)); set_remove(link->manager->links_requesting_uuid, link); + link_clean(link); } free(link->ifname); @@ -573,6 +576,14 @@ static Link *link_free(Link *link) { DEFINE_TRIVIAL_REF_UNREF_FUNC(Link, link, link_free); +void link_netlink_destroy_callback(void *userdata) { + Link *link = userdata; + + assert(userdata); + + link_unref(link); +} + int link_get(Manager *m, int ifindex, Link **ret) { Link *link; @@ -796,9 +807,10 @@ static int link_set_routing_policy_rule(Link *link) { } static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; + assert(link); assert(link->route_messages > 0); assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES, LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED, @@ -855,7 +867,7 @@ static int link_enter_set_routes(Link *link) { } int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(m); @@ -873,7 +885,7 @@ int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *use } static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(rtnl); @@ -904,7 +916,7 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda } static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(rtnl); @@ -1204,7 +1216,7 @@ static int link_enter_set_addresses(Link *link) { } int link_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(m); @@ -1248,9 +1260,11 @@ static int link_set_proxy_arp(Link *link) { } static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; + assert(link); + log_link_debug(link, "Set link"); r = sd_netlink_message_get_errno(m); @@ -1266,7 +1280,7 @@ static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userd static int link_configure_after_setting_mtu(Link *link); static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(m); @@ -1327,19 +1341,19 @@ int link_set_mtu(Link *link, uint32_t mtu) { if (r < 0) return log_link_error_errno(link, r, "Could not append MTU: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); - link->setting_mtu = true; - link_ref(link); + link->setting_mtu = true; return 0; } static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(m); @@ -1398,7 +1412,8 @@ static int link_set_flags(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not set link flags: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1473,7 +1488,8 @@ static int link_set_bridge(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, link_set_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, link_set_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1525,7 +1541,8 @@ static int link_bond_set(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1725,7 +1742,7 @@ bool link_has_carrier(Link *link) { } static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(link); @@ -1818,7 +1835,8 @@ int link_up(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1843,7 +1861,8 @@ static int link_up_can(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not set link flags: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1932,7 +1951,8 @@ static int link_set_can(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Failed to close netlink container: %m"); - r = sd_netlink_call_async(link->manager->rtnl, m, link_set_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, m, link_set_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -1952,7 +1972,7 @@ static int link_set_can(Link *link) { } static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(link); @@ -1964,10 +1984,8 @@ static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *user if (r < 0) log_link_warning_errno(link, r, "Could not bring down interface: %m"); - if (streq_ptr(link->kind, "can")) { - link_ref(link); + if (streq_ptr(link->kind, "can")) link_set_can(link); - } return 1; } @@ -1991,7 +2009,8 @@ int link_down(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not set link flags: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -2296,7 +2315,7 @@ static int link_joined(Link *link) { } static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(link); @@ -3007,7 +3026,7 @@ static int link_configure_duid(Link *link) { static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; Network *network; int r; @@ -3104,7 +3123,7 @@ int link_initialized(Link *link, sd_device *device) { r = sd_netlink_call_async(link->manager->rtnl, req, link_initialized_and_synced, - NULL, link, 0, NULL); + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return r; @@ -3350,9 +3369,6 @@ int link_add(Manager *m, sd_netlink_message *message, Link **ret) { if (r < 0) goto failed; } else { - /* we are calling a callback directly, so must take a ref */ - link_ref(link); - r = link_initialized_and_synced(m->rtnl, NULL, link); if (r < 0) goto failed; @@ -3479,7 +3495,6 @@ int link_update(Link *link, sd_netlink_message *m) { assert(m); if (link->state == LINK_STATE_LINGER) { - link_ref(link); log_link_info(link, "Link readded"); link_set_state(link, LINK_STATE_ENSLAVING); @@ -4004,8 +4019,7 @@ void link_clean(Link *link) { assert(link); assert(link->manager); - set_remove(link->manager->dirty_links, link); - link_unref(link); + link_unref(set_remove(link->manager->dirty_links, link)); } static const char* const link_state_table[_LINK_STATE_MAX] = { diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 033cca1576..bd66793cb6 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -130,6 +130,8 @@ int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_error *re Link *link_unref(Link *link); Link *link_ref(Link *link); +void link_netlink_destroy_callback(void *userdata); + int link_get(Manager *m, int ifindex, Link **ret); int link_add(Manager *manager, sd_netlink_message *message, Link **ret); void link_drop(Link *link); @@ -180,8 +182,6 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); int link_send_changed(Link *link, const char *property, ...) _sentinel_; -DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref); - /* Macros which append INTERFACE= to the message */ #define log_link_full(link, level, error, ...) \ diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 819a18e26c..51c9a5d1db 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1241,14 +1241,14 @@ Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr) { static int dhcp6_route_add_callback(sd_netlink *nl, sd_netlink_message *m, void *userdata) { - Link *l = userdata; + Link *link = userdata; int r; + assert(link); + r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) - log_link_debug_errno(l, r, "Received error adding DHCPv6 Prefix Delegation route: %m"); - - l = link_unref(l); + log_link_debug_errno(link, r, "Received error adding DHCPv6 Prefix Delegation route: %m"); return 0; } @@ -1274,21 +1274,19 @@ int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) { (void) in_addr_to_string(AF_INET6, (union in_addr_union *) addr, &buf); log_link_debug(link, "Adding prefix route %s/64", strnull(buf)); - link = link_ref(link); - return hashmap_put(m->dhcp6_prefixes, addr, link); } static int dhcp6_route_remove_callback(sd_netlink *nl, sd_netlink_message *m, void *userdata) { - Link *l = userdata; + Link *link = userdata; int r; + assert(link); + r = sd_netlink_message_get_errno(m); if (r < 0) - log_link_debug_errno(l, r, "Received error on DHCPv6 Prefix Delegation route removal: %m"); - - l = link_unref(l); + log_link_debug_errno(link, r, "Received error on DHCPv6 Prefix Delegation route removal: %m"); return 0; } @@ -1320,8 +1318,6 @@ int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) { (void) in_addr_to_string(AF_INET6, (union in_addr_union *) addr, &buf); log_link_debug(l, "Removing prefix route %s/64", strnull(buf)); - l = link_ref(l); - return 0; } @@ -1440,6 +1436,9 @@ void manager_free(Manager *m) { free(m->state_file); + sd_netlink_unref(m->rtnl); + sd_netlink_unref(m->genl); + while ((network = m->networks)) network_free(network); @@ -1474,8 +1473,6 @@ void manager_free(Manager *m) { set_free_with_destructor(m->rules_foreign, routing_policy_rule_free); set_free_with_destructor(m->rules_saved, routing_policy_rule_free); - sd_netlink_unref(m->rtnl); - sd_netlink_unref(m->genl); sd_event_unref(m->event); sd_resolve_unref(m->resolve); diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 4709d9c9c7..1dd949cea2 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -17,7 +17,7 @@ #define NDISC_PREFIX_LFT_MIN 7200U static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(link); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 9ebbc4355e..16a30b5731 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -439,7 +439,8 @@ int route_remove(Route *route, Link *link, return log_error_errno(r, "Could not append RTA_OIF attribute: %m"); } - r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); @@ -638,7 +639,8 @@ int route_configure( if (r < 0) return log_error_errno(r, "Could not append RTA_METRICS attribute: %m"); - r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, req, callback, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index cd9e913ebb..d7c68c680f 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -308,7 +308,7 @@ int routing_policy_rule_add_foreign(Manager *m, } static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(m); @@ -370,7 +370,8 @@ int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *lin return log_error_errno(r, "Could not set destination prefix length: %m"); } - r = sd_netlink_call_async(link->manager->rtnl, m, callback, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, m, callback, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); @@ -419,7 +420,7 @@ static int routing_policy_rule_new_static(Network *network, const char *filename } int link_routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; + Link *link = userdata; int r; assert(rtnl); @@ -538,7 +539,8 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, sd_netlin rule->link = link; - r = sd_netlink_call_async(link->manager->rtnl, m, callback, NULL, link, 0, NULL); + r = sd_netlink_call_async(link->manager->rtnl, m, callback, + link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); From 9bcb210ebcfb192cc8603103cffd3a565bbfa1e1 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 4 Oct 2018 03:59:16 +0900 Subject: [PATCH 06/15] network: add missing set_free() for Manager.dirty_links --- src/network/networkd-manager.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 51c9a5d1db..13f038bf95 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1455,8 +1455,9 @@ void manager_free(Manager *m) { link_unref(link); } - hashmap_free(m->links); + set_free_with_destructor(m->dirty_links, link_unref); + hashmap_free(m->links); set_free(m->links_requesting_uuid); set_free(m->duids_requesting_uuid); From 17e57d3cae0afee927816fa6cfcd41f336eb7f76 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 6 Oct 2018 13:20:07 +0900 Subject: [PATCH 07/15] networkd: drop unused element from AddressLabel struct --- src/network/networkd-address-label.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/networkd-address-label.h b/src/network/networkd-address-label.h index 70b8de7b2a..2e55feabd0 100644 --- a/src/network/networkd-address-label.h +++ b/src/network/networkd-address-label.h @@ -18,7 +18,6 @@ typedef struct NetworkConfigSection NetworkConfigSection; struct AddressLabel { Network *network; - Link *link; NetworkConfigSection *section; unsigned char prefixlen; From 09dd32eea7b1f8769f8bdee53f15f522e0a5bbce Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 10 Oct 2018 14:30:49 +0900 Subject: [PATCH 08/15] network: make netdev_enslave() static --- src/network/netdev/netdev.c | 2 +- src/network/netdev/netdev.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 55f24d0fbc..9b956ff66d 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -292,7 +292,7 @@ static int netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, void * return 1; } -int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t callback) { +static int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t callback) { int r; assert(netdev); diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index 855eadf9d3..2c1a59f2c4 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -155,7 +155,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref); int netdev_get(Manager *manager, const char *name, NetDev **ret); int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink); -int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t callback); int netdev_get_mac(const char *ifname, struct ether_addr **ret); int netdev_join(NetDev *netdev, Link *link, sd_netlink_message_handler_t cb); From fdb20b7c595f098f865cb9db5043d7f8fd7bcbd1 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 10 Oct 2018 14:31:32 +0900 Subject: [PATCH 09/15] network: make manager_dhcp6_prefix_remove() static --- src/network/networkd-manager.c | 2 +- src/network/networkd-manager.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 13f038bf95..8dcf6765c9 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1291,7 +1291,7 @@ static int dhcp6_route_remove_callback(sd_netlink *nl, sd_netlink_message *m, return 0; } -int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) { +static int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) { Link *l; int r; Route *route; diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index fbfcdad304..726a4d2d40 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -94,7 +94,6 @@ int manager_request_product_uuid(Manager *m, Link *link); Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr); int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link); -int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr); int manager_dhcp6_prefix_remove_all(Manager *m, Link *link); DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); From e8d1666687249abc7bb14fea48d99559dd1be651 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 10 Oct 2018 14:32:52 +0900 Subject: [PATCH 10/15] network: drop route_expire_callback() as it is duplicate of link_route_remove_handler() --- src/network/networkd-route.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 16a30b5731..f0b72c78f4 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -449,32 +449,13 @@ int route_remove(Route *route, Link *link, return 0; } -static int route_expire_callback(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - Link *link = userdata; - int r; - - assert(rtnl); - assert(m); - assert(link); - assert(link->ifname); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_netlink_message_get_errno(m); - if (r < 0 && r != -EEXIST) - log_link_warning_errno(link, r, "could not remove route: %m"); - - return 1; -} - int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata) { Route *route = userdata; int r; assert(route); - r = route_remove(route, route->link, route_expire_callback); + r = route_remove(route, route->link, link_route_remove_handler); if (r < 0) log_warning_errno(r, "Could not remove route: %m"); else From e6bf77744af47eee3bbc7a05f8fe1522730b4d62 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 10 Oct 2018 14:34:00 +0900 Subject: [PATCH 11/15] network: make netlink callback not return negative value Fixes #10320. --- src/network/networkd-link.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index ba15cac468..643a5e77c6 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3024,9 +3024,7 @@ static int link_configure_duid(Link *link) { return 0; } -static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m, - void *userdata) { - Link *link = userdata; +static int link_initialized_and_synced(Link *link) { Network *network; int r; @@ -3092,6 +3090,11 @@ static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m, return 1; } +static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { + (void) link_initialized_and_synced(userdata); + return 1; +} + int link_initialized(Link *link, sd_device *device) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; int r; @@ -3121,8 +3124,7 @@ int link_initialized(Link *link, sd_device *device) { if (r < 0) return r; - r = sd_netlink_call_async(link->manager->rtnl, req, - link_initialized_and_synced, + r = sd_netlink_call_async(link->manager->rtnl, req, link_initialized_handler, link_netlink_destroy_callback, link, 0, NULL); if (r < 0) return r; @@ -3369,7 +3371,7 @@ int link_add(Manager *m, sd_netlink_message *message, Link **ret) { if (r < 0) goto failed; } else { - r = link_initialized_and_synced(m->rtnl, NULL, link); + r = link_initialized_and_synced(link); if (r < 0) goto failed; } From 26d6b2147e62b8b6f12e0a765d48cb133e159b6c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 10 Oct 2018 14:36:32 +0900 Subject: [PATCH 12/15] network: drop break line in comment --- src/network/networkd-link.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 643a5e77c6..596f3dee3f 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1752,8 +1752,7 @@ static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda r = sd_netlink_message_get_errno(m); if (r < 0) - /* we warn but don't fail the link, as it may be - brought up later */ + /* we warn but don't fail the link, as it may be brought up later */ log_link_warning_errno(link, r, "Could not bring up interface: %m"); return 1; From c6de4729b1fc2f6dd091859f0f312f86555bd19a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 10 Oct 2018 14:37:20 +0900 Subject: [PATCH 13/15] network: rename ndisc_netlink_handler() to ndisc_route_handler() --- src/network/networkd-ndisc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 1dd949cea2..855eb8c054 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -16,7 +16,7 @@ #define NDISC_RDNSS_MAX 64U #define NDISC_PREFIX_LFT_MIN 7200U -static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { +static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { Link *link = userdata; int r; @@ -126,7 +126,7 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { route->lifetime = time_now + lifetime * USEC_PER_SEC; route->mtu = mtu; - r = route_configure(route, link, ndisc_netlink_handler); + r = route_configure(route, link, ndisc_route_handler); if (r < 0) { log_link_warning_errno(link, r, "Could not set default route: %m"); link_enter_failed(link); @@ -224,7 +224,7 @@ static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router * if (address->cinfo.ifa_valid == 0) return; - r = address_configure(address, link, ndisc_netlink_handler, true); + r = address_configure(address, link, ndisc_route_handler, true); if (r < 0) { log_link_warning_errno(link, r, "Could not set SLAAC address: %m"); link_enter_failed(link); @@ -282,7 +282,7 @@ static void ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) return; } - r = route_configure(route, link, ndisc_netlink_handler); + r = route_configure(route, link, ndisc_route_handler); if (r < 0) { log_link_warning_errno(link, r, "Could not set prefix route: %m"); link_enter_failed(link); @@ -354,7 +354,7 @@ static void ndisc_router_process_route(Link *link, sd_ndisc_router *rt) { return; } - r = route_configure(route, link, ndisc_netlink_handler); + r = route_configure(route, link, ndisc_route_handler); if (r < 0) { log_link_warning_errno(link, r, "Could not set additional route: %m"); link_enter_failed(link); From c8ee637e7fed464f523e14ff28658c0dde2a98ce Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 10 Oct 2018 14:38:57 +0900 Subject: [PATCH 14/15] network: use '_handler' suffix for netlink callbacks --- src/network/networkd-dhcp6.c | 10 ++++------ src/network/networkd-manager.c | 10 ++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 7071adc0bb..8e21b58875 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -100,8 +100,7 @@ static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix, return sd_radv_start(radv); } -static int dhcp6_route_remove_cb(sd_netlink *nl, sd_netlink_message *m, - void *userdata) { +static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, void *userdata) { Link *link = userdata; int r; @@ -152,7 +151,7 @@ int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link) { route_update(route, NULL, 0, NULL, NULL, 0, 0, RTN_UNREACHABLE); - r = route_remove(route, link, dhcp6_route_remove_cb); + r = route_remove(route, link, dhcp6_route_remove_handler); if (r < 0) { (void) in_addr_to_string(AF_INET6, &pd_prefix, &buf); @@ -248,8 +247,7 @@ static int dhcp6_pd_prefix_distribute(Link *dhcp6_link, Iterator *i, return 0; } -static int dhcp6_route_add_cb(sd_netlink *nl, sd_netlink_message *m, - void *userdata) { +static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, void *userdata) { Link *link = userdata; int r; @@ -313,7 +311,7 @@ static int dhcp6_lease_pd_prefix_acquired(sd_dhcp6_client *client, Link *link) { route_update(route, NULL, 0, NULL, NULL, 0, 0, RTN_UNREACHABLE); - r = route_configure(route, link, dhcp6_route_add_cb); + r = route_configure(route, link, dhcp6_route_handler); if (r < 0) { log_link_warning_errno(link, r, "Cannot configure unreachable route for delegated subnet %s/%u: %m", strnull(buf), diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 8dcf6765c9..8d0f4638bc 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1239,8 +1239,7 @@ Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr) { return hashmap_get(m->dhcp6_prefixes, addr); } -static int dhcp6_route_add_callback(sd_netlink *nl, sd_netlink_message *m, - void *userdata) { +static int dhcp6_route_add_handler(sd_netlink *nl, sd_netlink_message *m, void *userdata) { Link *link = userdata; int r; @@ -1267,7 +1266,7 @@ int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) { if (r < 0) return r; - r = route_configure(route, link, dhcp6_route_add_callback); + r = route_configure(route, link, dhcp6_route_add_handler); if (r < 0) return r; @@ -1277,8 +1276,7 @@ int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) { return hashmap_put(m->dhcp6_prefixes, addr, link); } -static int dhcp6_route_remove_callback(sd_netlink *nl, sd_netlink_message *m, - void *userdata) { +static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, void *userdata) { Link *link = userdata; int r; @@ -1311,7 +1309,7 @@ static int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) { if (r < 0) return r; - r = route_remove(route, l, dhcp6_route_remove_callback); + r = route_remove(route, l, dhcp6_route_remove_handler); if (r < 0) return r; From 0ae286e697352a28bf33ce9e06127a35b466291c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 10 Oct 2018 14:39:35 +0900 Subject: [PATCH 15/15] network: make netlink callbacks return 1 This is not necessary. But most of netlink callbacks in networkd return 1. --- src/network/networkd-dhcp6.c | 4 ++-- src/network/networkd-link.c | 3 +-- src/network/networkd-manager.c | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 8e21b58875..40b8780e56 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -110,7 +110,7 @@ static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, voi if (r < 0) log_link_debug_errno(link, r, "Received error on unreachable route removal for DHCPv6 delegated subnetl: %m"); - return 0; + return 1; } int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link) { @@ -257,7 +257,7 @@ static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, void *user if (r < 0 && r != -EEXIST) log_link_debug_errno(link, r, "Received error when adding unreachable route for DHCPv6 delegated subnet: %m"); - return 0; + return 1; } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 596f3dee3f..1f3204b486 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1271,10 +1271,9 @@ static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userd if (r < 0 && r != -EEXIST) { log_link_error_errno(link, r, "Could not join netdev: %m"); link_enter_failed(link); - return 1; } - return 0; + return 1; } static int link_configure_after_setting_mtu(Link *link); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 8d0f4638bc..e5c929f29b 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1286,7 +1286,7 @@ static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, voi if (r < 0) log_link_debug_errno(link, r, "Received error on DHCPv6 Prefix Delegation route removal: %m"); - return 0; + return 1; } static int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) {