1*** Settings ***
2Resource                ../lib/utils.robot
3Resource                ../lib/connection_client.robot
4Resource                ../lib/boot_utils.robot
5Library                 ../lib/gen_misc.py
6Library                 ../lib/utils.py
7Library                 ../lib/bmc_network_utils.py
8
9*** Variables ***
10# MAC input from user.
11${MAC_ADDRESS}          ${EMPTY}
12
13
14*** Keywords ***
15
16Check And Reset MAC
17    [Documentation]  Update BMC with user input MAC address.
18    [Arguments]  ${mac_address}=${MAC_ADDRESS}
19
20    # Description of argument(s):
21    # mac_address  The mac address (e.g. 00:01:6c:80:02:28).
22
23    ${active_channel_config}=  Get Active Channel Config
24    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
25
26    Should Not Be Empty  ${mac_address}
27    Open Connection And Log In
28    ${bmc_mac_addr}  ${stderr}  ${rc}=  BMC Execute Command
29    ...  cat /sys/class/net/${ethernet_interface}/address
30    Run Keyword If  '${mac_address.lower()}' != '${bmc_mac_addr.lower()}'
31    ...  Set MAC Address
32
33
34Set MAC Address
35    [Documentation]  Update eth0 with input MAC address.
36    [Arguments]  ${mac_address}=${MAC_ADDRESS}
37
38    # Description of argument(s):
39    # mac_address  The mac address (e.g. 00:01:6c:80:02:28).
40
41    ${active_channel_config}=  Get Active Channel Config
42    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
43
44    Write  fw_setenv ethaddr ${mac_address}
45    OBMC Reboot (off)
46
47    # Take SSH session post BMC reboot.
48    Open Connection And Log In
49    ${bmc_mac_addr}  ${stderr}  ${rc}=  BMC Execute Command
50    ...  cat /sys/class/net/${ethernet_interface}/address
51    Should Be Equal  ${bmc_mac_addr}  ${mac_address}  ignore_case=True
52
53
54Get BMC IP Info
55    [Documentation]  Get system IP address and prefix length.
56
57
58    # Get system IP address and prefix length details using "ip addr"
59    # Sample Output of "ip addr":
60    # 1: eth0: <BROADCAST,MULTIAST> mtu 1500 qdisc mq state UP qlen 1000
61    #     link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
62    #     inet xx.xx.xx.xx/24 brd xx.xx.xx.xx scope global eth0
63
64    ${active_channel_config}=  Get Active Channel Config
65    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
66    ${cmd_output}  ${stderr}  ${rc}=  BMC Execute Command
67    ...  /sbin/ip addr | grep ${ethernet_interface}
68
69    # Get line having IP address details.
70    ${lines}=  Get Lines Containing String  ${cmd_output}  inet
71
72    # List IP address details.
73    @{ip_components}=  Split To Lines  ${lines}
74
75    @{ip_data}=  Create List
76
77    # Get all IP addresses and prefix lengths on system.
78    FOR  ${ip_component}  IN  @{ip_components}
79      @{if_info}=  Split String  ${ip_component}
80      ${ip_n_prefix}=  Get From List  ${if_info}  1
81      Append To List  ${ip_data}  ${ip_n_prefix}
82    END
83
84    [Return]  ${ip_data}
85
86Get BMC Route Info
87    [Documentation]  Get system route info.
88
89
90    # Sample output of "ip route":
91    # default via xx.xx.xx.x dev eth0
92    # xx.xx.xx.0/23 dev eth0  src xx.xx.xx.xx
93    # xx.xx.xx.0/24 dev eth0  src xx.xx.xx.xx
94
95    ${cmd_output}  ${stderr}  ${rc}=  BMC Execute Command
96    ...  /sbin/ip route
97
98    [Return]  ${cmd_output}
99
100# TODO: openbmc/openbmc-test-automation#1331
101Get BMC MAC Address
102    [Documentation]  Get system MAC address.
103
104
105    # Sample output of "ip addr | grep ether":
106    # link/ether xx.xx.xx.xx.xx.xx brd ff:ff:ff:ff:ff:ff
107
108    ${active_channel_config}=  Get Active Channel Config
109    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
110
111    ${cmd_output}  ${stderr}  ${rc}=  BMC Execute Command
112    ...  /sbin/ip addr | grep ${ethernet_interface} -A 1 | grep ether
113
114    # Split the line and return MAC address.
115    # Split list data:
116    # link/ether | xx:xx:xx:xx:xx:xx | brd | ff:ff:ff:ff:ff:ff
117
118    @{words}=  Split String  ${cmd_output}
119
120    [Return]  ${words[1]}
121
122
123Get BMC MAC Address List
124    [Documentation]  Get system MAC address
125
126    # Sample output of "ip addr | grep ether":
127    # link/ether xx.xx.xx.xx.xx.xx brd ff:ff:ff:ff:ff:ff
128
129    ${cmd_output}  ${stderr}  ${rc}=  BMC Execute Command
130    ...  /sbin/ip addr | grep ether
131
132    # Split the line and return MAC address.
133    # Split list data:
134    # link/ether | xx:xx:xx:xx:xx:xx | brd | ff:ff:ff:ff:ff:ff
135    # link/ether | xx:xx:xx:xx:xx:xx | brd | ff:ff:ff:ff:ff:ff
136
137    ${mac_list}=  Create List
138    @{lines}=  Split To Lines  ${cmd_output}
139    FOR  ${line}  IN  @{lines}
140      @{words}=  Split String  ${line}
141      Append To List  ${mac_list}  ${words[1]}
142    END
143
144    [Return]  ${mac_list}
145
146Get BMC Hostname
147    [Documentation]  Get BMC hostname.
148
149    # Sample output of  "hostname":
150    # test_hostname
151
152    ${output}  ${stderr}  ${rc}=  BMC Execute Command  hostname
153
154    [Return]  ${output}
155
156Get FW_Env MAC Address
157    [Documentation]  Get FW_Env MAC address.
158
159    # Sample output of "fw_printenv | grep ethaddr"
160    # ethaddr=xx:xx:xx:xx:xx:xx:xx
161
162    ${cmd_output}  ${stderr}  ${rc}=  BMC Execute Command
163    ...  /sbin/fw_printenv | grep ethaddr
164
165    # Split the line and return MAC address.
166    # Split list data:
167    # ethaddr | xx:xx:xx:xx:xx:xx:xx
168
169    @{words}=  Split String  ${cmd_output}  =
170
171    [Return]  ${words[1]}
172
173
174Get List Of IP Address Via REST
175    [Documentation]  Get list of IP address via REST.
176    [Arguments]  @{ip_uri_list}
177
178    # Description of argument(s):
179    # ip_uri_list  List of IP objects.
180    # Example:
181    #   "data": [
182    #     "/xyz/openbmc_project/network/eth0/ipv4/e9767624",
183    #     "/xyz/openbmc_project/network/eth0/ipv4/31f4ce8b"
184    #   ],
185
186    ${ip_list}=  Create List
187
188    FOR  ${ip_uri}  IN  @{ip_uri_list}
189      ${ip_addr}=  Read Attribute  ${ip_uri}  Address
190      Append To List  ${ip_list}  ${ip_addr}
191    END
192
193    [Return]  @{ip_list}
194
195Delete IP And Object
196    [Documentation]  Delete IP and object.
197    [Arguments]  ${ip_addr}  @{ip_uri_list}
198
199    # Description of argument(s):
200    # ip_addr      IP address to be deleted.
201    # ip_uri_list  List of IP object URIs.
202
203    # Find IP object having this IP address.
204
205     FOR  ${ip_uri}  IN  @{ip_uri_list}
206       ${ip_addr1}=  Read Attribute  ${ip_uri}  Address
207       Run Keyword If  '${ip_addr}' == '${ip_addr1}'  Exit For Loop
208     END
209
210    # If the given IP address is not configured, return.
211    # Otherwise, delete the IP and object.
212
213    Run Keyword And Return If  '${ip_addr}' != '${ip_addr1}'
214    ...  Pass Execution  IP address to be deleted is not configured.
215
216    Run Keyword And Ignore Error  OpenBMC Delete Request  ${ip_uri}
217
218    # After any modification on network interface, BMC restarts network
219    # module, wait until it is reachable. Then wait 15 seconds for new
220    # configuration to be updated on BMC.
221
222    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
223    ...  ${NETWORK_RETRY_TIME}
224    Sleep  15s
225
226    # Verify whether deleted IP address is removed from BMC system.
227
228    ${ip_data}=  Get BMC IP Info
229    Should Not Contain Match  ${ip_data}  ${ip_addr}*
230    ...  msg=IP address not deleted.
231
232Get First Non Pingable IP From Subnet
233    [Documentation]  Find first non-pingable IP from the subnet and return it.
234    [Arguments]  ${host}=${OPENBMC_HOST}
235
236    # Description of argument(s):
237    # host  Any valid host name or IP address
238    #       (e.g. "machine1" or "9.xx.xx.31").
239
240    # Non-pingable IP is unused IP address in the subnet.
241    ${host_name}  ${ip_addr}=  Get Host Name IP
242
243    # Split IP address into network part and host part.
244    # IP address will have 4 octets xx.xx.xx.xx.
245    # Sample output after split:
246    # split_ip  [xx.xx.xx, xx]
247
248    ${split_ip}=  Split String From Right  ${ip_addr}  .  1
249    # First element in list is Network part.
250    ${network_part}=  Get From List  ${split_ip}  0
251
252    FOR  ${octet4}  IN RANGE  1  255
253      ${new_ip}=  Catenate  ${network_part}.${octet4}
254      ${status}=  Run Keyword And Return Status  Ping Host  ${new_ip}
255      # If IP is non-pingable, return it.
256      Return From Keyword If  '${status}' == 'False'  ${new_ip}
257    END
258
259    Fail  msg=No non-pingable IP could be found in subnet ${network_part}.
260
261
262Validate MAC On BMC
263    [Documentation]  Validate MAC on BMC.
264    [Arguments]  ${mac_addr}
265
266    # Description of argument(s):
267    # mac_addr  MAC address of the BMC.
268
269    ${system_mac}=  Get BMC MAC Address
270    ${mac_new_addr}=  Truncate MAC Address  ${system_mac}  ${mac_addr}
271
272    ${status}=  Compare MAC Address  ${system_mac}  ${mac_new_addr}
273    Should Be True  ${status}
274    ...  msg=MAC address ${system_mac} does not match ${mac_new_addr}.
275
276Validate MAC On FW_Env
277    [Documentation]  Validate MAC on FW_Env.
278    [Arguments]  ${mac_addr}
279
280    # Description of argument(s):
281    # mac_addr  MAC address of the BMC.
282
283    ${fw_env_addr}=  Get FW_Env MAC Address
284    ${mac_new_addr}=  Truncate MAC Address  ${fw_env_addr}  ${mac_addr}
285
286    ${status}=  Compare MAC Address  ${fw_env_addr}  ${mac_new_addr}
287    Should Be True  ${status}
288    ...  msg=MAC address ${fw_env_addr} does not match ${mac_new_addr}.
289
290Truncate MAC Address
291    [Documentation]  Truncates and returns user provided MAC address.
292    [Arguments]    ${sys_mac_addr}  ${user_mac_addr}
293
294    # Description of argument(s):
295    # sys_mac_addr  MAC address of the BMC.
296    # user_mac_addr user provided MAC address.
297
298    ${mac_byte}=  Set Variable  ${0}
299    @{user_mac_list}=  Split String  ${user_mac_addr}  :
300    @{sys_mac_list}=  Split String  ${sys_mac_addr}  :
301    ${user_new_mac_list}  Create List
302
303    # Truncate extra bytes and bits from MAC address
304    FOR  ${mac_item}  IN  @{sys_mac_list}
305        ${invalid_mac_byte} =  Get Regexp Matches  ${user_mac_list}[${mac_byte}]  [^A-Za-z0-9]+
306        Return From Keyword If  ${invalid_mac_byte}  ${user_mac_addr}
307        ${mac_int} =    Convert To Integer      ${user_mac_list}[${mac_byte}]   16
308        ${user_mac_len} =  Get Length  ${user_mac_list}
309        ${user_mac_byte}=  Run Keyword IF
310        ...  ${mac_int} >= ${256}  Truncate MAC Bits  ${user_mac_list}[${mac_byte}]
311        ...  ELSE  Set Variable  ${user_mac_list}[${mac_byte}]
312
313        Append To List  ${user_new_mac_list}  ${user_mac_byte}
314        ${mac_byte} =    Set Variable    ${mac_byte + 1}
315        Exit For Loop If  '${mac_byte}' == '${user_mac_len}'
316
317    END
318    ${user_new_mac_string}=   Evaluate  ":".join(${user_new_mac_list})
319    [Return]  ${user_new_mac_string}
320
321Truncate MAC Bits
322    [Documentation]  Truncates user provided MAC address byte to bits.
323    [Arguments]    ${user_mac_addr_byte}
324
325    # Description of argument(s):
326    # user_mac_addr_byte user provided MAC address byte to truncate bits
327
328    ${user_mac_addr_int}=   Convert To List  ${user_mac_addr_byte}
329    ${user_mac_addr_byte}=  Get Slice From List  ${user_mac_addr_int}  0  2
330    ${user_mac_addr_byte_string}=  Evaluate  "".join(${user_mac_addr_byte})
331    [Return]  ${user_mac_addr_byte_string}
332
333
334Run Build Net
335    [Documentation]  Run build_net to preconfigure the ethernet interfaces.
336
337    OS Execute Command  build_net help y y
338    # Run pingum to check if the "build_net" was run correctly done.
339    ${output}  ${stderr}  ${rc}=  OS Execute Command  pingum
340    Should Contain  ${output}  All networks ping Ok
341
342
343Configure Hostname
344    [Documentation]  Configure hostname on BMC via Redfish.
345    [Arguments]  ${hostname}
346
347    # Description of argument(s):
348    # hostname  A hostname value which is to be configured on BMC.
349
350    ${data}=  Create Dictionary  HostName=${hostname}
351    Redfish.patch  ${REDFISH_NW_PROTOCOL_URI}  body=&{data}
352    ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NO_CONTENT}]
353
354
355Verify IP On BMC
356    [Documentation]  Verify IP on BMC.
357    [Arguments]  ${ip}
358
359    # Description of argument(s):
360    # ip  IP address to be verified (e.g. "10.7.7.7").
361
362    # Get IP address details on BMC using IP command.
363    @{ip_data}=  Get BMC IP Info
364    Should Contain Match  ${ip_data}  ${ip}/*
365    ...  msg=IP address does not exist.
366
367
368Verify Gateway On BMC
369    [Documentation]  Verify gateway on BMC.
370    [Arguments]  ${gateway_ip}=0.0.0.0
371
372    # Description of argument(s):
373    # gateway_ip  Gateway IP address.
374
375    ${route_info}=  Get BMC Route Info
376
377    # If gateway IP is empty or 0.0.0.0 it will not have route entry.
378
379    Run Keyword If  '${gateway_ip}' == '0.0.0.0'
380    ...      Pass Execution  Gateway IP is "0.0.0.0".
381    ...  ELSE
382    ...      Should Contain  ${route_info}  ${gateway_ip}
383    ...      msg=Gateway IP address not matching.
384
385
386Get BMC DNS Info
387    [Documentation]  Get system DNS info.
388
389
390    # Sample output of "resolv.conf":
391    # ### Generated manually via dbus settings ###
392    # nameserver 8.8.8.8
393
394    ${cmd_output}  ${stderr}  ${rc}=  BMC Execute Command
395    ...  cat /etc/resolv.conf
396
397    [Return]  ${cmd_output}
398
399
400CLI Get Nameservers
401    [Documentation]  Get the nameserver IPs from /etc/resolv.conf and return as a list.
402
403    # Example of /etc/resolv.conf data:
404    # nameserver x.x.x.x
405    # nameserver y.y.y.y
406
407    ${stdout}  ${stderr}  ${rc}=  BMC Execute Command  egrep nameserver /etc/resolv.conf | cut -f2- -d ' '
408    ${nameservers}=  Split String  ${stdout}
409
410    [Return]  ${nameservers}
411
412
413Get Network Configuration
414    [Documentation]  Get network configuration.
415    # Sample output:
416    #{
417    #  "@odata.context": "/redfish/v1/$metadata#EthernetInterface.EthernetInterface",
418    #  "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces/eth0",
419    #  "@odata.type": "#EthernetInterface.v1_2_0.EthernetInterface",
420    #  "Description": "Management Network Interface",
421    #  "IPv4Addresses": [
422    #    {
423    #      "Address": "169.254.xx.xx",
424    #      "AddressOrigin": "IPv4LinkLocal",
425    #      "Gateway": "0.0.0.0",
426    #      "SubnetMask": "255.255.0.0"
427    #    },
428    #    {
429    #      "Address": "xx.xx.xx.xx",
430    #      "AddressOrigin": "Static",
431    #      "Gateway": "xx.xx.xx.1",
432    #      "SubnetMask": "xx.xx.xx.xx"
433    #    }
434    #  ],
435    #  "Id": "eth0",
436    #  "MACAddress": "xx:xx:xx:xx:xx:xx",
437    #  "Name": "Manager Ethernet Interface",
438    #  "SpeedMbps": 0,
439    #  "VLAN": {
440    #    "VLANEnable": false,
441    #    "VLANId": 0
442    #  }
443
444
445    ${active_channel_config}=  Get Active Channel Config
446    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${active_channel_config['${CHANNEL_NUMBER}']['name']}
447
448    @{network_configurations}=  Get From Dictionary  ${resp.dict}  IPv4StaticAddresses
449    [Return]  @{network_configurations}
450
451
452Add IP Address
453    [Documentation]  Add IP Address To BMC.
454    [Arguments]  ${ip}  ${subnet_mask}  ${gateway}
455    ...  ${valid_status_codes}=${HTTP_OK}
456
457    # Description of argument(s):
458    # ip                  IP address to be added (e.g. "10.7.7.7").
459    # subnet_mask         Subnet mask for the IP to be added
460    #                     (e.g. "255.255.0.0").
461    # gateway             Gateway for the IP to be added (e.g. "10.7.7.1").
462    # valid_status_codes  Expected return code from patch operation
463    #                     (e.g. "200").  See prolog of rest_request
464    #                     method in redfish_plus.py for details.
465
466    ${empty_dict}=  Create Dictionary
467    ${ip_data}=  Create Dictionary  Address=${ip}
468    ...  SubnetMask=${subnet_mask}  Gateway=${gateway}
469
470    ${patch_list}=  Create List
471    ${network_configurations}=  Get Network Configuration
472    ${num_entries}=  Get Length  ${network_configurations}
473
474    FOR  ${INDEX}  IN RANGE  0  ${num_entries}
475      Append To List  ${patch_list}  ${empty_dict}
476    END
477
478    ${valid_status_codes}=  Run Keyword If  '${valid_status_codes}' == '${HTTP_OK}'
479    ...  Set Variable   ${HTTP_OK},${HTTP_NO_CONTENT}
480    ...  ELSE  Set Variable  ${valid_status_codes}
481
482    # We need not check for existence of IP on BMC while adding.
483    Append To List  ${patch_list}  ${ip_data}
484    ${data}=  Create Dictionary  IPv4StaticAddresses=${patch_list}
485
486    ${active_channel_config}=  Get Active Channel Config
487    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
488
489    Redfish.patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}  body=&{data}
490    ...  valid_status_codes=[${valid_status_codes}]
491
492    Return From Keyword If  '${valid_status_codes}' != '${HTTP_OK},${HTTP_NO_CONTENT}'
493
494    # Note: Network restart takes around 15-18s after patch request processing.
495    Sleep  ${NETWORK_TIMEOUT}s
496    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
497
498    Verify IP On BMC  ${ip}
499    Validate Network Config On BMC
500
501
502Delete IP Address
503    [Documentation]  Delete IP Address Of BMC.
504    [Arguments]  ${ip}  ${valid_status_codes}=${HTTP_OK}
505
506    # Description of argument(s):
507    # ip                  IP address to be deleted (e.g. "10.7.7.7").
508    # valid_status_codes  Expected return code from patch operation
509    #                     (e.g. "200").  See prolog of rest_request
510    #                     method in redfish_plus.py for details.
511
512    ${empty_dict}=  Create Dictionary
513    ${patch_list}=  Create List
514
515    @{network_configurations}=  Get Network Configuration
516    FOR  ${network_configuration}  IN  @{network_configurations}
517      Run Keyword If  '${network_configuration['Address']}' == '${ip}'
518      ...  Append To List  ${patch_list}  ${null}
519      ...  ELSE  Append To List  ${patch_list}  ${empty_dict}
520    END
521
522    ${ip_found}=  Run Keyword And Return Status  List Should Contain Value
523    ...  ${patch_list}  ${null}  msg=${ip} does not exist on BMC
524    Pass Execution If  ${ip_found} == ${False}  ${ip} does not exist on BMC
525
526    # Run patch command only if given IP is found on BMC
527    ${data}=  Create Dictionary  IPv4StaticAddresses=${patch_list}
528
529    ${active_channel_config}=  Get Active Channel Config
530    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
531
532    Redfish.patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}  body=&{data}
533    ...  valid_status_codes=[${valid_status_codes}]
534
535    # Note: Network restart takes around 15-18s after patch request processing
536    Sleep  ${NETWORK_TIMEOUT}s
537    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
538
539    ${delete_status}=  Run Keyword And Return Status  Verify IP On BMC  ${ip}
540    Run Keyword If  '${valid_status_codes}' == '${HTTP_OK}'
541    ...  Should Be True  '${delete_status}' == '${False}'
542    ...  ELSE  Should Be True  '${delete_status}' == '${True}'
543
544    Validate Network Config On BMC
545
546
547Validate Network Config On BMC
548    [Documentation]  Check that network info obtained via redfish matches info
549    ...              obtained via CLI.
550
551    @{network_configurations}=  Get Network Configuration
552    ${ip_data}=  Get BMC IP Info
553    FOR  ${network_configuration}  IN  @{network_configurations}
554      Should Contain Match  ${ip_data}  ${network_configuration['Address']}/*
555      ...  msg=IP address does not exist.
556    END
557
558
559Create VLAN
560    [Documentation]  Create a VLAN.
561    [Arguments]  ${id}  ${interface}=eth0  ${expected_result}=valid
562
563    # Description of argument(s):
564    # id  The VLAN ID (e.g. '53').
565    # interface  The physical interface for the VLAN(e.g. 'eth0').
566    # expected_result  Expected status of VLAN configuration.
567
568    @{data_vlan_id}=  Create List  ${interface}  ${id}
569    ${data}=  Create Dictionary   data=@{data_vlan_id}
570    ${resp}=  OpenBMC Post Request  ${vlan_resource}  data=${data}
571    ${resp.status_code}=  Convert To String  ${resp.status_code}
572    ${status}=  Run Keyword And Return Status
573    ...  Valid Value  resp.status_code  ["${HTTP_OK}"]
574
575    Run Keyword If  '${expected_result}' == 'error'
576    ...      Should Be Equal  ${status}  ${False}
577    ...      msg=Configuration of an invalid VLAN ID Failed.
578    ...  ELSE
579    ...      Should Be Equal  ${status}  ${True}
580    ...      msg=Configuration of a valid VLAN ID Failed.
581
582    Sleep  ${NETWORK_TIMEOUT}s
583
584
585Configure Network Settings On VLAN
586    [Documentation]  Configure network settings.
587    [Arguments]  ${id}  ${ip_addr}  ${prefix_len}  ${gateway_ip}=${gateway}
588    ...  ${expected_result}=valid  ${interface}=eth0
589
590    # Description of argument(s):
591    # id               The VLAN ID (e.g. '53').
592    # ip_addr          IP address of VLAN Interface.
593    # prefix_len       Prefix length of VLAN Interface.
594    # gateway_ip       Gateway IP address of VLAN Interface.
595    # expected_result  Expected status of network setting configuration.
596    # interface        Physical Interface on which the VLAN is defined.
597
598    @{ip_parm_list}=  Create List  ${network_resource}
599    ...  ${ip_addr}  ${prefix_len}  ${gateway_ip}
600
601    ${data}=  Create Dictionary  data=@{ip_parm_list}
602
603    Run Keyword And Ignore Error  OpenBMC Post Request
604    ...  ${NETWORK_MANAGER}${interface}_${id}/action/IP  data=${data}
605
606    # After any modification on network interface, BMC restarts network
607    # module, wait until it is reachable. Then wait 15 seconds for new
608    # configuration to be updated on BMC.
609
610    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
611    ...  ${NETWORK_RETRY_TIME}
612    Sleep  ${NETWORK_TIMEOUT}s
613
614    # Verify whether new IP address is populated on BMC system.
615    # It should not allow to configure invalid settings.
616    ${status}=  Run Keyword And Return Status
617    ...  Verify IP On BMC  ${ip_addr}
618
619    Run Keyword If  '${expected_result}' == 'error'
620    ...      Should Be Equal  ${status}  ${False}
621    ...      msg=Configuration of invalid IP Failed.
622    ...  ELSE
623    ...      Should Be Equal  ${status}  ${True}
624    ...      msg=Configuration of valid IP Failed.
625
626
627Get BMC Default Gateway
628    [Documentation]  Get system default gateway.
629
630    ${route_info}=  Get BMC Route Info
631
632    ${lines}=  Get Lines Containing String  ${route_info}  default via
633    @{gateway_list}=  Split To Lines  ${lines}
634
635    # Extract first default gateway and return.
636    @{default_gw}=  Split String  ${gateway_list[0]}
637
638    [Return]  ${default_gw[2]}
639