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