blob: 8d594f5e193c106d0612773447fe7bcd0934bcf7 [file] [log] [blame]
Adriano Cordova6c998e42024-12-04 00:05:29 -03001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * efi_selftest_ipconfig
4 *
5 * This unit test covers the IPv4 Config2 Protocol.
6 *
7 */
8
9#include <efi_selftest.h>
10#include <charset.h>
11#include <net.h>
12
13static struct efi_boot_services *boottime;
14
15static struct efi_ip4_config2_protocol *ip4_config2;
16static const efi_guid_t efi_ip4_config2_guid = EFI_IP4_CONFIG2_PROTOCOL_GUID;
17
18/*
19 * Setup unit test.
20 *
21 * Open IPv4 Config2 protocol
22 *
23 * @handle: handle of the loaded image
24 * @systable: system table
25 * Return: EFI_ST_SUCCESS for success
26 */
27static int setup(const efi_handle_t handle,
28 const struct efi_system_table *systable)
29{
30 efi_status_t ret;
31 efi_handle_t *net_handle;
32 efi_uintn_t num_handles;
33 efi_handle_t *handles;
34
35 boottime = systable->boottime;
36
37 num_handles = 0;
38 boottime->locate_handle_buffer(BY_PROTOCOL, &efi_ip4_config2_guid,
39 NULL, &num_handles, &handles);
40
41 if (!num_handles) {
42 efi_st_error("Failed to locate ipv4 config2 protocol\n");
43 return EFI_ST_FAILURE;
44 }
45
46 for (net_handle = handles; num_handles--; net_handle++) {
47 ret = boottime->open_protocol(*net_handle, &efi_ip4_config2_guid,
48 (void **)&ip4_config2, 0, 0,
49 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
50 if (ret != EFI_SUCCESS || !ip4_config2)
51 continue;
52 break; // Get first handle that supports ipv4
53 }
54
55 if (!ip4_config2) {
56 efi_st_error("Failed to open ipv4 config2 protocol\n");
57 return EFI_ST_FAILURE;
58 }
59
60 return EFI_ST_SUCCESS;
61}
62
63/*
64 * Execute unit test.
65 *
66 *
67 * Return: EFI_ST_SUCCESS for success
68 */
69static int execute(void)
70{
71 efi_status_t ret;
72 enum efi_ip4_config2_policy policy;
73 efi_uintn_t data_size;
74 struct efi_ip4_config2_manual_address manual_address;
75 struct efi_ip4_config2_manual_address orig_address;
76 u8 netmask[] = {255, 255, 255, 0};
77 u8 ip[] = {10, 0, 0, 1};
78
79 /* Setup may have failed */
80 if (!ip4_config2) {
81 efi_st_error("Setup failure, cannot proceed with test\n");
82 return EFI_ST_FAILURE;
83 }
84
85 /* Set policy to static */
86 policy = EFI_IP4_CONFIG2_POLICY_STATIC;
87 ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_POLICY,
88 sizeof(policy), (void *)&policy);
89 if (ret != EFI_SUCCESS) {
90 efi_st_error("Failed to set policy\n");
91 return EFI_ST_FAILURE;
92 }
93
94 /* Save original ip address and netmask */
95 data_size = sizeof(manual_address);
96 ret = ip4_config2->get_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
97 &data_size, &orig_address);
98 if (ret != EFI_SUCCESS) {
99 efi_st_error("Failed to save original ip address and netmask\n");
100 return EFI_ST_FAILURE;
101 }
102
103 /* Set static ip and netmask */
104 memcpy(&manual_address.address, ip,
105 sizeof(struct efi_ipv4_address));
106 memcpy(&manual_address.subnet_mask, netmask,
107 sizeof(struct efi_ipv4_address));
108 ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
109 sizeof(manual_address), &manual_address);
110 if (ret != EFI_SUCCESS) {
111 efi_st_error("Failed to get ip address and netmask\n");
112 return EFI_ST_FAILURE;
113 }
114
115 /* Try to set interface info, this should fail */
116 ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, 0, NULL);
117 if (ret == EFI_SUCCESS) {
118 efi_st_error("Interface info is read-only\n");
119 return EFI_ST_FAILURE;
120 }
121
122 /* Get ip address and netmask and check that they match with the previously set ones */
123 data_size = sizeof(manual_address);
124 ret = ip4_config2->get_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
125 &data_size, &manual_address);
126 if (ret != EFI_SUCCESS) {
127 efi_st_error("Failed to get ip address and netmask\n");
128 return EFI_ST_FAILURE;
129 }
130 if (memcmp(ip, &manual_address.address,
131 sizeof(struct efi_ipv4_address)) ||
132 memcmp(netmask, &manual_address.subnet_mask,
133 sizeof(struct efi_ipv4_address))) {
134 efi_st_error("Ip address mismatch\n");
135 return EFI_ST_FAILURE;
136 }
137
138 /* Restore original ip address and netmask */
139 ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
140 sizeof(orig_address), &orig_address);
141 if (ret != EFI_SUCCESS) {
142 efi_st_error("Failed to restore original ip address and netmask\n");
143 return EFI_ST_FAILURE;
144 }
145
146 efi_st_printf("Efi ipconfig test execute succeeded\n");
147 return EFI_ST_SUCCESS;
148}
149
150/*
151 * Tear down unit test.
152 *
153 * Return: EFI_ST_SUCCESS for success
154 */
155static int teardown(void)
156{
157 int exit_status = EFI_ST_SUCCESS;
158
159 return exit_status;
160}
161
162EFI_UNIT_TEST(ipconfig) = {
163 .name = "IPv4 config2 protocol",
164 .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
165 .setup = setup,
166 .execute = execute,
167 .teardown = teardown,
168#ifdef CONFIG_SANDBOX
169 /*
170 * Running this test on the sandbox requires setting environment
171 * variable ethact to a network interface connected to a DHCP server and
172 * ethrotate to 'no'.
173 */
174 .on_request = true,
175#endif
176};