[systemd-devel] [PATCH v2] libnetworkd: add link local tests
Tom Gundersen
teg at jklm.no
Sun Apr 27 14:40:50 PDT 2014
Applied. Thanks!
On Sun, Apr 27, 2014 at 9:58 PM, Umut Tezduyar Lindskog
<umut.tezduyar at axis.com> wrote:
> - Also only allow positive ifindex on both dhcp and ipv4ll
> ---
> Makefile.am | 14 +-
> src/libsystemd-network/sd-dhcp-client.c | 2 +-
> src/libsystemd-network/sd-ipv4ll.c | 7 +-
> src/libsystemd-network/test-dhcp-client.c | 4 +-
> src/libsystemd-network/test-ipv4ll.c | 225 +++++++++++++++++++++++++++++
> 5 files changed, 247 insertions(+), 5 deletions(-)
> create mode 100644 src/libsystemd-network/test-ipv4ll.c
>
> diff --git a/Makefile.am b/Makefile.am
> index 7f3924f..5fc14d9 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -2514,9 +2514,21 @@ test_dhcp_client_LDADD = \
> libsystemd-internal.la \
> libsystemd-shared.la
>
> +test_ipv4ll_SOURCES = \
> + src/systemd/sd-ipv4ll.h \
> + src/libsystemd-network/ipv4ll-internal.h \
> + src/libsystemd-network/test-ipv4ll.c
> +
> +test_ipv4ll_LDADD = \
> + libsystemd-network.la \
> + libsystemd-label.la \
> + libsystemd-internal.la \
> + libsystemd-shared.la
> +
> tests += \
> test-dhcp-option \
> - test-dhcp-client
> + test-dhcp-client \
> + test-ipv4ll
>
> # ------------------------------------------------------------------------------
> if ENABLE_GTK_DOC
> diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
> index 854c671..14f2267 100644
> --- a/src/libsystemd-network/sd-dhcp-client.c
> +++ b/src/libsystemd-network/sd-dhcp-client.c
> @@ -143,7 +143,7 @@ int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
> assert_return(client, -EINVAL);
> assert_return (IN_SET(client->state, DHCP_STATE_INIT,
> DHCP_STATE_STOPPED), -EBUSY);
> - assert_return(interface_index >= -1, -EINVAL);
> + assert_return(interface_index > 0, -EINVAL);
>
> client->index = interface_index;
>
> diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
> index 72289b2..fd39c12 100644
> --- a/src/libsystemd-network/sd-ipv4ll.c
> +++ b/src/libsystemd-network/sd-ipv4ll.c
> @@ -382,7 +382,7 @@ static int ipv4ll_receive_message(sd_event_source *s, int fd,
>
> int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index) {
> assert_return(ll, -EINVAL);
> - assert_return(interface_index >= -1, -EINVAL);
> + assert_return(interface_index > 0, -EINVAL);
> assert_return(IN_SET(ll->state, IPV4LL_STATE_INIT,
> IPV4LL_STATE_STOPPED), -EBUSY);
>
> @@ -469,10 +469,13 @@ int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address){
> }
>
> int sd_ipv4ll_set_address_seed (sd_ipv4ll *ll, uint8_t seed[8]) {
> - unsigned int entropy = *seed;
> + unsigned int entropy;
> int r;
>
> assert_return(ll, -EINVAL);
> + assert_return(seed, -EINVAL);
> +
> + entropy = *seed;
>
> free(ll->random_data);
> free(ll->random_data_state);
> diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c
> index e7787fa..83dd619 100644
> --- a/src/libsystemd-network/test-dhcp-client.c
> +++ b/src/libsystemd-network/test-dhcp-client.c
> @@ -79,7 +79,9 @@ static void test_request_basic(sd_event *e)
>
> assert_se(sd_dhcp_client_set_index(client, 15) == 0);
> assert_se(sd_dhcp_client_set_index(client, -42) == -EINVAL);
> - assert_se(sd_dhcp_client_set_index(client, -1) == 0);
> + assert_se(sd_dhcp_client_set_index(client, -1) == -EINVAL);
> + assert_se(sd_dhcp_client_set_index(client, 0) == -EINVAL);
> + assert_se(sd_dhcp_client_set_index(client, 1) == 0);
>
> assert_se(sd_dhcp_client_set_request_option(client,
> DHCP_OPTION_SUBNET_MASK) == -EEXIST);
> diff --git a/src/libsystemd-network/test-ipv4ll.c b/src/libsystemd-network/test-ipv4ll.c
> new file mode 100644
> index 0000000..459d5c3
> --- /dev/null
> +++ b/src/libsystemd-network/test-ipv4ll.c
> @@ -0,0 +1,225 @@
> +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
> +/***
> + This file is part of systemd.
> +
> + Copyright (C) 2014 Axis Communications AB. All rights reserved.
> +
> + systemd is free software; you can redistribute it and/or modify it
> + under the terms of the GNU Lesser General Public License as published by
> + the Free Software Foundation; either version 2.1 of the License, or
> + (at your option) any later version.
> +
> + systemd is distributed in the hope that it will be useful, but
> + WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public License
> + along with systemd; If not, see <http://www.gnu.org/licenses/>.
> +***/
> +
> +#include <stdlib.h>
> +#include <assert.h>
> +#include <errno.h>
> +#include <stdio.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <unistd.h>
> +
> +#include "util.h"
> +#include "socket-util.h"
> +
> +#include "sd-ipv4ll.h"
> +#include "ipv4ll-internal.h"
> +
> +static bool verbose = false;
> +static bool extended = false;
> +static int test_fd[2];
> +
> +static int basic_request_handler_bind = 0;
> +static int basic_request_handler_stop = 0;
> +static void* basic_request_handler_user_data = (void*)0xCABCAB;
> +static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
> + assert_se(userdata == basic_request_handler_user_data);
> +
> + switch(event) {
> + case IPV4LL_EVENT_STOP:
> + basic_request_handler_stop = 1;
> + break;
> + case IPV4LL_EVENT_BIND:
> + basic_request_handler_bind = 1;
> + break;
> + default:
> + assert_se(0);
> + break;
> + }
> +}
> +
> +int arp_network_send_raw_socket(int fd, const union sockaddr_union *link,
> + const struct ether_arp *arp) {
> + assert_se(arp);
> + assert_se(link);
> + assert_se(fd >= 0);
> +
> + if (send(fd, arp, sizeof(struct ether_arp), 0) < 0)
> + return -errno;
> +
> + return 0;
> +}
> +
> +int arp_network_bind_raw_socket(int index, union sockaddr_union *link) {
> + if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, test_fd) < 0)
> + return -errno;
> +
> + return test_fd[0];
> +}
> +
> +static void test_arp_header(struct ether_arp *arp) {
> + assert_se(arp);
> + assert_se(arp->ea_hdr.ar_hrd == htons(ARPHRD_ETHER)); /* HTYPE */
> + assert_se(arp->ea_hdr.ar_pro == htons(ETHERTYPE_IP)); /* PTYPE */
> + assert_se(arp->ea_hdr.ar_hln == ETH_ALEN); /* HLEN */
> + assert_se(arp->ea_hdr.ar_pln == sizeof arp->arp_spa); /* PLEN */
> + assert_se(arp->ea_hdr.ar_op == htons(ARPOP_REQUEST)); /* REQUEST */
> +}
> +
> +static void test_arp_probe(void) {
> + struct ether_arp arp;
> + struct ether_addr mac_addr = {
> + .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
> + be32_t pa = 0x3030;
> +
> + if (verbose)
> + printf("* %s\n", __FUNCTION__);
> +
> + arp_packet_probe(&arp, pa, &mac_addr);
> + test_arp_header(&arp);
> + assert_se(memcmp(arp.arp_sha, &mac_addr, ETH_ALEN) == 0);
> + assert_se(memcmp(arp.arp_tpa, &pa, sizeof(pa)) == 0);
> +}
> +
> +static void test_arp_announce(void) {
> + struct ether_arp arp;
> + struct ether_addr mac_addr = {
> + .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
> + be32_t pa = 0x3131;
> +
> + if (verbose)
> + printf("* %s\n", __FUNCTION__);
> +
> + arp_packet_announcement(&arp, pa, &mac_addr);
> + test_arp_header(&arp);
> + assert_se(memcmp(arp.arp_sha, &mac_addr, ETH_ALEN) == 0);
> + assert_se(memcmp(arp.arp_tpa, &pa, sizeof(pa)) == 0);
> + assert_se(memcmp(arp.arp_spa, &pa, sizeof(pa)) == 0);
> +}
> +
> +static void test_public_api_setters(sd_event *e) {
> + uint8_t seed[8];
> + sd_ipv4ll *ll;
> + struct ether_addr mac_addr = {
> + .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
> +
> + if (verbose)
> + printf("* %s\n", __FUNCTION__);
> +
> + assert_se(sd_ipv4ll_new(&ll) == 0);
> + assert_se(ll);
> +
> + assert_se(sd_ipv4ll_attach_event(NULL, NULL, 0) == -EINVAL);
> + assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
> + assert_se(sd_ipv4ll_attach_event(ll, e, 0) == -EBUSY);
> +
> + assert_se(sd_ipv4ll_set_callback(NULL, NULL, NULL) == -EINVAL);
> + assert_se(sd_ipv4ll_set_callback(ll, NULL, NULL) == 0);
> +
> + assert_se(sd_ipv4ll_set_address_seed(NULL, NULL) == -EINVAL);
> + assert_se(sd_ipv4ll_set_address_seed(ll, NULL) == -EINVAL);
> + assert_se(sd_ipv4ll_set_address_seed(ll, seed) == 0);
> +
> + assert_se(sd_ipv4ll_set_mac(NULL, NULL) == -EINVAL);
> + assert_se(sd_ipv4ll_set_mac(ll, NULL) == -EINVAL);
> + assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
> +
> + assert_se(sd_ipv4ll_set_index(NULL, -1) == -EINVAL);
> + assert_se(sd_ipv4ll_set_index(ll, -1) == -EINVAL);
> + assert_se(sd_ipv4ll_set_index(ll, -99) == -EINVAL);
> + assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
> + assert_se(sd_ipv4ll_set_index(ll, 99) == 0);
> +
> + assert_se(sd_ipv4ll_ref(ll) == ll);
> + assert_se(sd_ipv4ll_unref(ll) == ll);
> +
> + /* Cleanup */
> + assert_se(sd_ipv4ll_unref(ll) == NULL);
> +}
> +
> +static void test_basic_request(sd_event *e) {
> +
> + sd_ipv4ll *ll;
> + struct ether_arp arp;
> + struct ether_addr mac_addr = {
> + .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
> +
> + if (verbose)
> + printf("* %s\n", __FUNCTION__);
> +
> + assert_se(sd_ipv4ll_new(&ll) == 0);
> + assert_se(sd_ipv4ll_start(ll) == -EINVAL);
> +
> + assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
> + assert_se(sd_ipv4ll_start(ll) == -EINVAL);
> +
> + assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
> + assert_se(sd_ipv4ll_start(ll) == -EINVAL);
> +
> + assert_se(sd_ipv4ll_set_callback(ll, basic_request_handler,
> + basic_request_handler_user_data) == 0);
> + assert_se(sd_ipv4ll_start(ll) == -EINVAL);
> +
> + assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
> + assert_se(sd_ipv4ll_start(ll) == 0);
> +
> + sd_event_run(e, (uint64_t) -1);
> + assert_se(sd_ipv4ll_start(ll) == -EBUSY);
> +
> + /* PROBE */
> + sd_event_run(e, (uint64_t) -1);
> + assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
> + test_arp_header(&arp);
> +
> + if (extended) {
> + /* PROBE */
> + sd_event_run(e, (uint64_t) -1);
> + assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
> + test_arp_header(&arp);
> +
> + /* PROBE */
> + sd_event_run(e, (uint64_t) -1);
> + assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
> + test_arp_header(&arp);
> +
> + sd_event_run(e, (uint64_t) -1);
> + assert_se(basic_request_handler_bind == 1);
> + }
> +
> + sd_ipv4ll_stop(ll);
> + assert_se(basic_request_handler_stop == 1);
> +
> + /* Cleanup */
> + assert_se(sd_ipv4ll_unref(ll) == NULL);
> + safe_close(test_fd[1]);
> +}
> +
> +int main(int argc, char *argv[]) {
> + sd_event *e;
> +
> + assert_se(sd_event_new(&e) >= 0);
> +
> + test_public_api_setters(e);
> + test_arp_probe();
> + test_arp_announce();
> + test_basic_request(e);
> +
> + return 0;
> +}
> --
> 1.7.10.4
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
More information about the systemd-devel
mailing list