[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