diff options
-rw-r--r-- | src/libsystemd/sd-dhcp-client.c | 130 | ||||
-rw-r--r-- | src/libsystemd/test-dhcp-client.c | 16 | ||||
-rw-r--r-- | src/network/networkd-link.c | 10 | ||||
-rw-r--r-- | src/systemd/sd-dhcp-client.h | 8 |
4 files changed, 131 insertions, 33 deletions
diff --git a/src/libsystemd/sd-dhcp-client.c b/src/libsystemd/sd-dhcp-client.c index 908f844671..a057852e36 100644 --- a/src/libsystemd/sd-dhcp-client.c +++ b/src/libsystemd/sd-dhcp-client.c @@ -53,6 +53,7 @@ typedef struct DHCPLease DHCPLease; struct sd_dhcp_client { DHCPState state; sd_event *event; + int event_priority; sd_event_source *timeout_resend; int index; int fd; @@ -626,7 +627,11 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, usec_t next_timeout = 0; uint32_t time_left; uint16_t secs; - int err = 0; + int r = 0; + + assert(s); + assert(client); + assert(client->event); switch (client->state) { case DHCP_STATE_RENEWING: @@ -665,19 +670,23 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, next_timeout += (random_u32() & 0x1fffff); - err = sd_event_add_monotonic(client->event, next_timeout, + r = sd_event_add_monotonic(client->event, next_timeout, 10 * USEC_PER_MSEC, client_timeout_resend, client, &client->timeout_resend); - if (err < 0) + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); + if (r < 0) goto error; secs = (usec - client->start_time) / USEC_PER_SEC; switch (client->state) { case DHCP_STATE_INIT: - err = client_send_discover(client, secs); - if (err >= 0) { + r = client_send_discover(client, secs); + if (r >= 0) { client->state = DHCP_STATE_SELECTING; client->attempt = 1; } else { @@ -688,8 +697,8 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, break; case DHCP_STATE_SELECTING: - err = client_send_discover(client, secs); - if (err < 0 && client->attempt >= 64) + r = client_send_discover(client, secs); + if (r < 0 && client->attempt >= 64) goto error; break; @@ -697,8 +706,8 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, case DHCP_STATE_REQUESTING: case DHCP_STATE_RENEWING: case DHCP_STATE_REBINDING: - err = client_send_request(client, secs); - if (err < 0 && client->attempt >= 64) + r = client_send_request(client, secs); + if (r < 0 && client->attempt >= 64) goto error; client->request_sent = usec; @@ -715,7 +724,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, return 0; error: - client_stop(client, err); + client_stop(client, r); /* Errors were dealt with when stopping the client, don't spill errors into the event loop handler */ @@ -725,15 +734,26 @@ error: static int client_initialize_events(sd_dhcp_client *client, usec_t usec) { int r; + assert(client); + assert(client->event); + r = sd_event_add_io(client->event, client->fd, EPOLLIN, client_receive_message, client, &client->receive_message); if (r < 0) goto error; + r = sd_event_source_set_priority(client->receive_message, client->event_priority); + if (r < 0) + goto error; + r = sd_event_add_monotonic(client->event, usec, 0, client_timeout_resend, client, &client->timeout_resend); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); error: if (r < 0) @@ -1030,6 +1050,9 @@ static int client_set_lease_timeouts(sd_dhcp_client *client, uint64_t usec) { uint64_t next_timeout; int r; + assert(client); + assert(client->event); + if (client->lease->lifetime < 10) return -EINVAL; @@ -1052,6 +1075,10 @@ static int client_set_lease_timeouts(sd_dhcp_client *client, uint64_t usec) { if (r < 0) return r; + r = sd_event_source_set_priority(client->timeout_t1, client->event_priority); + if (r < 0) + return r; + if (!client->lease->t2) client->lease->t2 = client->lease->lifetime * 7 / 8; @@ -1073,6 +1100,10 @@ static int client_set_lease_timeouts(sd_dhcp_client *client, uint64_t usec) { if (r < 0) return r; + r = sd_event_source_set_priority(client->timeout_t2, client->event_priority); + if (r < 0) + return r; + next_timeout = client_compute_timeout(client->request_sent, client->lease->lifetime); if (next_timeout < usec) @@ -1085,6 +1116,10 @@ static int client_set_lease_timeouts(sd_dhcp_client *client, uint64_t usec) { if (r < 0) return r; + r = sd_event_source_set_priority(client->timeout_expire, client->event_priority); + if (r < 0) + return r; + return 0; } @@ -1097,6 +1132,10 @@ static int client_receive_message(sd_event_source *s, int fd, DHCPPacket *message; usec_t time_now; + assert(s); + assert(client); + assert(client->event); + len = read(fd, &buf, buflen); if (len < 0) return 0; @@ -1124,6 +1163,10 @@ static int client_receive_message(sd_event_source *s, int fd, &client->timeout_resend); if (r < 0) goto error; + + r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); + if (r < 0) + goto error; } break; @@ -1187,6 +1230,7 @@ int sd_dhcp_client_start(sd_dhcp_client *client) { int r; assert_return(client, -EINVAL); + assert_return(client->event, -EINVAL); assert_return(client->index > 0, -EINVAL); assert_return(client->state == DHCP_STATE_INIT || client->state == DHCP_STATE_INIT_REBOOT, -EBUSY); @@ -1210,28 +1254,63 @@ int sd_dhcp_client_stop(sd_dhcp_client *client) { return client_stop(client, DHCP_EVENT_STOP); } -sd_dhcp_client *sd_dhcp_client_free(sd_dhcp_client *client) { - assert_return(client, NULL); +int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int priority) { + int r; + + assert_return(client, -EINVAL); + assert_return(!client->event, -EBUSY); + + if (event) + client->event = sd_event_ref(event); + else { + r = sd_event_default(&client->event); + if (r < 0) + return 0; + } + + client->event_priority = priority; + + return 0; +} + +int sd_dhcp_client_detach_event(sd_dhcp_client *client) { + assert_return(client, -EINVAL); + + client->event = sd_event_unref(client->event); + + return 0; +} + +sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) { + if (!client) + return NULL; + + return client->event; +} + +void sd_dhcp_client_free(sd_dhcp_client *client) { + if (!client) + return; sd_dhcp_client_stop(client); + sd_dhcp_client_detach_event(client); - sd_event_unref(client->event); free(client->req_opts); free(client); - - return NULL; } -sd_dhcp_client *sd_dhcp_client_new(sd_event *event) { - sd_dhcp_client *client; +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_free); +#define _cleanup_dhcp_client_free_ _cleanup_(sd_dhcp_client_freep) + +int sd_dhcp_client_new(sd_dhcp_client **ret) { + _cleanup_dhcp_client_free_ sd_dhcp_client *client = NULL; - assert_return(event, NULL); + assert_return(ret, -EINVAL); client = new0(sd_dhcp_client, 1); if (!client) - return NULL; + return -ENOMEM; - client->event = sd_event_ref(event); client->state = DHCP_STATE_INIT; client->index = -1; client->fd = -1; @@ -1240,10 +1319,11 @@ sd_dhcp_client *sd_dhcp_client_new(sd_event *event) { client->req_opts_size = ELEMENTSOF(default_req_opts); client->req_opts = memdup(default_req_opts, client->req_opts_size); - if (!client->req_opts) { - free(client); - return NULL; - } + if (!client->req_opts) + return -ENOMEM; + + *ret = client; + client = NULL; - return client; + return 0; } diff --git a/src/libsystemd/test-dhcp-client.c b/src/libsystemd/test-dhcp-client.c index 929b869ec3..56a10b3dfc 100644 --- a/src/libsystemd/test-dhcp-client.c +++ b/src/libsystemd/test-dhcp-client.c @@ -42,12 +42,18 @@ static int test_fd[2]; static void test_request_basic(sd_event *e) { + int r; + sd_dhcp_client *client; - client = sd_dhcp_client_new(e); + r = sd_dhcp_client_new(&client); + assert(r >= 0); assert(client); + r = sd_dhcp_client_attach_event(client, e, 0); + assert(r >= 0); + assert(sd_dhcp_client_set_request_option(NULL, 0) == -EINVAL); assert(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL); assert(sd_dhcp_client_set_index(NULL, 0) == -EINVAL); @@ -199,11 +205,15 @@ int dhcp_network_send_udp_socket(int s, be32_t server_address, static void test_discover_message(sd_event *e) { sd_dhcp_client *client; - int res; + int res, r; - client = sd_dhcp_client_new(e); + r = sd_dhcp_client_new(&client); + assert(r >= 0); assert(client); + r = sd_dhcp_client_attach_event(client, e, 0); + assert(r >= 0); + assert(sd_dhcp_client_set_index(client, 42) >= 0); assert(sd_dhcp_client_set_mac(client, &mac_addr) >= 0); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index f1a2695e83..ce1f956eaf 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -588,9 +588,13 @@ static int link_acquire_conf(Link *link) { assert(link->manager->event); if (!link->dhcp) { - link->dhcp = sd_dhcp_client_new(link->manager->event); - if (!link->dhcp) - return -ENOMEM; + r = sd_dhcp_client_new(&link->dhcp); + if (r < 0) + return r; + + r = sd_dhcp_client_attach_event(link->dhcp, NULL, 0); + if (r < 0) + return r; r = sd_dhcp_client_set_index(link->dhcp, link->ifindex); if (r < 0) diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 937ed86e8d..0f16e99617 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -61,7 +61,11 @@ int sd_dhcp_client_get_hostname(sd_dhcp_client *client, const char **hostname); int sd_dhcp_client_stop(sd_dhcp_client *client); int sd_dhcp_client_start(sd_dhcp_client *client); -sd_dhcp_client *sd_dhcp_client_free(sd_dhcp_client *client); -sd_dhcp_client *sd_dhcp_client_new(sd_event *event); +void sd_dhcp_client_free(sd_dhcp_client *client); +int sd_dhcp_client_new(sd_dhcp_client **ret); + +int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int priority); +int sd_dhcp_client_detach_event(sd_dhcp_client *client); +sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client); #endif |