xref: /openbmc/openbmc-test-automation/redfish/managers/test_bmc_ipv6.robot (revision ed94c69cd347f62cba21b4926b69f4cf42c01a5f)
1*** Settings ***
2Documentation  Network interface IPv6 configuration and verification
3               ...  tests.
4
5Resource       ../../lib/bmc_redfish_resource.robot
6Resource       ../../lib/openbmc_ffdc.robot
7Resource       ../../lib/bmc_ipv6_utils.robot
8Resource       ../../lib/external_intf/vmi_utils.robot
9Library        ../../lib/bmc_network_utils.py
10Library        Collections
11Library        Process
12
13Test Setup      Test Setup Execution
14Test Teardown   Test Teardown Execution
15Suite Setup     Suite Setup Execution
16Suite Teardown  Redfish.Logout
17
18Test Tags     BMC_IPv6
19
20*** Variables ***
21${test_ipv6_addr}            2001:db8:3333:4444:5555:6666:7777:8888
22${test_ipv6_invalid_addr}    2001:db8:3333:4444:5555:6666:7777:JJKK
23${test_ipv6_addr1}           2001:db8:3333:4444:5555:6666:7777:9999
24
25# Valid prefix length is a integer ranges from 1 to 128.
26${test_prefix_length}        64
27${ipv6_gw_addr}              2002:903:15F:32:9:3:32:1
28${prefix_length_def}         None
29${invalid_staticv6_gateway}  9.41.164.1
30${linklocal_addr_format}     fe80::[0-9a-f:]+$
31
32*** Test Cases ***
33
34Get IPv6 Address And Verify
35    [Documentation]  Get IPv6 Address And Verify.
36    [Tags]  Get_IPv6_Address_And_Verify
37
38    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
39      Verify IPv6 On BMC  ${ipv6_network_configuration['Address']}
40    END
41
42
43Get PrefixLength And Verify
44    [Documentation]  Get IPv6 prefix length and verify.
45    [Tags]  Get_PrefixLength_And_Verify
46
47    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
48      Verify IPv6 On BMC  ${ipv6_network_configuration['PrefixLength']}
49    END
50
51
52Get IPv6 Default Gateway And Verify
53    [Documentation]  Get IPv6 default gateway and verify.
54    [Tags]  Get_IPv6_Default_Gateway_And_Verify
55
56    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
57    ${ipv6_gateway}=  Get From Dictionary  ${resp.dict}  IPv6DefaultGateway
58    Verify IPv6 Default Gateway On BMC  ${ipv6_gateway}
59
60
61Verify All Configured IPv6 And PrefixLength On BMC
62    [Documentation]  Verify IPv6 address and its prefix length on BMC.
63    [Tags]  Verify_All_Configured_IPv6_And_PrefixLength_On_BMC
64
65    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
66      Verify IPv6 And PrefixLength  ${ipv6_network_configuration['Address']}
67      ...  ${ipv6_network_configuration['PrefixLength']}
68    END
69
70
71Configure IPv6 Address And Verify
72    [Documentation]  Configure IPv6 address and verify.
73    [Tags]  Configure_IPv6_Address_And_Verify
74    [Teardown]  Run Keywords
75    ...  Delete IPv6 Address  ${test_ipv6_addr}  AND  Test Teardown Execution
76    [Template]  Configure IPv6 Address On BMC
77
78
79    # IPv6 address     Prefix length
80    ${test_ipv6_addr}  ${test_prefix_length}
81
82
83Delete IPv6 Address And Verify
84    [Documentation]  Delete IPv6 address and verify.
85    [Tags]  Delete_IPv6_Address_And_Verify
86
87    Configure IPv6 Address On BMC  ${test_ipv6_addr}  ${test_prefix_length}
88
89    Delete IPv6 Address  ${test_ipv6_addr}
90
91
92Modify IPv6 Address And Verify
93    [Documentation]  Modify IPv6 address and verify.
94    [Tags]  Modify_IPv6_Address_And_Verify
95    [Teardown]  Run Keywords
96    ...  Delete IPv6 Address  ${test_ipv6_addr1}  AND  Test Teardown Execution
97
98    Configure IPv6 Address On BMC  ${test_ipv6_addr}  ${test_prefix_length}
99
100    Modify IPv6 Address  ${test_ipv6_addr}  ${test_ipv6_addr1}  ${test_prefix_length}
101
102
103Verify Persistency Of IPv6 After BMC Reboot
104    [Documentation]  Verify persistency of IPv6 after BMC reboot.
105    [Tags]  Verify_Persistency_Of_IPv6_After_BMC_Reboot
106    [Teardown]  Run Keywords
107    ...  Delete IPv6 Address  ${test_ipv6_addr}  AND  Test Teardown Execution
108
109    Configure IPv6 Address On BMC  ${test_ipv6_addr}  ${test_prefix_length}
110
111    Redfish OBMC Reboot (off)  stack_mode=skip
112
113    # Verifying persistency of IPv6.
114    Verify IPv6 On BMC  ${test_ipv6_addr}
115
116
117Enable SLAAC On BMC And Verify
118    [Documentation]  Enable SLAAC on BMC and verify.
119    [Tags]  Enable_SLAAC_On_BMC_And_Verify
120
121    Set SLAAC Configuration State And Verify  ${True}
122
123
124Enable DHCPv6 Property On BMC And Verify
125    [Documentation]  Enable DHCPv6 property on BMC and verify.
126    [Tags]  Enable_DHCPv6_Property_On_BMC_And_Verify
127
128    Set And Verify DHCPv6 Property  Enabled
129
130
131Disable DHCPv6 Property On BMC And Verify
132    [Documentation]  Disable DHCPv6 property on BMC and verify.
133    [Tags]  Disable_DHCPv6_Property_On_BMC_And_Verify
134
135    Set And Verify DHCPv6 Property  Disabled
136
137
138Verify Persistency Of DHCPv6 On Reboot
139    [Documentation]  Verify persistency of DHCPv6 property on reboot.
140    [Tags]  Verify_Persistency_Of_DHCPv6_On_Reboot
141
142    Set And Verify DHCPv6 Property  Enabled
143    Redfish OBMC Reboot (off)       stack_mode=skip
144    Verify DHCPv6 Property          Enabled
145
146
147Configure Invalid Static IPv6 And Verify
148    [Documentation]  Configure invalid static IPv6 and verify.
149    [Tags]  Configure_Invalid_Static_IPv6_And_Verify
150    [Template]  Configure IPv6 Address On BMC
151
152    #invalid_ipv6         prefix length           valid_status_code
153    ${ipv4_hexword_addr}  ${test_prefix_length}   ${HTTP_BAD_REQUEST}
154
155
156Configure IPv6 Static Default Gateway And Verify
157    [Documentation]  Configure IPv6 static default gateway and verify.
158    [Tags]  Configure_IPv6_Static_Default_Gateway_And_Verify
159    [Template]  Configure IPv6 Static Default Gateway On BMC
160
161    # static_def_gw              prefix length           valid_status_code
162    ${ipv6_gw_addr}              ${prefix_length_def}    ${HTTP_OK}
163    ${invalid_staticv6_gateway}  ${test_prefix_length}   ${HTTP_BAD_REQUEST}
164
165
166Modify Static Default Gateway And Verify
167    [Documentation]  Modify static default gateway and verify.
168    [Tags]  Modify_Static_Default_Gateway_And_Verify
169    [Setup]  Configure IPv6 Static Default Gateway On BMC  ${ipv6_gw_addr}  ${prefix_length_def}
170
171    Modify IPv6 Static Default Gateway On BMC  ${test_ipv6_addr1}  ${prefix_length_def}  ${HTTP_OK}  ${ipv6_gw_addr}
172
173
174Delete IPv6 Static Default Gateway And Verify
175    [Documentation]  Delete IPv6 static default gateway and verify.
176    [Tags]  Delete_IPv6_Static_Default_Gateway_And_Verify
177    [Setup]  Configure IPv6 Static Default Gateway On BMC  ${ipv6_gw_addr}  ${prefix_length_def}
178
179    Delete IPv6 Static Default Gateway  ${ipv6_gw_addr}
180
181
182Verify Coexistence Of Linklocalv6 And Static IPv6 On BMC
183    [Documentation]  Verify linklocalv6 And static IPv6 both exist.
184    [Tags]  Verify_Coexistence_Of_Linklocalv6_And_Static_IPv6_On_BMC
185    [Setup]  Configure IPv6 Address On BMC  ${test_ipv6_addr}  ${test_prefix_length}
186    [Teardown]  Delete IPv6 Address  ${test_ipv6_addr}
187
188    Check Coexistence Of Linklocalv6 And Static IPv6
189
190
191Verify IPv6 Linklocal Address Is In Corrrect Format
192    [Documentation]  Verify linklocal address has network part as fe80 and host part as EUI64.
193    [Tags]  Verify_IPv6_Linklocal_Address_Is_In_Correct_Format
194
195    Check If Linklocal Address Is In Correct Format
196
197
198Verify BMC Gets SLAAC Address On Enabling SLAAC
199    [Documentation]  On enabling SLAAC verify SLAAC address comes up.
200    [Tags]  Verify_BMC_Gets_SLAAC_Address_On_Enabling_SLAAC
201    [Setup]  Set SLAAC Configuration State And Verify  ${False}
202
203    Set SLAAC Configuration State And Verify  ${True}
204    Sleep  ${NETWORK_TIMEOUT}
205    Check BMC Gets SLAAC Address
206
207
208Enable And Verify DHCPv6 Property On Eth1 When DHCPv6 Property Enabled On Eth0
209    [Documentation]  Verify DHCPv6 on eth1 when DHCPv6 property is enabled on eth0.
210    [Tags]  Enable_And_Verify_DHCPv6_Property_On_Eth1_When_DHCPv6_Property_Enabled_On_Eth0
211    [Setup]  Get The Initial DHCPv6 Settings
212    [Teardown]  Run Keywords  Set And Verify DHCPv6 Property  ${dhcpv6_channel_1}  ${1}
213    ...  AND  Set And Verify DHCPv6 Property  ${dhcpv6_channel_2}  ${2}
214
215    Set And Verify DHCPv6 Property  Enabled  ${1}
216    Set And Verify DHCPv6 Property  Enabled  ${2}
217
218
219Enable And Verify SLAAC Property On Eth1 When SLAAC Property Enabled On Eth0
220    [Documentation]  Enable and verify SLAAC property on Eth1 when SLAAC property enabled on Eth0.
221    [Tags]  Enable_And_Verify_SLAAC_Property_On_Eth1_When_SLAAC_Property_Enabled_On_Eth0
222    [Setup]  Get The Initial SLAAC Settings
223    [Teardown]  Run Keywords  Set SLAAC Configuration State And Verify  ${slaac_channel_1}  [${HTTP_OK}]  ${1}
224    ...  AND  Set SLAAC Configuration State And Verify  ${slaac_channel_2}  [${HTTP_OK}]  ${2}
225
226    Set SLAAC Configuration State And Verify   ${True}  [${HTTP_OK}]  ${1}
227    Set SLAAC Configuration State And Verify   ${True}  [${HTTP_OK}]  ${2}
228
229    # Check all the addresses and address origins remain intact.
230    Verify All The Addresses Are Intact
231
232
233Verify Autoconfig Is Present On Ethernet Interface
234    [Documentation]  Verify autoconfig is present on ethernet interface.
235    [Tags]  Verify_Autoconfig_Is_Present_On_Ethernet_Interface
236
237    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
238    Should Contain  ${resp.dict}  StatelessAddressAutoConfig
239
240
241*** Keywords ***
242
243Suite Setup Execution
244    [Documentation]  Do suite setup execution.
245
246    Redfish.Login
247    ${active_channel_config}=  Get Active Channel Config
248    Set Suite Variable  ${active_channel_config}
249
250    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
251
252    Set Suite variable  ${ethernet_interface}
253
254    ${initial_ipv4_addressorigin_list}  ${initial_ipv4_addr_list}=  Get Address Origin List And IPv4 or IPv6 Address  IPv4Addresses
255    ${initial_ipv6_addressorigin_list}  ${initial_ipv6_addr_list}=  Get Address Origin List And IPv4 or IPv6 Address  IPv6Addresses
256
257    Set Suite Variable   ${initial_ipv4_addressorigin_list}
258    Set Suite Variable   ${initial_ipv4_addr_list}
259    Set Suite Variable   ${initial_ipv6_addressorigin_list}
260    Set Suite Variable   ${initial_ipv6_addr_list}
261
262
263Test Setup Execution
264    [Documentation]  Test setup execution.
265
266    @{ipv6_network_configurations}=  Get IPv6 Network Configuration
267    Set Test Variable  @{ipv6_network_configurations}
268
269    # Get BMC IPv6 address and prefix length.
270    ${ipv6_data}=  Get BMC IPv6 Info
271    Set Test Variable  ${ipv6_data}
272
273
274Test Teardown Execution
275    [Documentation]  Test teardown execution.
276
277    FFDC On Test Case Fail
278
279
280Get IPv6 Network Configuration
281    [Documentation]  Get Ipv6 network configuration.
282    # Sample output:
283    # {
284    #  "@odata.id": "/redfish/v1/Managers/${MANAGER_ID}/EthernetInterfaces/eth0",
285    #  "@odata.type": "#EthernetInterface.v1_4_1.EthernetInterface",
286    #   "DHCPv4": {
287    #    "DHCPEnabled": false,
288    #    "UseDNSServers": false,
289    #    "UseDomainName": true,
290    #    "UseNTPServers": false
291    #  },
292    #  "DHCPv6": {
293    #    "OperatingMode": "Disabled",
294    #    "UseDNSServers": false,
295    #    "UseDomainName": true,
296    #    "UseNTPServers": false
297    #  },
298    #  "Description": "Management Network Interface",
299    #  "FQDN": "localhost",
300    #  "HostName": "localhost",
301    #  "IPv4Addresses": [
302    #    {
303    #      "Address": "xx.xx.xx.xx",
304    #      "AddressOrigin": "Static",
305    #      "Gateway": "xx.xx.xx.1",
306    #      "SubnetMask": "xx.xx.xx.0"
307    #    },
308    #    {
309    #      "Address": "169.254.xx.xx",
310    #      "AddressOrigin": "IPv4LinkLocal",
311    #      "Gateway": "0.0.0.0",
312    #      "SubnetMask": "xx.xx.0.0"
313    #    },
314    #  ],
315    #  "IPv4StaticAddresses": [
316    #    {
317    #      "Address": "xx.xx.xx.xx",
318    #      "AddressOrigin": "Static",
319    #      "Gateway": "xx.xx.xx.1",
320    #      "SubnetMask": "xx.xx.0.0"
321    #    }
322    # }
323    #  ],
324    #  "IPv6AddressPolicyTable": [],
325    #  "IPv6Addresses": [
326    #    {
327    #      "Address": "fe80::xxxx:xxxx:xxxx:xxxx",
328    #      "AddressOrigin": "LinkLocal",
329    #      "AddressState": null,
330    #      "PrefixLength": xx
331    #    }
332    #  ],
333    #  "IPv6DefaultGateway": "",
334    #  "IPv6StaticAddresses": [
335    #    { "Address": "xxxx:xxxx:xxxx:xxxx::xxxx",
336    #      "AddressOrigin": "Static",
337    #      "AddressState": null,
338    #      "PrefixLength": xxx
339    #    }
340    #  ],
341    #  "Id": "eth0",
342    #  "InterfaceEnabled": true,
343    #  "LinkStatus": "LinkUp",
344    #  "MACAddress": "xx:xx:xx:xx:xx:xx",
345    #  "Name": "Manager Ethernet Interface",
346    #  "NameServers": [],
347    #  "SpeedMbps": 0,
348    #  "StaticNameServers": [],
349    #  "Status": {
350    #    "Health": "OK",
351    #    "HealthRollup": "OK",
352    #    "State": "Enabled"
353    #  },
354    #  "VLANs": {
355    #    "@odata.id": "/redfish/v1/Managers/${MANAGER_ID}/EthernetInterfaces/eth0/VLANs"
356
357
358    ${active_channel_config}=  Get Active Channel Config
359    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${active_channel_config['${CHANNEL_NUMBER}']['name']}
360
361    @{ipv6_network_configurations}=  Get From Dictionary  ${resp.dict}  IPv6StaticAddresses
362    RETURN  @{ipv6_network_configurations}
363
364
365Verify IPv6 And PrefixLength
366    [Documentation]  Verify IPv6 address and prefix length on BMC.
367    [Arguments]  ${ipv6_addr}  ${prefix_len}
368
369    # Description of the argument(s):
370    # ipv6_addr   IPv6 address to be verified.
371    # prefix_len  PrefixLength value to be verified.
372
373    # Catenate IPv6 address and its prefix length.
374    ${ipv6_with_prefix}=  Catenate  ${ipv6_addr}/${prefix_len}
375
376    # Get IPv6 address details on BMC using IP command.
377    @{ip_data}=  Get BMC IPv6 Info
378
379    # Verify if IPv6 and prefix length is configured on BMC.
380
381    Should Contain  ${ip_data}  ${ipv6_with_prefix}
382    ...  msg=IPv6 and prefix length pair does not exist.
383
384
385Configure IPv6 Address On BMC
386    [Documentation]  Add IPv6 Address on BMC.
387    [Arguments]  ${ipv6_addr}  ${prefix_len}  ${valid_status_codes}=${HTTP_OK}
388
389    # Description of argument(s):
390    # ipv6_addr           IPv6 address to be added (e.g. "2001:EEEE:2222::2022").
391    # prefix_len          Prefix length for the IPv6 to be added
392    #                     (e.g. "64").
393    # valid_status_codes  Expected return code from patch operation
394    #                     (e.g. "200").
395
396    ${prefix_length}=  Convert To Integer  ${prefix_len}
397    ${empty_dict}=  Create Dictionary
398    ${ipv6_data}=  Create Dictionary  Address=${ipv6_addr}
399    ...  PrefixLength=${prefix_length}
400
401    ${patch_list}=  Create List
402
403    # Get existing static IPv6 configurations on BMC.
404    ${ipv6_network_configurations}=  Get IPv6 Network Configuration
405    ${num_entries}=  Get Length  ${ipv6_network_configurations}
406
407    FOR  ${INDEX}  IN RANGE  0  ${num_entries}
408      Append To List  ${patch_list}  ${empty_dict}
409    END
410
411    ${valid_status_codes}=  Set Variable If  '${valid_status_codes}' == '${HTTP_OK}'
412    ...  ${HTTP_OK},${HTTP_NO_CONTENT}
413    ...  ${valid_status_codes}
414
415    # We need not check for existence of IPv6 on BMC while adding.
416    Append To List  ${patch_list}  ${ipv6_data}
417    ${data}=  Create Dictionary  IPv6StaticAddresses=${patch_list}
418
419    ${active_channel_config}=  Get Active Channel Config
420    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
421
422    Redfish.patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}  body=&{data}
423    ...  valid_status_codes=[${valid_status_codes}]
424
425    Return From Keyword If  '${valid_status_codes}' != '${HTTP_OK},${HTTP_NO_CONTENT}'
426
427    # Note: Network restart takes around 15-18s after patch request processing.
428    Sleep  ${NETWORK_TIMEOUT}s
429    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
430
431    Verify IPv6 And PrefixLength  ${ipv6_addr}  ${prefix_len}
432
433    # Verify if existing static IPv6 addresses still exist.
434    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
435      Verify IPv6 On BMC  ${ipv6_network_configuration['Address']}
436    END
437
438    Validate IPv6 Network Config On BMC
439
440
441Validate IPv6 Network Config On BMC
442    [Documentation]  Check that IPv6 network info obtained via redfish matches info
443    ...              obtained via CLI.
444
445    @{ipv6_network_configurations}=  Get IPv6 Network Configuration
446    ${ipv6_data}=  Get BMC IPv6 Info
447    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
448      Should Contain Match  ${ipv6_data}  ${ipv6_network_configuration['Address']}/*
449      ...  msg=IPv6 address does not exist.
450    END
451
452
453Delete IPv6 Address
454    [Documentation]  Delete IPv6 address of BMC.
455    [Arguments]  ${ipv6_addr}
456    ...          ${valid_status_codes}=[${HTTP_OK},${HTTP_ACCEPTED},${HTTP_NO_CONTENT}]
457
458    # Description of argument(s):
459    # ipv6_addr           IPv6 address to be deleted (e.g. "2001:1234:1234:1234::1234").
460    # valid_status_codes  Expected return code from patch operation
461    #                     (e.g. "200").  See prolog of rest_request
462    #                     method in redfish_plus.py for details.
463
464    ${empty_dict}=  Create Dictionary
465    ${patch_list}=  Create List
466
467    @{ipv6_network_configurations}=  Get IPv6 Network Configuration
468    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
469        IF  '${ipv6_network_configuration['Address']}' == '${ipv6_addr}'
470            Append To List  ${patch_list}  ${null}
471        ELSE
472            Append To List  ${patch_list}  ${empty_dict}
473        END
474    END
475
476    ${ip_found}=  Run Keyword And Return Status  List Should Contain Value
477    ...  ${patch_list}  ${null}  msg=${ipv6_addr} does not exist on BMC
478    Pass Execution If  ${ip_found} == ${False}  ${ipv6_addr} does not exist on BMC
479
480    # Run patch command only if given IP is found on BMC
481    ${data}=  Create Dictionary  IPv6StaticAddresses=${patch_list}
482
483    ${active_channel_config}=  Get Active Channel Config
484    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
485
486    Redfish.patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}  body=&{data}
487    ...  valid_status_codes=${valid_status_codes}
488
489    # Note: Network restart takes around 15-18s after patch request processing
490    Sleep  ${NETWORK_TIMEOUT}s
491    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
492
493    # IPv6 address that is deleted should not be there on BMC.
494    ${delete_status}=  Run Keyword And Return Status  Verify IPv6 On BMC  ${ipv6_addr}
495    IF  '${valid_status_codes}' == '[${HTTP_OK},${HTTP_ACCEPTED},${HTTP_NO_CONTENT}]'
496        Should Be True  '${delete_status}' == '${False}'
497    ELSE
498        Should Be True  '${delete_status}' == '${True}'
499    END
500
501    Validate IPv6 Network Config On BMC
502
503
504Modify IPv6 Address
505    [Documentation]  Modify and verify IPv6 address of BMC.
506    [Arguments]  ${ipv6}  ${new_ipv6}  ${prefix_len}
507    ...  ${valid_status_codes}=[${HTTP_OK}, ${HTTP_NO_CONTENT}]
508
509    # Description of argument(s):
510    # ipv6                  IPv6 address to be replaced (e.g. "2001:AABB:CCDD::AAFF").
511    # new_ipv6              New IPv6 address to be configured.
512    # prefix_len            Prefix length value (Range 1 to 128).
513    # valid_status_codes    Expected return code from patch operation
514    #                       (e.g. "200", "201").
515
516    ${empty_dict}=  Create Dictionary
517    ${patch_list}=  Create List
518    ${prefix_length}=  Convert To Integer  ${prefix_len}
519    ${ipv6_data}=  Create Dictionary
520    ...  Address=${new_ipv6}  PrefixLength=${prefix_length}
521
522    # Sample IPv6 network configurations:
523    #  "IPv6AddressPolicyTable": [],
524    #  "IPv6Addresses": [
525    #    {
526    #      "Address": "X002:db8:0:2::XX0",
527    #      "AddressOrigin": "DHCPv6",
528    #      "PrefixLength": 128
529    #    },
530    #    {
531    #      "Address": “X002:db8:0:2:a94:XXff:fe82:XXXX",
532    #      "AddressOrigin": "SLAAC",
533    #      "PrefixLength": 64
534    #    },
535    #    {
536    #      "Address": “Y002:db8:0:2:a94:efff:fe82:5000",
537    #      "AddressOrigin": "Static",
538    #      "PrefixLength": 56
539    #    },
540    #    {
541    #      "Address": “Z002:db8:0:2:a94:efff:fe82:5000",
542    #      "AddressOrigin": "Static",
543    #      "PrefixLength": 56
544    #    },
545    #    {
546    #      "Address": “Xe80::a94:efff:YYYY:XXXX",
547    #      "AddressOrigin": "LinkLocal",
548    #      "PrefixLength": 64
549    #    },
550    #    {
551    #     "Address": “X002:db8:1:2:eff:233:fee:546",
552    #      "AddressOrigin": "Static",
553    #      "PrefixLength": 56
554    #    }
555    #  ],
556    #  "IPv6DefaultGateway": “XXXX::ab2e:80fe:87df:XXXX”,
557    #  "IPv6StaticAddresses": [
558    #    {
559    #      "Address": “X002:db8:0:2:a94:efff:fe82:5000",
560    #      "PrefixLength": 56
561    #    },
562    #    {
563    #      "Address": “Y002:db8:0:2:a94:efff:fe82:5000",
564    #      "PrefixLength": 56
565    #    },
566    #    {
567    #      "Address": “Z002:db8:1:2:eff:233:fee:546",
568    #      "PrefixLength": 56
569    #    }
570    #  ],
571    #  "IPv6StaticDefaultGateways": [],
572
573    # Find the position of IPv6 address to be modified.
574    @{ipv6_network_configurations}=  Get IPv6 Network Configuration
575    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
576      IF  '${ipv6_network_configuration['Address']}' == '${ipv6}'
577          Append To List  ${patch_list}  ${ipv6_data}
578      ELSE
579          Append To List  ${patch_list}  ${empty_dict}
580      END
581    END
582
583    # Modify the IPv6 address only if given IPv6 is found
584    ${ip_found}=  Run Keyword And Return Status  List Should Contain Value
585    ...  ${patch_list}  ${ipv6_data}  msg=${ipv6} does not exist on BMC
586    Pass Execution If  ${ip_found} == ${False}  ${ipv6} does not exist on BMC
587
588    ${data}=  Create Dictionary  IPv6StaticAddresses=${patch_list}
589
590    ${active_channel_config}=  Get Active Channel Config
591    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
592
593    Redfish.patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
594    ...  body=&{data}  valid_status_codes=${valid_status_codes}
595
596    # Note: Network restart takes around 15-18s after patch request processing.
597    Sleep  ${NETWORK_TIMEOUT}s
598    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
599
600    # Verify if new IPv6 address is configured on BMC.
601    Verify IPv6 On BMC  ${new_ipv6}
602
603    # Verify if old IPv6 address is erased.
604    ${cmd_status}=  Run Keyword And Return Status
605    ...  Verify IPv6 On BMC  ${ipv6}
606    Should Be Equal  ${cmd_status}  ${False}  msg=Old IPv6 address is not deleted.
607
608    Validate IPv6 Network Config On BMC
609
610
611Set SLAAC Configuration State And Verify
612    [Documentation]  Set SLAAC configuration state and verify.
613    [Arguments]  ${slaac_state}  ${valid_status_codes}=[${HTTP_OK},${HTTP_ACCEPTED},${HTTP_NO_CONTENT}]
614    ...  ${channel_number}=${CHANNEL_NUMBER}
615
616    # Description of argument(s):
617    # slaac_state         SLAAC state('True' or 'False').
618    # valid_status_code   Expected valid status codes.
619    # channel_number      Channel number 1(eth0) or 2(eth1).
620
621    ${active_channel_config}=  Get Active Channel Config
622    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
623
624    ${data}=  Set Variable If  ${slaac_state} == ${False}  ${DISABLE_SLAAC}  ${ENABLE_SLAAC}
625    ${resp}=  Redfish.Patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
626    ...  body=${data}  valid_status_codes=${valid_status_codes}
627
628    # Verify SLAAC is set correctly.
629    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
630    ${slaac_verify}=  Get From Dictionary  ${resp.dict}  StatelessAddressAutoConfig
631
632    IF  '${slaac_verify['IPv6AutoConfigEnabled']}' != '${slaac_state}'
633        Fail  msg=SLAAC not set properly.
634    END
635
636Set And Verify DHCPv6 Property
637    [Documentation]  Set DHCPv6 property and verify.
638    [Arguments]  ${dhcpv6_operating_mode}=${Disabled}  ${channel_number}=${CHANNEL_NUMBER}
639
640    # Description of argument(s):
641    # dhcpv6_operating_mode    Enabled if user wants to enable DHCPv6('Enabled' or 'Disabled').
642    # channel_number           Channel number 1 or 2.
643
644    Set DHCPv6 Property  ${dhcpv6_operating_mode}  ${channel_number}
645    Verify DHCPv6 Property  ${dhcpv6_operating_mode}  ${channel_number}
646
647
648Set DHCPv6 Property
649    [Documentation]  Set DHCPv6 attribute is enables or disabled.
650    [Arguments]  ${dhcpv6_operating_mode}=${Disabled}  ${channel_number}=${CHANNEL_NUMBER}
651
652    # Description of argument(s):
653    # dhcpv6_operating_mode    Enabled if user wants to enable DHCPv6('Enabled' or 'Disabled').
654    # channel_number           Channel number 1 or 2.
655
656    ${data}=  Set Variable If  '${dhcpv6_operating_mode}' == 'Disabled'  ${DISABLE_DHCPv6}  ${ENABLE_DHCPv6}
657    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
658
659    Redfish.Patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
660    ...  body=${data}  valid_status_codes=[${HTTP_OK},${HTTP_NO_CONTENT}]
661
662
663Verify DHCPv6 Property
664    [Documentation]  Verify DHCPv6 settings is enabled or disabled.
665    [Arguments]  ${dhcpv6_operating_mode}  ${channel_number}=${CHANNEL_NUMBER}
666
667    # Description of Argument(s):
668    # dhcpv6_operating_mode  Enable/ Disable DHCPv6.
669    # channel_number         Channel number 1 or 2.
670
671    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
672
673    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
674    ${dhcpv6_verify}=  Get From Dictionary  ${resp.dict}  DHCPv6
675
676    Should Be Equal  '${dhcpv6_verify['OperatingMode']}'  '${dhcpv6_operating_mode}'
677
678
679Get IPv6 Static Default Gateway
680    [Documentation]  Get IPv6 static default gateway.
681
682    ${active_channel_config}=  Get Active Channel Config
683    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${active_channel_config['${CHANNEL_NUMBER}']['name']}
684
685    @{ipv6_static_defgw_configurations}=  Get From Dictionary  ${resp.dict}  IPv6StaticDefaultGateways
686    RETURN  @{ipv6_static_defgw_configurations}
687
688
689Configure IPv6 Static Default Gateway On BMC
690    [Documentation]  Configure IPv6 static default gateway on BMC.
691    [Arguments]  ${ipv6_gw_addr}  ${prefix_length_def}
692    ...  ${valid_status_codes}=${HTTP_OK}
693
694    # Description of argument(s):
695    # ipv6_gw_addr          IPv6 Static Default Gateway address to be configured.
696    # prefix_len_def        Prefix length value (Range 1 to 128).
697    # valid_status_codes    Expected return code from patch operation
698    #                       (e.g. "200", "204".)
699
700    # Prefix Length is passed as None.
701    IF   '${prefix_length_def}' == '${None}'
702        ${ipv6_gw}=  Create Dictionary  Address=${ipv6_gw_addr}
703    ELSE
704        ${ipv6_gw}=  Create Dictionary  Address=${ipv6_gw_addr}  Prefix Length=${prefix_length_def}
705    END
706
707    ${ipv6_static_def_gw}=  Get IPv6 Static Default Gateway
708
709    ${num_entries}=  Get Length  ${ipv6_static_def_gw}
710
711    ${patch_list}=  Create List
712    ${empty_dict}=  Create Dictionary
713
714    FOR  ${INDEX}  IN RANGE  0  ${num_entries}
715      Append To List  ${patch_list}  ${empty_dict}
716    END
717
718    ${valid_status_codes}=  Set Variable If  '${valid_status_codes}' == '${HTTP_OK}'
719    ...  ${HTTP_OK},${HTTP_NO_CONTENT}
720    ...  ${valid_status_codes}
721
722    Append To List  ${patch_list}  ${ipv6_gw}
723    ${data}=  Create Dictionary  IPv6StaticDefaultGateways=${patch_list}
724
725    Redfish.Patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
726    ...  body=${data}  valid_status_codes=[${valid_status_codes}]
727
728    # Verify the added static default gateway is present in Redfish Get Output.
729    ${ipv6_staticdef_gateway}=  Get IPv6 Static Default Gateway
730
731    ${ipv6_static_def_gw_list}=  Create List
732    FOR  ${ipv6_staticdef_gateway}  IN  @{ipv6_staticdef_gateway}
733        ${value}=    Get From Dictionary    ${ipv6_staticdef_gateway}    Address
734        Append To List  ${ipv6_static_def_gw_list}  ${value}
735    END
736
737    IF  '${valid_status_codes}' != '${HTTP_OK},${HTTP_NO_CONTENT}'
738        Should Not Contain  ${ipv6_static_def_gw_list}  ${ipv6_gw_addr}
739    ELSE
740        Should Contain  ${ipv6_static_def_gw_list}  ${ipv6_gw_addr}
741    END
742
743
744Modify IPv6 Static Default Gateway On BMC
745    [Documentation]  Modify and verify IPv6 address of BMC.
746    [Arguments]  ${ipv6_gw_addr}  ${new_static_def_gw}  ${prefix_length}
747    ...  ${valid_status_codes}=[${HTTP_OK},${HTTP_ACCEPTED}]
748
749    # Description of argument(s):
750    # ipv6_gw_addr          IPv6 static default gateway address to be replaced (e.g. "2001:AABB:CCDD::AAFF").
751    # new_static_def_gw     New static default gateway address to be configured.
752    # prefix_length         Prefix length value (Range 1 to 128).
753    # valid_status_codes    Expected return code from patch operation
754    #                       (e.g. "200", "204").
755
756    ${empty_dict}=  Create Dictionary
757    ${patch_list}=  Create List
758    # Prefix Length is passed as None.
759    IF   '${prefix_length_def}' == '${None}'
760        ${modified_ipv6_gw_addripv6_data}=  Create Dictionary  Address=${new_static_def_gw}
761    ELSE
762        ${modified_ipv6_gw_addripv6_data}=  Create Dictionary  Address=${new_static_def_gw}  Prefix Length=${prefix_length_def}
763    END
764
765    @{ipv6_static_def_gw_list}=  Get IPv6 Static Default Gateway
766
767    FOR  ${ipv6_static_def_gw}  IN  @{ipv6_static_def_gw_list}
768      IF  '${ipv6_static_def_gw['Address']}' == '${ipv6_gw_addr}'
769          Append To List  ${patch_list}  ${modified_ipv6_gw_addripv6_data}
770      ELSE
771          Append To List  ${patch_list}  ${empty_dict}
772      END
773    END
774
775    # Modify the IPv6 address only if given IPv6 static default gateway is found.
776    ${ip_static_def_gw_found}=  Run Keyword And Return Status  List Should Contain Value
777    ...  ${patch_list}  ${modified_ipv6_gw_addripv6_data}  msg=${ipv6_gw_addr} does not exist on BMC
778    Pass Execution If  ${ip_static_def_gw_found} == ${False}  ${ipv6_gw_addr} does not exist on BMC
779
780    ${data}=  Create Dictionary  IPv6StaticDefaultGateways=${patch_list}
781
782    Redfish.Patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
783    ...  body=&{data}  valid_status_codes=${valid_status_codes}
784
785    ${ipv6_staticdef_gateway}=  Get IPv6 Static Default Gateway
786
787    ${ipv6_static_def_gw_list}=  Create List
788    FOR  ${ipv6_staticdef_gateway}  IN  @{ipv6_staticdef_gateway}
789        ${value}=  Get From Dictionary  ${ipv6_staticdef_gateway}  Address
790        Append To List  ${ipv6_static_def_gw_list}  ${value}
791    END
792
793    Should Contain  ${ipv6_static_def_gw_list}  ${new_static_def_gw}
794    # Verify if old static default gateway address is erased.
795    Should Not Contain  ${ipv6_static_def_gw_list}  ${ipv6_gw_addr}
796
797
798Delete IPv6 Static Default Gateway
799    [Documentation]  Delete IPv6 static default gateway on BMC.
800    [Arguments]  ${ipv6_gw_addr}
801    ...          ${valid_status_codes}=[${HTTP_OK},${HTTP_ACCEPTED},${HTTP_NO_CONTENT}]
802
803    # Description of argument(s):
804    # ipv6_gw_addr          IPv6 Static Default Gateway address to be deleted.
805    # valid_status_codes    Expected return code from patch operation
806    #                       (e.g. "200").
807
808    ${patch_list}=  Create List
809    ${empty_dict}=  Create Dictionary
810
811    ${ipv6_static_def_gw_list}=  Create List
812    @{ipv6_static_defgw_configurations}=  Get IPv6 Static Default Gateway
813
814    FOR  ${ipv6_staticdef_gateway}  IN  @{ipv6_static_defgw_configurations}
815        ${value}=  Get From Dictionary  ${ipv6_staticdef_gateway}  Address
816        Append To List  ${ipv6_static_def_gw_list}  ${value}
817    END
818
819    ${defgw_found}=  Run Keyword And Return Status  List Should Contain Value
820    ...  ${ipv6_static_def_gw_list}  ${ipv6_gw_addr}  msg=${ipv6_gw_addr} does not exist on BMC
821    Skip If  ${defgw_found} == ${False}  ${ipv6_gw_addr} does not exist on BMC
822
823    FOR  ${ipv6_static_def_gw}  IN  @{ipv6_static_defgw_configurations}
824        IF  '${ipv6_static_def_gw['Address']}' == '${ipv6_gw_addr}'
825            Append To List  ${patch_list}  ${null}
826        ELSE
827            Append To List  ${patch_list}  ${empty_dict}
828      END
829    END
830
831    # Run patch command only if given IP is found on BMC.
832    ${data}=  Create Dictionary  IPv6StaticDefaultGateways=${patch_list}
833
834    Redfish.Patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}  body=&{data}
835    ...  valid_status_codes=${valid_status_codes}
836
837    ${data}=  Create Dictionary  IPv6StaticDefaultGateways=${patch_list}
838
839    @{ipv6_static_defgw_configurations}=  Get IPv6 Static Default Gateway
840    Should Not Contain Match  ${ipv6_static_defgw_configurations}  ${ipv6_gw_addr}
841    ...  msg=IPv6 Static default gateway does not exist.
842
843
844Check Coexistence Of Linklocalv6 And Static IPv6
845    [Documentation]  Verify both linklocalv6 and static IPv6 exist.
846
847    # Verify the address origin contains static and linklocal.
848    @{ipv6_addressorigin_list}  ${ipv6_linklocal_addr}=  Get Address Origin List And Address For Type  LinkLocal
849
850    Should Match Regexp  ${ipv6_linklocal_addr}        ${linklocal_addr_format}
851    Should Contain       ${ipv6_addressorigin_list}    Static
852
853
854Check If Linklocal Address Is In Correct Format
855    [Documentation]  Linklocal address has network part fe80 and host part EUI64.
856
857    # Fetch the linklocal address.
858    @{ipv6_addressorigin_list}  ${ipv6_linklocal_addr}=  Get Address Origin List And Address For Type  LinkLocal
859
860    # Follow EUI64 from MAC.
861    ${system_mac}=  Get BMC MAC Address
862    ${split_octets}=  Split String  ${system_mac}  :
863    ${first_octet}=  Evaluate  int('${split_octets[0]}', 16)
864    ${flipped_hex}=  Evaluate  format(${first_octet} ^ 2, '02x')
865    ${grp1}=  Evaluate  re.sub(r'^0+', '', '${flipped_hex}${split_octets[1]}')  modules=re
866    ${grp2}=  Evaluate  re.sub(r'^0+', '', '${split_octets[2]}ff')  modules=re
867    ${grp3}=  Evaluate  re.sub(r'^0+', '', '${split_octets[4]}${split_octets[5]}')  modules=re
868    ${linklocal}=  Set Variable  fe80::${grp1}:${grp2}:fe${split_octets[3]}:${grp3}
869
870    # Verify the linklocal obtained is the same as on the machine.
871    Should Be Equal  ${linklocal}  ${ipv6_linklocal_addr}
872
873
874Check BMC Gets SLAAC Address
875    [Documentation]  Check BMC gets slaac address.
876
877    @{ipv6_addressorigin_list}  ${ipv6_slaac_addr}=  Get Address Origin List And Address For Type  SLAAC
878
879
880Get The Initial DHCPv6 Setting On Each Interface
881    [Documentation]  Get the initial DHCPv6 setting of each interface.
882    [Arguments]  ${channel_number}
883
884    # Description of the argument(s):
885    # channel_number    Channel number 1 or 2.
886
887    ${ethernet_interface}=  Set Variable  ${active_channel_config['${channel_number}']['name']}
888    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
889    ${initial_dhcpv6_iface}=  Get From Dictionary  ${resp.dict}  DHCPv6
890    IF  ${channel_number}==${1}
891        Set Test Variable  ${dhcpv6_channel_1}  ${initial_dhcpv6_iface['OperatingMode']}
892    ELSE
893        Set Test Variable  ${dhcpv6_channel_2}  ${initial_dhcpv6_iface['OperatingMode']}
894    END
895
896
897Get The Initial DHCPv6 Settings
898    [Documentation]  Get the initial DHCPv6 settings of both the interfaces.
899
900    Get The Initial DHCPv6 Setting On Each Interface  ${1}
901    Get The Initial DHCPv6 Setting On Each Interface  ${2}
902
903
904Get The Initial SLAAC Settings
905    [Documentation]  Get the initial SLAAC settings of both the interfaces.
906
907    Get The Initial SLAAC Setting On Each Interface  ${1}
908    Get The Initial SLAAC Setting On Each Interface   ${2}
909
910
911Get The Initial SLAAC Setting On Each Interface
912    [Documentation]  Get the initial SLAAC setting of the interface.
913    [Arguments]  ${channel_number}
914
915    # Description of the argument(s):
916    # channel_number     Channel number 1 or 2.
917
918    ${ethernet_interface}=  Set Variable  ${active_channel_config['${channel_number}']['name']}
919    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
920    ${initial_slaac_iface}=  Get From Dictionary  ${resp.dict}  StatelessAddressAutoConfig
921    IF  ${channel_number}==${1}
922        Set Test Variable  ${slaac_channel_1}  ${initial_slaac_iface['IPv6AutoConfigEnabled']}
923    ELSE
924        Set Test Variable  ${slaac_channel_2}  ${initial_slaac_iface['IPv6AutoConfigEnabled']}
925    END
926
927
928Get Address Origin List And Address For Type
929    [Documentation]  Get address origin list and address for type.
930    [Arguments]  ${ipv6_address_type}
931
932    # Description of the argument(s):
933    # ipv6_address_type  Type of IPv6 address to be checked.
934
935    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${active_channel_config['${CHANNEL_NUMBER}']['name']}
936    @{ipv6_addresses}=  Get From Dictionary  ${resp.dict}  IPv6Addresses
937
938    ${ipv6_addressorigin_list}=  Create List
939    ${ipv6_slaac_addr}=  Set Variable  ${None}
940    FOR  ${ipv6_address}  IN  @{ipv6_addresses}
941        ${ipv6_addressorigin}=  Get From Dictionary  ${ipv6_address}  AddressOrigin
942        Append To List  ${ipv6_addressorigin_list}  ${ipv6_addressorigin}
943        IF  '${ipv6_addressorigin}' == '${ipv6_address_type}'
944            Set Test Variable  ${ipv6_type_addr}  ${ipv6_address['Address']}
945        END
946    END
947    Should Contain  ${ipv6_addressorigin_list}  ${ipv6_address_type}
948    Should Not Be Empty  ${ipv6_type_addr}  msg=${ipv6_address_type} address is not present
949    RETURN  @{ipv6_addressorigin_list}  ${ipv6_type_addr}
950
951
952Get Address Origin List And IPv4 or IPv6 Address
953    [Documentation]  Get address origin list and address for type.
954    [Arguments]  ${ip_address_type}
955
956    # Description of the argument(s):
957    # ip_address_type  Type of IPv4 or IPv6 address to be checked.
958
959    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${active_channel_config['${CHANNEL_NUMBER}']['name']}
960    @{ip_addresses}=  Get From Dictionary  ${resp.dict}  ${ip_address_type}
961
962    ${ip_addressorigin_list}=  Create List
963    ${ip_addr_list}=  Create List
964    FOR  ${ip_address}  IN  @{ip_addresses}
965        ${ip_addressorigin}=  Get From Dictionary  ${ip_address}  AddressOrigin
966        Append To List  ${ip_addressorigin_list}  ${ip_addressorigin}
967        Append To List  ${ip_addr_list}  ${ip_address['Address']}
968    END
969    RETURN  ${ip_addressorigin_list}  ${ip_addr_list}
970
971
972Verify All The Addresses Are Intact
973    [Documentation]  Verify all the addresses and address origins remain intact.
974
975    # Verify that it will not impact the IPv4 configuration.
976    Sleep  ${NETWORK_TIMEOUT}
977    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
978
979    # IPv6 address must be present.
980    @{ipv6_addressorigin_list}  ${ipv6_slaac_addr}=  Get Address Origin List And Address For Type  SLAAC
981    @{ipv6_addressorigin_list}  ${ipv6_linklocal_addr}=  Get Address Origin List And Address For Type  LinkLocal
982
983    # IPv4 and IPv6 addresses must remain intact.
984    ${ipv4_addressorigin_list}  ${ipv4_addr_list}=  Get Address Origin List And IPv4 or IPv6 Address  IPv4Addresses
985    ${ipv6_addressorigin_list}  ${ipv6_addr_list}=  Get Address Origin List And IPv4 or IPv6 Address  IPv6Addresses
986
987    ${ipv6_is_subset}=  Evaluate  set(${initial_ipv6_addr_list}).issubset(set(${ipv6_addr_list}))
988    Should Be True  ${ipv6_is_subset}
989
990    Should be Equal  ${initial_ipv4_addressorigin_list}  ${ipv4_addressorigin_list}
991    Should be Equal  ${initial_ipv4_addr_list}  ${ipv4_addr_list}
992