Message ID | 20241111210959.560738-16-adrianox@gmail.com |
---|---|
State | Superseded, archived |
Delegated to: | Heinrich Schuchardt |
Headers | show |
Series | efi_loader: efi http and ipconfig drivers | expand |
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 >
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 +};
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