Re: [PATCH v3 15/15] efi_selftest: add test for IPv4 Config2 protocol

Ilias Apalodimas
2024-11-18T12:28:40Z

Overall this looks good. Get rid of the unneeded casts in memcpy for
the next version.

Thanks
/Ilias

On Mon, 11 Nov 2024 at 23:10, Adriano Cordova <adrianox@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@gmail.com>
> ---
>
> (no changes since v2)
>
> lib/efi_selftest/Makefile | 2 +
> lib/efi_selftest/efi_selftest_ipconfig.c | 173 +++++++++++++++++++++++
> 2 files changed, 175 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..e81ab4e334
> --- /dev/null
> +++ b/lib/efi_selftest/efi_selftest_ipconfig.c
> @@ -0,0 +1,173 @@
> +// 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);
> +
> + 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;
> + }
> +
> + /* 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);
> + 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((void *)&manual_address.address, (void *)ip,
> + sizeof(struct efi_ipv4_address));
> + memcpy((void *)&manual_address.subnet_mask, (void *)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((void *)ip, (void *)&manual_address.address,
> + sizeof(struct efi_ipv4_address)) ||
> + memcmp((void *)netmask, (void *)&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.
> + *
> + * Close the timer event created in setup.
> + * Shut down the network adapter.
> + *
> + * 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
>