From c4e8ceddccfbb14e475e74eb5c57ba32c3c6cf86 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Wed, 10 Dec 2014 16:17:33 +0200 Subject: test-dhcp6-client: Add a simple Information Request test case Start the DHCPv6 test case by sending an Information Request, verifying the reply and continuing at once with the normal address acquisition procedure. Reuse the DHCPv6 Solicit Reply so that the client code is verified to ignore any erroneously added IPv6 address information. --- src/libsystemd-network/sd-dhcp6-client.c | 1 + src/libsystemd-network/test-dhcp6-client.c | 126 ++++++++++++++++++++++++----- 2 files changed, 108 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 940a606d09..017371e837 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -1025,6 +1025,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) assert_return(client->index > 0, -EINVAL); assert_return(client->state != state, -EINVAL); + log_dhcp6_client(client, "client state %d new state %d", client->state, state); client->timeout_resend_expire = sd_event_source_unref(client->timeout_resend_expire); client->timeout_resend = sd_event_source_unref(client->timeout_resend); diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index 26b28a20e8..75908391f0 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -41,7 +41,7 @@ static struct ether_addr mac_addr = { .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'} }; -static bool verbose = false; +static bool verbose = true; static sd_event_source *hangcheck; static int test_dhcp_fd[2]; @@ -335,13 +335,19 @@ int detect_virtualization(const char **id) { return 1; } -int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) { - assert_se(index == test_index); +static void test_client_solicit_cb(sd_dhcp6_client *client, int event, + void *userdata) { + sd_event *e = userdata; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_dhcp_fd) < 0) - return -errno; + assert_se(e); + assert_se(event == DHCP6_EVENT_IP_ACQUIRE); - return test_dhcp_fd[0]; + assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EBUSY); + + if (verbose) + printf(" got DHCPv6 event %d\n", event); + + sd_event_exit(e, 0); } static int test_client_send_reply(DHCP6Message *request) { @@ -513,6 +519,83 @@ static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option, return 0; } +static void test_client_information_cb(sd_dhcp6_client *client, int event, + void *userdata) { + sd_event *e = userdata; + + assert_se(e); + assert_se(event == DHCP6_EVENT_INFORMATION_REQUEST); + + if (verbose) + printf(" got DHCPv6 event %d\n", event); + + assert_se(sd_dhcp6_client_set_information_request(client, false) >= 0); + assert_se(sd_dhcp6_client_set_callback(client, + test_client_solicit_cb, e) >= 0); + + assert_se(sd_dhcp6_client_start(client) >= 0); +} + +static int test_client_verify_information_request(DHCP6Message *information_request, + uint8_t *option, size_t len) { + + _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL; + uint8_t *optval; + uint16_t optcode; + size_t optlen; + bool found_clientid = false, found_elapsed_time = false; + int r; + struct in6_addr addr; + uint32_t lt_pref, lt_valid; + + assert_se(information_request->type == DHCP6_INFORMATION_REQUEST); + + assert_se(dhcp6_lease_new(&lease) >= 0); + + while ((r = dhcp6_option_parse(&option, &len, + &optcode, &optlen, &optval)) >= 0) { + switch(optcode) { + case DHCP6_OPTION_CLIENTID: + assert_se(!found_clientid); + found_clientid = true; + + assert_se(optlen == sizeof(test_duid)); + memcpy(&test_duid, optval, sizeof(test_duid)); + + break; + + case DHCP6_OPTION_IA_NA: + assert_not_reached("IA TA option must not be present"); + + break; + + case DHCP6_OPTION_SERVERID: + assert_not_reached("Server ID option must not be present"); + + break; + + case DHCP6_OPTION_ELAPSED_TIME: + assert_se(!found_elapsed_time); + found_elapsed_time = true; + + assert_se(optlen == 2); + + break; + } + } + + assert_se(r == -ENOMSG); + assert_se(found_clientid && found_elapsed_time); + + assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, <_pref, + <_valid) == -ENOMSG); + + assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, <_pref, + <_valid) == -ENOMSG); + + return 0; +} + int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, const void *packet, size_t len) { struct in6_addr mcast = @@ -534,10 +617,14 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, assert_se(message->transaction_id & 0x00ffffff); if (test_client_message_num == 0) { + test_client_verify_information_request(message, option, len); + test_client_send_reply(message); + test_client_message_num++; + } else if (test_client_message_num == 1) { test_client_verify_solicit(message, option, len); test_client_send_advertise(message); test_client_message_num++; - } else if (test_client_message_num == 1) { + } else if (test_client_message_num == 2) { test_client_verify_request(message, option, len); test_client_send_reply(message); test_client_message_num++; @@ -546,24 +633,19 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, return len; } -static void test_client_solicit_cb(sd_dhcp6_client *client, int event, - void *userdata) { - sd_event *e = userdata; - - assert_se(e); - assert_se(event == DHCP6_EVENT_IP_ACQUIRE); - - assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EBUSY); +int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) { + assert_se(index == test_index); - if (verbose) - printf(" got DHCPv6 event %d\n", event); + if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_dhcp_fd) < 0) + return -errno; - sd_event_exit(e, 0); + return test_dhcp_fd[0]; } static int test_client_solicit(sd_event *e) { sd_dhcp6_client *client; usec_t time_now = now(clock_boottime_or_monotonic()); + bool val = true; if (verbose) printf("* %s\n", __FUNCTION__); @@ -578,8 +660,14 @@ static int test_client_solicit(sd_event *e) { sizeof (mac_addr), ARPHRD_ETHER) >= 0); + assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0); + assert_se(val == false); + assert_se(sd_dhcp6_client_set_information_request(client, true) >= 0); + assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0); + assert_se(val == true); + assert_se(sd_dhcp6_client_set_callback(client, - test_client_solicit_cb, e) >= 0); + test_client_information_cb, e) >= 0); assert_se(sd_event_add_time(e, &hangcheck, clock_boottime_or_monotonic(), time_now + 2 * USEC_PER_SEC, 0, -- cgit v1.2.3-54-g00ecf