blob: 038a473b239471ea4dc398803cbebc303dda21ae [file] [log] [blame]
Stephen Warren1a218552016-01-21 16:05:31 -07001# SPDX-License-Identifier: GPL-2.0
Tom Rini10e47792018-05-06 17:58:06 -04002# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
Stephen Warren1a218552016-01-21 16:05:31 -07003
4# Test various network-related functionality, such as the dhcp, ping, and
5# tftpboot commands.
6
7import pytest
8import u_boot_utils
Love Kumar55ef4532023-10-03 18:42:46 +05309import uuid
Love Kumar49f87492023-11-08 12:40:31 +053010import datetime
Love Kumar4578d152024-01-30 13:37:01 +053011import re
Stephen Warren1a218552016-01-21 16:05:31 -070012
Stephen Warren75e731e2016-01-26 13:41:30 -070013"""
Stephen Warren1a218552016-01-21 16:05:31 -070014Note: This test relies on boardenv_* containing configuration values to define
Ehsan Mohandesi3eb50532023-04-21 17:08:22 -070015which network environment is available for testing. Without this, this test
Stephen Warren1a218552016-01-21 16:05:31 -070016will be automatically skipped.
17
18For example:
19
Stephen Warren8d57b922016-01-26 11:10:14 -070020# Boolean indicating whether the Ethernet device is attached to USB, and hence
21# USB enumeration needs to be performed prior to network tests.
22# This variable may be omitted if its value is False.
23env__net_uses_usb = False
24
25# Boolean indicating whether the Ethernet device is attached to PCI, and hence
26# PCI enumeration needs to be performed prior to network tests.
27# This variable may be omitted if its value is False.
28env__net_uses_pci = True
Stephen Warren1a218552016-01-21 16:05:31 -070029
30# True if a DHCP server is attached to the network, and should be tested.
31# If DHCP testing is not possible or desired, this variable may be omitted or
32# set to False.
33env__net_dhcp_server = True
34
Love Kumar4578d152024-01-30 13:37:01 +053035# False or omitted if a DHCP server is attached to the network, and dhcp abort
36# case should be tested.
37# If DHCP abort testing is not possible or desired, set this variable to True.
38# For example: On some setup, dhcp is too fast and this case may not work.
39env__dhcp_abort_test_skip = True
40
Sean Edmondd407acf2023-04-11 10:48:48 -070041# True if a DHCPv6 server is attached to the network, and should be tested.
42# If DHCPv6 testing is not possible or desired, this variable may be omitted or
43# set to False.
44env__net_dhcp6_server = True
45
Stephen Warren1a218552016-01-21 16:05:31 -070046# A list of environment variables that should be set in order to configure a
47# static IP. If solely relying on DHCP, this variable may be omitted or set to
48# an empty list.
49env__net_static_env_vars = [
Simon Glasse9f4d872018-12-27 08:11:13 -070050 ('ipaddr', '10.0.0.100'),
51 ('netmask', '255.255.255.0'),
52 ('serverip', '10.0.0.1'),
Stephen Warren1a218552016-01-21 16:05:31 -070053]
54
55# Details regarding a file that may be read from a TFTP server. This variable
56# may be omitted or set to None if TFTP testing is not possible or desired.
57env__net_tftp_readable_file = {
Simon Glasse9f4d872018-12-27 08:11:13 -070058 'fn': 'ubtest-readable.bin',
59 'addr': 0x10000000,
60 'size': 5058624,
61 'crc32': 'c2244b26',
Love Kumar49f87492023-11-08 12:40:31 +053062 'timeout': 50000,
63 'fnu': 'ubtest-upload.bin',
Stephen Warren1a218552016-01-21 16:05:31 -070064}
Guillaume GARDET1b0102d2016-09-14 10:29:12 +020065
66# Details regarding a file that may be read from a NFS server. This variable
67# may be omitted or set to None if NFS testing is not possible or desired.
68env__net_nfs_readable_file = {
Simon Glasse9f4d872018-12-27 08:11:13 -070069 'fn': 'ubtest-readable.bin',
70 'addr': 0x10000000,
71 'size': 5058624,
72 'crc32': 'c2244b26',
Guillaume GARDET1b0102d2016-09-14 10:29:12 +020073}
Ehsan Mohandesi3eb50532023-04-21 17:08:22 -070074
Love Kumar55ef4532023-10-03 18:42:46 +053075# Details regarding a file that may be read from a TFTP server. This variable
76# may be omitted or set to None if PXE testing is not possible or desired.
77env__net_pxe_readable_file = {
78 'fn': 'default',
79 'addr': 0x2000000,
80 'size': 74,
81 'timeout': 50000,
82 'pattern': 'Linux',
83}
84
Ehsan Mohandesi3eb50532023-04-21 17:08:22 -070085# True if a router advertisement service is connected to the network, and should
86# be tested. If router advertisement testing is not possible or desired, this
87variable may be omitted or set to False.
88env__router_on_net = True
Stephen Warren75e731e2016-01-26 13:41:30 -070089"""
Stephen Warren1a218552016-01-21 16:05:31 -070090
91net_set_up = False
Sean Edmondd407acf2023-04-11 10:48:48 -070092net6_set_up = False
Stephen Warren1a218552016-01-21 16:05:31 -070093
94def test_net_pre_commands(u_boot_console):
Stephen Warren75e731e2016-01-26 13:41:30 -070095 """Execute any commands required to enable network hardware.
Stephen Warren1a218552016-01-21 16:05:31 -070096
97 These commands are provided by the boardenv_* file; see the comment at the
98 beginning of this file.
Stephen Warren75e731e2016-01-26 13:41:30 -070099 """
Stephen Warren1a218552016-01-21 16:05:31 -0700100
Stephen Warren8d57b922016-01-26 11:10:14 -0700101 init_usb = u_boot_console.config.env.get('env__net_uses_usb', False)
102 if init_usb:
103 u_boot_console.run_command('usb start')
Stephen Warren1a218552016-01-21 16:05:31 -0700104
Stephen Warren8d57b922016-01-26 11:10:14 -0700105 init_pci = u_boot_console.config.env.get('env__net_uses_pci', False)
106 if init_pci:
107 u_boot_console.run_command('pci enum')
Stephen Warren1a218552016-01-21 16:05:31 -0700108
Maxim Uvarovb5977fc2023-12-26 21:46:12 +0600109 u_boot_console.run_command('net list')
110
Stephen Warren1a218552016-01-21 16:05:31 -0700111@pytest.mark.buildconfigspec('cmd_dhcp')
112def test_net_dhcp(u_boot_console):
Stephen Warren75e731e2016-01-26 13:41:30 -0700113 """Test the dhcp command.
Stephen Warren1a218552016-01-21 16:05:31 -0700114
115 The boardenv_* file may be used to enable/disable this test; see the
116 comment at the beginning of this file.
Stephen Warren75e731e2016-01-26 13:41:30 -0700117 """
Stephen Warren1a218552016-01-21 16:05:31 -0700118
119 test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False)
120 if not test_dhcp:
121 pytest.skip('No DHCP server available')
122
123 u_boot_console.run_command('setenv autoload no')
124 output = u_boot_console.run_command('dhcp')
125 assert 'DHCP client bound to address ' in output
126
127 global net_set_up
128 net_set_up = True
129
Love Kumar4578d152024-01-30 13:37:01 +0530130@pytest.mark.buildconfigspec('cmd_dhcp')
131@pytest.mark.buildconfigspec('cmd_mii')
132def test_net_dhcp_abort(u_boot_console):
133 """Test the dhcp command by pressing ctrl+c in the middle of dhcp request
134
135 The boardenv_* file may be used to enable/disable this test; see the
136 comment at the beginning of this file.
137 """
138
139 test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False)
140 if not test_dhcp:
141 pytest.skip('No DHCP server available')
142
143 if u_boot_console.config.env.get('env__dhcp_abort_test_skip', True):
144 pytest.skip('DHCP abort test is not enabled!')
145
146 u_boot_console.run_command('setenv autoload no')
147
148 # Phy reset before running dhcp command
149 output = u_boot_console.run_command('mii device')
150 if not re.search(r"Current device: '(.+?)'", output):
151 pytest.skip('PHY device does not exist!')
152 eth_num = re.search(r"Current device: '(.+?)'", output).groups()[0]
153 u_boot_console.run_command(f'mii device {eth_num}')
154 output = u_boot_console.run_command('mii info')
155 eth_addr = hex(int(re.search(r'PHY (.+?):', output).groups()[0], 16))
156 u_boot_console.run_command(f'mii modify {eth_addr} 0 0x8000 0x8000')
157
158 u_boot_console.run_command('dhcp', wait_for_prompt=False)
159 try:
160 u_boot_console.wait_for('Waiting for PHY auto negotiation to complete')
161 except:
162 pytest.skip('Timeout waiting for PHY auto negotiation to complete')
163
164 u_boot_console.wait_for('done')
165
166 try:
167 # Sending Ctrl-C
168 output = u_boot_console.run_command(
169 chr(3), wait_for_echo=False, send_nl=False
170 )
171 assert 'TIMEOUT' not in output
172 assert 'DHCP client bound to address ' not in output
173 assert 'Abort' in output
174 finally:
175 # Provide a time to recover from Abort - if it is not performed
176 # There is message like: ethernet@ff0e0000: No link.
177 u_boot_console.run_command('sleep 1')
178 # Run the dhcp test to setup the network configuration
179 test_net_dhcp(u_boot_console)
180
Sean Edmondd407acf2023-04-11 10:48:48 -0700181@pytest.mark.buildconfigspec('cmd_dhcp6')
182def test_net_dhcp6(u_boot_console):
183 """Test the dhcp6 command.
184
185 The boardenv_* file may be used to enable/disable this test; see the
186 comment at the beginning of this file.
187 """
188
189 test_dhcp6 = u_boot_console.config.env.get('env__net_dhcp6_server', False)
190 if not test_dhcp6:
191 pytest.skip('No DHCP6 server available')
192
193 u_boot_console.run_command('setenv autoload no')
194 output = u_boot_console.run_command('dhcp6')
195 assert 'DHCP6 client bound to ' in output
196
197 global net6_set_up
198 net6_set_up = True
199
Stephen Warren1a218552016-01-21 16:05:31 -0700200@pytest.mark.buildconfigspec('net')
201def test_net_setup_static(u_boot_console):
Stephen Warren75e731e2016-01-26 13:41:30 -0700202 """Set up a static IP configuration.
Stephen Warren1a218552016-01-21 16:05:31 -0700203
204 The configuration is provided by the boardenv_* file; see the comment at
205 the beginning of this file.
Stephen Warren75e731e2016-01-26 13:41:30 -0700206 """
Stephen Warren1a218552016-01-21 16:05:31 -0700207
208 env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None)
209 if not env_vars:
210 pytest.skip('No static network configuration is defined')
211
212 for (var, val) in env_vars:
213 u_boot_console.run_command('setenv %s %s' % (var, val))
214
215 global net_set_up
216 net_set_up = True
217
218@pytest.mark.buildconfigspec('cmd_ping')
219def test_net_ping(u_boot_console):
Stephen Warren75e731e2016-01-26 13:41:30 -0700220 """Test the ping command.
Stephen Warren1a218552016-01-21 16:05:31 -0700221
222 The $serverip (as set up by either test_net_dhcp or test_net_setup_static)
223 is pinged. The test validates that the host is alive, as reported by the
224 ping command's output.
Stephen Warren75e731e2016-01-26 13:41:30 -0700225 """
Stephen Warren1a218552016-01-21 16:05:31 -0700226
227 if not net_set_up:
Stephen Warren3deb8962016-01-26 13:41:31 -0700228 pytest.skip('Network not initialized')
Stephen Warren1a218552016-01-21 16:05:31 -0700229
230 output = u_boot_console.run_command('ping $serverip')
231 assert 'is alive' in output
232
Ehsan Mohandesi3eb50532023-04-21 17:08:22 -0700233@pytest.mark.buildconfigspec('IPV6_ROUTER_DISCOVERY')
234def test_net_network_discovery(u_boot_console):
235 """Test the network discovery feature of IPv6.
236
237 An IPv6 network command (ping6 in this case) is run to make U-Boot send a
238 router solicitation packet, receive a router advertisement message, and
239 parse it.
240 A router advertisement service needs to be running for this test to succeed.
241 U-Boot receives the RA, processes it, and if successful, assigns the gateway
242 IP and prefix length.
243 The configuration is provided by the boardenv_* file; see the comment at
244 the beginning of this file.
245 """
246
247 router_on_net = u_boot_console.config.env.get('env__router_on_net', False)
248 if not router_on_net:
249 pytest.skip('No router on network')
250
251 fake_host_ip = 'fe80::215:5dff:fef6:2ec6'
252 output = u_boot_console.run_command('ping6 ' + fake_host_ip)
253 assert 'ROUTER SOLICITATION 1' in output
254 assert 'Set gatewayip6:' in output
255 assert '0000:0000:0000:0000:0000:0000:0000:0000' not in output
256
Stephen Warren1a218552016-01-21 16:05:31 -0700257@pytest.mark.buildconfigspec('cmd_net')
258def test_net_tftpboot(u_boot_console):
Stephen Warren75e731e2016-01-26 13:41:30 -0700259 """Test the tftpboot command.
Stephen Warren1a218552016-01-21 16:05:31 -0700260
261 A file is downloaded from the TFTP server, its size and optionally its
262 CRC32 are validated.
263
264 The details of the file to download are provided by the boardenv_* file;
265 see the comment at the beginning of this file.
Stephen Warren75e731e2016-01-26 13:41:30 -0700266 """
Stephen Warren1a218552016-01-21 16:05:31 -0700267
268 if not net_set_up:
Stephen Warren3deb8962016-01-26 13:41:31 -0700269 pytest.skip('Network not initialized')
Stephen Warren1a218552016-01-21 16:05:31 -0700270
271 f = u_boot_console.config.env.get('env__net_tftp_readable_file', None)
272 if not f:
273 pytest.skip('No TFTP readable file to read')
274
Michal Simek6596e032016-04-04 20:06:14 +0200275 addr = f.get('addr', None)
Michal Simek6596e032016-04-04 20:06:14 +0200276
Stephen Warren1a218552016-01-21 16:05:31 -0700277 fn = f['fn']
Heinrich Schuchardt23287c82019-01-26 15:25:12 +0100278 if not addr:
279 output = u_boot_console.run_command('tftpboot %s' % (fn))
280 else:
281 output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
Stephen Warren1a218552016-01-21 16:05:31 -0700282 expected_text = 'Bytes transferred = '
283 sz = f.get('size', None)
284 if sz:
285 expected_text += '%d' % sz
286 assert expected_text in output
287
288 expected_crc = f.get('crc32', None)
289 if not expected_crc:
290 return
291
292 if u_boot_console.config.buildconfig.get('config_cmd_crc32', 'n') != 'y':
293 return
294
Heinrich Schuchardt23287c82019-01-26 15:25:12 +0100295 output = u_boot_console.run_command('crc32 $fileaddr $filesize')
Stephen Warren1a218552016-01-21 16:05:31 -0700296 assert expected_crc in output
Guillaume GARDET1b0102d2016-09-14 10:29:12 +0200297
298@pytest.mark.buildconfigspec('cmd_nfs')
299def test_net_nfs(u_boot_console):
300 """Test the nfs command.
301
302 A file is downloaded from the NFS server, its size and optionally its
303 CRC32 are validated.
304
305 The details of the file to download are provided by the boardenv_* file;
306 see the comment at the beginning of this file.
307 """
308
309 if not net_set_up:
310 pytest.skip('Network not initialized')
311
312 f = u_boot_console.config.env.get('env__net_nfs_readable_file', None)
313 if not f:
314 pytest.skip('No NFS readable file to read')
315
316 addr = f.get('addr', None)
317 if not addr:
Quentin Schulzdae1aa82018-07-09 19:16:27 +0200318 addr = u_boot_utils.find_ram_base(u_boot_console)
Guillaume GARDET1b0102d2016-09-14 10:29:12 +0200319
320 fn = f['fn']
321 output = u_boot_console.run_command('nfs %x %s' % (addr, fn))
322 expected_text = 'Bytes transferred = '
323 sz = f.get('size', None)
324 if sz:
325 expected_text += '%d' % sz
326 assert expected_text in output
327
328 expected_crc = f.get('crc32', None)
329 if not expected_crc:
330 return
331
332 if u_boot_console.config.buildconfig.get('config_cmd_crc32', 'n') != 'y':
333 return
334
335 output = u_boot_console.run_command('crc32 %x $filesize' % addr)
336 assert expected_crc in output
Love Kumar55ef4532023-10-03 18:42:46 +0530337
338@pytest.mark.buildconfigspec("cmd_net")
339@pytest.mark.buildconfigspec("cmd_pxe")
340def test_net_pxe_get(u_boot_console):
341 """Test the pxe get command.
342
343 A pxe configuration file is downloaded from the TFTP server and interpreted
344 to boot the images mentioned in pxe configuration file.
345
346 The details of the file to download are provided by the boardenv_* file;
347 see the comment at the beginning of this file.
348 """
349
350 if not net_set_up:
351 pytest.skip("Network not initialized")
352
353 test_net_setup_static(u_boot_console)
354
355 f = u_boot_console.config.env.get("env__net_pxe_readable_file", None)
356 if not f:
357 pytest.skip("No PXE readable file to read")
358
359 addr = f.get("addr", None)
360 timeout = f.get("timeout", u_boot_console.p.timeout)
361
362 pxeuuid = uuid.uuid1()
363 u_boot_console.run_command(f"setenv pxeuuid {pxeuuid}")
364 expected_text_uuid = f"Retrieving file: pxelinux.cfg/{pxeuuid}"
365
366 ethaddr = u_boot_console.run_command("echo $ethaddr")
367 ethaddr = ethaddr.replace(':', '-')
368 expected_text_ethaddr = f"Retrieving file: pxelinux.cfg/01-{ethaddr}"
369
370 ip = u_boot_console.run_command("echo $ipaddr")
371 ip = ip.split('.')
372 ipaddr_file = "".join(['%02x' % int(x) for x in ip]).upper()
373 expected_text_ipaddr = f"Retrieving file: pxelinux.cfg/{ipaddr_file}"
374 expected_text_default = f"Retrieving file: pxelinux.cfg/default"
375
376 with u_boot_console.temporary_timeout(timeout):
377 output = u_boot_console.run_command("pxe get")
378
379 assert "TIMEOUT" not in output
380 assert expected_text_uuid in output
381 assert expected_text_ethaddr in output
382 assert expected_text_ipaddr in output
383
384 i = 1
385 for i in range(0, len(ipaddr_file) - 1):
386 expected_text_ip = f"Retrieving file: pxelinux.cfg/{ipaddr_file[:-i]}"
387 assert expected_text_ip in output
388 i += 1
389
390 assert expected_text_default in output
391 assert "Config file 'default.boot' found" in output
Love Kumar49f87492023-11-08 12:40:31 +0530392
393@pytest.mark.buildconfigspec("cmd_crc32")
394@pytest.mark.buildconfigspec("cmd_net")
395@pytest.mark.buildconfigspec("cmd_tftpput")
396def test_net_tftpput(u_boot_console):
397 """Test the tftpput command.
398
399 A file is downloaded from the TFTP server and then uploaded to the TFTP
400 server, its size and its CRC32 are validated.
401
402 The details of the file to download are provided by the boardenv_* file;
403 see the comment at the beginning of this file.
404 """
405
406 if not net_set_up:
407 pytest.skip("Network not initialized")
408
409 f = u_boot_console.config.env.get("env__net_tftp_readable_file", None)
410 if not f:
411 pytest.skip("No TFTP readable file to read")
412
413 addr = f.get("addr", None)
414 if not addr:
415 addr = u_boot_utils.find_ram_base(u_boot_console)
416
417 sz = f.get("size", None)
418 timeout = f.get("timeout", u_boot_console.p.timeout)
419 fn = f["fn"]
420 fnu = f.get("fnu", "_".join([datetime.datetime.now().strftime("%y%m%d%H%M%S"), fn]))
421 expected_text = "Bytes transferred = "
422 if sz:
423 expected_text += "%d" % sz
424
425 with u_boot_console.temporary_timeout(timeout):
426 output = u_boot_console.run_command("tftpboot %x %s" % (addr, fn))
427
428 assert "TIMEOUT" not in output
429 assert expected_text in output
430
431 expected_tftpb_crc = f.get("crc32", None)
432
433 output = u_boot_console.run_command("crc32 $fileaddr $filesize")
434 assert expected_tftpb_crc in output
435
436 with u_boot_console.temporary_timeout(timeout):
437 output = u_boot_console.run_command(
438 "tftpput $fileaddr $filesize $serverip:%s" % (fnu)
439 )
440
441 expected_text = "Bytes transferred = "
442 if sz:
443 expected_text += "%d" % sz
444 addr = addr + sz
445 assert "TIMEOUT" not in output
446 assert "Access violation" not in output
447 assert expected_text in output
448
449 with u_boot_console.temporary_timeout(timeout):
450 output = u_boot_console.run_command("tftpboot %x %s" % (addr, fnu))
451
452 expected_text = "Bytes transferred = "
453 if sz:
454 expected_text += "%d" % sz
455 assert "TIMEOUT" not in output
456 assert expected_text in output
457
458 output = u_boot_console.run_command("crc32 $fileaddr $filesize")
459 assert expected_tftpb_crc in output