[PATCH v6 14/14] efi_selftest: add test for IPv4 Config2 protocol

Ilias Apalodimas ilias.apalodimas at linaro.org
Tue Dec 3 14:02:58 CET 2024


Hi Adriano

On Thu, 28 Nov 2024 at 16:44, Adriano Cordova <adrianox at gmail.com> wrote:
>
> Add a test for the EFI_IP4_CONFIG2_PROTOCOL. The test sets the ip
> policy to static, adds an ip address, and then reads the current
> ip address and checks for it to be the same as the one that was set.
>
> Signed-off-by: Adriano Cordova <adrianox at gmail.com>
> ---
> (no changes since v4)
> Changes in v4:
> - Removed unnecessary void* casts
>
> (no changes since v2)
>  lib/efi_selftest/Makefile                |   2 +
>  lib/efi_selftest/efi_selftest_ipconfig.c | 170 +++++++++++++++++++++++
>  2 files changed, 172 insertions(+)
>  create mode 100644 lib/efi_selftest/efi_selftest_ipconfig.c
>
> diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
> index 140c08effc..17fbfad116 100644
> --- a/lib/efi_selftest/Makefile
> +++ b/lib/efi_selftest/Makefile
> @@ -53,6 +53,8 @@ efi_selftest_watchdog.o
>  obj-$(CONFIG_EFI_ECPT) += efi_selftest_ecpt.o
>  obj-$(CONFIG_NETDEVICES) += efi_selftest_snp.o
>  obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_selftest_http.o
> +obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_selftest_ipconfig.o
> +
>  obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_selftest_devicepath.o
>  obj-$(CONFIG_EFI_UNICODE_COLLATION_PROTOCOL2) += \
>  efi_selftest_unicode_collation.o
> diff --git a/lib/efi_selftest/efi_selftest_ipconfig.c b/lib/efi_selftest/efi_selftest_ipconfig.c
> new file mode 100644
> index 0000000000..67a7d4f411
> --- /dev/null
> +++ b/lib/efi_selftest/efi_selftest_ipconfig.c
> @@ -0,0 +1,170 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * efi_selftest_ipconfig
> + *
> + * This unit test covers the IPv4 Config2 Protocol.
> + *
> + */
> +
> +#include <efi_selftest.h>
> +#include <charset.h>
> +#include <net.h>
> +
> +static struct efi_boot_services *boottime;
> +
> +static struct efi_ip4_config2_protocol *ip4_config2;
> +static const efi_guid_t efi_ip4_config2_guid = EFI_IP4_CONFIG2_PROTOCOL_GUID;
> +
> +/*
> + * Setup unit test.
> + *
> + * Open IPv4 Config2 protocol
> + *
> + * @handle:    handle of the loaded image
> + * @systable:  system table
> + * Return:     EFI_ST_SUCCESS for success
> + */
> +static int setup(const efi_handle_t handle,
> +                const struct efi_system_table *systable)
> +{
> +       efi_status_t ret;
> +       efi_handle_t *net_handle;
> +       efi_uintn_t num_handles;
> +       efi_handle_t *handles;
> +
> +       boottime = systable->boottime;
> +
> +       boottime->locate_handle_buffer(BY_PROTOCOL, &efi_ip4_config2_guid,
> +                                      NULL, &num_handles, &handles);
> +

You can avoid looping over a null handle here by checking num_handles
and remove the if (!ip4_config2) { later.

> +       for (net_handle = handles; num_handles--; net_handle++) {
> +               ret = boottime->open_protocol(*net_handle, &efi_ip4_config2_guid,
> +                                             (void **)&ip4_config2, 0, 0,
> +                                             EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +               if (ret != EFI_SUCCESS || !ip4_config2)
> +                       continue;
> +               break; // Get first handle that supports ipv4
> +       }
> +
> +       if (!ip4_config2) {
> +               efi_st_error("Failed to locate ipv4 config2 protocol\n");
> +               return EFI_ST_FAILURE;
> +       }
> +
> +       return EFI_ST_SUCCESS;
> +}
> +
> +/*
> + * Execute unit test.
> + *
> + *
> + * Return:     EFI_ST_SUCCESS for success
> + */
> +static int execute(void)
> +{
> +       efi_status_t ret;
> +       enum efi_ip4_config2_policy policy;
> +       efi_uintn_t data_size;
> +       struct efi_ip4_config2_manual_address manual_address;
> +       struct efi_ip4_config2_manual_address orig_address;
> +       u8 netmask[] = {255, 255, 255, 0};
> +       u8 ip[] = {10, 0, 0, 1};
> +
> +       /* Setup may have failed */
> +       if (!ip4_config2) {
> +               efi_st_error("Setup failure, cannot proceed with test\n");
> +               return EFI_ST_FAILURE;
> +       }
> +

Will this run if setup fails?

> +       /* Set policy to static */
> +       policy = EFI_IP4_CONFIG2_POLICY_STATIC;
> +       ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_POLICY,
> +                             sizeof(enum efi_ip4_config2_policy), (void *)&policy);
> +       if (ret != EFI_SUCCESS) {
> +               efi_st_error("Failed to set policy\n");
> +               return EFI_ST_FAILURE;
> +       }
> +
> +       /* Save original ip address and netmask */
> +       data_size = sizeof(struct efi_ip4_config2_manual_address);

sizeof(manual_address); same for the rest of the code

> +       ret = ip4_config2->get_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
> +                             &data_size, &orig_address);
> +       if (ret != EFI_SUCCESS) {
> +               efi_st_error("Failed to save original ip address and netmask\n");
> +               return EFI_ST_FAILURE;
> +       }
> +
> +       /* Set static ip and netmask */
> +       memcpy(&manual_address.address, ip,
> +              sizeof(struct efi_ipv4_address));
> +       memcpy(&manual_address.subnet_mask, netmask,
> +              sizeof(struct efi_ipv4_address));
> +       ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
> +                             sizeof(struct efi_ip4_config2_manual_address), &manual_address);
> +       if (ret != EFI_SUCCESS) {
> +               efi_st_error("Failed to get ip address and netmask\n");
> +               return EFI_ST_FAILURE;
> +       }
> +
> +       /* Try to set interface info, this should fail */
> +       ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, 0, NULL);
> +       if (ret == EFI_SUCCESS) {
> +               efi_st_error("Interface info is read-only\n");
> +               return EFI_ST_FAILURE;
> +       }
> +
> +       /* Get ip address and netmask and check that they match with the previously set ones */
> +       data_size = sizeof(struct efi_ip4_config2_manual_address);
> +       ret = ip4_config2->get_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
> +                             &data_size, &manual_address);
> +       if (ret != EFI_SUCCESS) {
> +               efi_st_error("Failed to get ip address and netmask\n");
> +               return EFI_ST_FAILURE;
> +       }
> +       if (memcmp(ip, &manual_address.address,
> +                  sizeof(struct efi_ipv4_address)) ||
> +           memcmp(netmask, &manual_address.subnet_mask,
> +                  sizeof(struct efi_ipv4_address))) {
> +               efi_st_error("Ip address mismatch\n");
> +               return EFI_ST_FAILURE;
> +       }
> +
> +       /* Restore original ip address and netmask */
> +       ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
> +                             sizeof(struct efi_ip4_config2_manual_address), &orig_address);
> +       if (ret != EFI_SUCCESS) {
> +               efi_st_error("Failed to restore original ip address and netmask\n");
> +               return EFI_ST_FAILURE;
> +       }
> +
> +       efi_st_printf("Efi ipconfig test execute succeeded\n");
> +       return EFI_ST_SUCCESS;
> +}
> +
> +/*
> + * Tear down unit test.
> + *
> + * Return:     EFI_ST_SUCCESS for success
> + */
> +static int teardown(void)
> +{
> +       int exit_status = EFI_ST_SUCCESS;
> +
> +       return exit_status;
> +}
> +
> +EFI_UNIT_TEST(ipconfig) = {
> +       .name = "IPv4 config2 protocol",
> +       .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
> +       .setup = setup,
> +       .execute = execute,
> +       .teardown = teardown,
> +#ifdef CONFIG_SANDBOX
> +       /*
> +        * Running this test on the sandbox requires setting environment
> +        * variable ethact to a network interface connected to a DHCP server and
> +        * ethrotate to 'no'.
> +        */
> +       .on_request = true,
> +#endif
> +};
> --
> 2.43.0
>

Thanks
/Ilias


More information about the U-Boot mailing list