X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-network%2Fsd-dhcp6-client.c;h=6e006624ca111990017352ebd38f62f058fe7cae;hp=60d502fcbe8225b40b73c1e57e30a292c81b6007;hb=54d61deb7bffec5ca22cf765b13afbb0af547868;hpb=3dc34fcc97b41f8b7b019027225b121dfbb9871d diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 60d502fcb..6e006624c 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -252,6 +252,9 @@ static int client_send_message(sd_dhcp6_client *client) { case DHCP6_STATE_SOLICITATION: message->type = DHCP6_SOLICIT; + r = dhcp6_option_append(&opt, &optlen, + DHCP6_OPTION_RAPID_COMMIT, 0, NULL); + r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na); if (r < 0) return r; @@ -529,6 +532,9 @@ error: } static int client_ensure_iaid(sd_dhcp6_client *client) { + /* name is a pointer to memory in the udev_device struct, so must + have the same scope */ + _cleanup_udev_device_unref_ struct udev_device *device = NULL; const char *name = NULL; uint64_t id; @@ -540,7 +546,6 @@ static int client_ensure_iaid(sd_dhcp6_client *client) { if (detect_container(NULL) <= 0) { /* not in a container, udev will be around */ _cleanup_udev_unref_ struct udev *udev; - _cleanup_udev_device_unref_ struct udev_device *device = NULL; char ifindex_str[2 + DECIMAL_STR_MAX(int)]; udev = udev_new(); @@ -658,6 +663,13 @@ static int client_parse_message(sd_dhcp6_client *client, } break; + + case DHCP6_OPTION_RAPID_COMMIT: + r = dhcp6_lease_set_rapid_commit(lease); + if (r < 0) + return r; + + break; } } @@ -680,9 +692,10 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, { int r; _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL; + bool rapid_commit; if (reply->type != DHCP6_REPLY) - return -EINVAL; + return 0; r = dhcp6_lease_new(&lease); if (r < 0) @@ -692,6 +705,15 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, if (r < 0) return r; + if (client->state == DHCP6_STATE_SOLICITATION) { + r = dhcp6_lease_get_rapid_commit(lease, &rapid_commit); + if (r < 0) + return r; + + if (!rapid_commit) + return 0; + } + dhcp6_lease_clear_timers(&client->lease->ia); client->lease = sd_dhcp6_lease_unref(client->lease); @@ -708,7 +730,7 @@ static int client_receive_advertise(sd_dhcp6_client *client, uint8_t pref_advertise = 0, pref_lease = 0; if (advertise->type != DHCP6_ADVERTISE) - return -EINVAL; + return 0; r = dhcp6_lease_new(&lease); if (r < 0) @@ -793,11 +815,13 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, case DHCP6_STATE_SOLICITATION: r = client_receive_advertise(client, message, len); - if (r == DHCP6_STATE_REQUEST) + if (r == DHCP6_STATE_REQUEST) { client_start(client, r); - break; + break; + } + /* fall through for Soliciation Rapid Commit option check */ case DHCP6_STATE_REQUEST: case DHCP6_STATE_RENEW: case DHCP6_STATE_REBIND: