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

Adriano Córdova adrianox at gmail.com
Tue Dec 3 20:43:28 CET 2024


El mar, 3 dic 2024 a las 10:03, Ilias Apalodimas (<
ilias.apalodimas at linaro.org>) escribió:

> 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.
>

The (!ip4_config2) { is necessay because the protocol can fail to open too


> > +       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?


I do not know, I took the skeleton from another test where this was present

>


> > +       /* 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