xref: /openbmc/openbmc-test-automation/lib/bmc_ipv6_utils.robot (revision 1d03ee954c3c53fadcac65e0c3ae1029ff6351b7)
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${test_ipv6_addr}           2001:db8:3333:4444:5555:6666:7777:9999
11${test_prefix_length}       64
12
13*** Keywords ***
14
15Get BMC IPv6 Info
16    [Documentation]  Get system IPv6 address and prefix length.
17
18    # Get system IP address and prefix length details using "ip addr"
19    # Sample Output of "ip addr":
20    # 1: eth0: <BROADCAST,MULTIAST> mtu 1500 qdisc mq state UP qlen 1000
21    #     link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
22    #     inet xx.xx.xx.xx/24 brd xx.xx.xx.xx scope global eth0
23    #     inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
24    #     inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope global
25
26    ${cmd_output}  ${stderr}  ${rc}=  BMC Execute Command  /sbin/ip addr
27
28    # Get line having IPv6 address details.
29    ${lines}=  Get Lines Containing String  ${cmd_output}  inet6
30
31    # List IP address details.
32    @{ip_components}=  Split To Lines  ${lines}
33
34    @{ipv6_data}=  Create List
35
36    # Get all IP addresses and prefix lengths on system.
37    FOR  ${ip_component}  IN  @{ip_components}
38      @{if_info}=  Split String  ${ip_component}
39      ${ip_n_prefix}=  Get From List  ${if_info}  1
40      Append To List  ${ipv6_data}  ${ip_n_prefix}
41    END
42
43    RETURN  ${ipv6_data}
44
45
46Verify IPv6 On BMC
47    [Documentation]  Verify IPv6 on BMC.
48    [Arguments]  ${ipv6}
49
50    # Description of argument(s):
51    # ipv6  IPv6 address to be verified (e.g. "2001::1234:1234").
52
53    # Get IPv6 address details on BMC using IP command.
54    @{ip_data}=  Get BMC IPv6 Info
55    Should Contain Match  ${ip_data}  ${ipv6}/*
56    ...  msg=IPv6 address does not exist.
57
58
59Verify IPv6 Default Gateway On BMC
60    [Documentation]  Verify IPv6 default gateway on BMC.
61    [Arguments]  ${gateway_ip}=0:0:0:0:0:0:0:0
62
63    # Description of argument(s):
64    # gateway_ip  Gateway IPv6 address.
65
66    ${route_info}=  Get BMC IPv6 Route Info
67
68    # If gateway IP is empty it will not have route entry.
69
70    IF  '${gateway_ip}' == '0:0:0:0:0:0:0:0'
71        Pass Execution  Gateway IP is not configured.
72    ELSE
73        Should Contain  ${route_info}  ${gateway_ip}  msg=Gateway IP address not matching.
74    END
75
76
77Get BMC IPv6 Route Info
78    [Documentation]  Get IPv6 route info on BMC.
79
80    # Sample output of "ip -6 route":
81    # unreachable ::/96 dev lo metric 1024 error -113
82    # unreachable ::ffff:0.0.0.0/96 dev lo metric 1024 error -113
83    # 2xxx:xxxx:0:1::/64 dev eth0 proto kernel metric 256
84    # fe80::/64 dev eth1 proto kernel metric 256
85    # fe80::/64 dev eth0 proto kernel metric 256
86    # fe80::/64 dev eth2 proto kernel metric 256
87
88
89    ${cmd_output}  ${stderr}  ${rc}=  BMC Execute Command
90    ...  /sbin/ip -6 route
91
92    RETURN  ${cmd_output}
93
94
95Get Address Origin List And Address For Type
96    [Documentation]  Get address origin list and address for type.
97    [Arguments]  ${ipv6_address_type}  ${channel_number}=${CHANNEL_NUMBER}
98
99    # Description of the argument(s):
100    # ipv6_address_type  Type of IPv6 address to be checked.
101    # channel_number      Channel number 1(eth0) or 2(eth1).
102
103    ${active_channel_config}=  Get Active Channel Config
104    ${ethernet_interface}=  Set Variable  ${active_channel_config['${channel_number}']['name']}
105    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${active_channel_config['${channel_number}']['name']}
106    @{ipv6_addresses}=  Get From Dictionary  ${resp.dict}  IPv6Addresses
107
108    ${ipv6_addressorigin_list}=  Create List
109    FOR  ${ipv6_address}  IN  @{ipv6_addresses}
110        ${ipv6_addressorigin}=  Get From Dictionary  ${ipv6_address}  AddressOrigin
111        Append To List  ${ipv6_addressorigin_list}  ${ipv6_addressorigin}
112        IF  '${ipv6_addressorigin}' == '${ipv6_address_type}'
113            Set Test Variable  ${ipv6_type_addr}  ${ipv6_address['Address']}
114        END
115    END
116    Should Contain  ${ipv6_addressorigin_list}  ${ipv6_address_type}
117    Should Not Be Empty  ${ipv6_type_addr}  msg=${ipv6_address_type} address is not present
118    RETURN  @{ipv6_addressorigin_list}  ${ipv6_type_addr}
119
120
121Verify The Coexistence Of The Address Type
122    [Documentation]  Verify the coexistence of the address type.
123    [Arguments]  @{ipv6_address_types}
124
125    # Description of the argument(s):
126    # ipv6_address_types  Types of IPv6 address to be checked.
127
128    FOR  ${ipv6_address_type}  IN  @{ipv6_address_types}
129        @{ipv6_address_origin_list}  ${ipv6_type_addr}=
130        ...  Get Address Origin List And Address For Type  ${ipv6_address_type}
131        Should Contain    ${ipv6_address_origin_list}  ${ipv6_address_type}
132        Should Not Be Empty    ${ipv6_type_addr}  msg=${ipv6_address_type} address is not present
133    END
134
135
136Get Address Origin List And IPv4 or IPv6 Address
137    [Documentation]  Get address origin list and address for type.
138    [Arguments]  ${ip_address_type}  ${channel_number}=${CHANNEL_NUMBER}
139
140    # Description of the argument(s):
141    # ip_address_type  Type of IPv4 or IPv6 address to be checked.
142    # channel_number   Channel number 1(eth0) or 2(eth1).
143
144    ${active_channel_config}=  Get Active Channel Config
145    ${ethernet_interface}=  Set Variable  ${active_channel_config['${channel_number}']['name']}
146    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${active_channel_config['${channel_number}']['name']}
147    @{ip_addresses}=  Get From Dictionary  ${resp.dict}  ${ip_address_type}
148
149    ${ip_addressorigin_list}=  Create List
150    ${ip_addr_list}=  Create List
151    FOR  ${ip_address}  IN  @{ip_addresses}
152        ${ip_addressorigin}=  Get From Dictionary  ${ip_address}  AddressOrigin
153        Append To List  ${ip_addressorigin_list}  ${ip_addressorigin}
154        Append To List  ${ip_addr_list}  ${ip_address['Address']}
155    END
156    RETURN  ${ip_addressorigin_list}  ${ip_addr_list}
157
158
159Configure IPv6 Address On BMC
160    [Documentation]  Add IPv6 Address on BMC.
161    [Arguments]  ${ipv6_addr1}  ${prefix_len}  ${ipv6_addr2}=${None}
162    ...  ${channel_number}=${CHANNEL_NUMBER}
163    ...  ${valid_status_codes}=[${HTTP_OK},${HTTP_NO_CONTENT}]  ${Version}=IPv4
164
165    # Description of argument(s):
166    # ipv6_addr1          IPv6 address to be added (e.g. "2001:0022:0033::0111").
167    # ipv6_addr2          IPv6 address to be Verified (e.g. "2001:22:33::111").
168    # prefix_len          Prefix length for the IPv6 to be added
169    #                     (e.g. "64").
170    # channel_number      Channel number (1 - eth0 and 2 - eth1).
171    # valid_status_codes  Expected return code from patch operation
172    #                     (e.g. "200").
173
174    ${prefix_length}=  Convert To Integer  ${prefix_len}
175    ${empty_dict}=  Create Dictionary
176    ${ipv6_data}=  Create Dictionary  Address=${ipv6_addr1}
177    ...  PrefixLength=${prefix_length}
178
179    ${patch_list}=  Create List
180
181    # Get existing static IPv6 configurations on BMC.
182    ${ipv6_network_configurations}=  Get IPv6 Network Configuration  ${channel_number}
183    ${num_entries}=  Get Length  ${ipv6_network_configurations}
184
185    FOR  ${INDEX}  IN RANGE  0  ${num_entries}
186      Append To List  ${patch_list}  ${empty_dict}
187    END
188
189    # Check for existence of IPv6 on BMC while adding.
190    Append To List  ${patch_list}  ${ipv6_data}
191    ${data}=  Create Dictionary  IPv6StaticAddresses=${patch_list}
192
193    ${active_channel_config}=  Get Active Channel Config
194    ${ethernet_interface}=  Set Variable  ${active_channel_config['${channel_number}']['name']}
195
196    IF  '${Version}' == 'IPv4'
197        Redfish.patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}  body=&{data}
198        ...  valid_status_codes=${valid_status_codes}
199    ELSE
200        Redfish IPv6.patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}  body=&{data}
201        ...  valid_status_codes=${valid_status_codes}
202    END
203
204    IF  ${valid_status_codes} != [${HTTP_OK}, ${HTTP_NO_CONTENT}]
205        Fail  msg=Static address not added correctly
206    END
207
208    # Note: Network restart takes around 15-18s after patch request processing.
209    Sleep  ${NETWORK_TIMEOUT}s
210    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
211
212    # Verify ip address on CLI.
213    IF  '${ipv6_addr2}' != '${None}'
214        Verify IPv6 And PrefixLength  ${ipv6_addr2}  ${prefix_len}
215    ELSE
216        Verify IPv6 And PrefixLength  ${ipv6_addr1}  ${prefix_len}
217    END
218
219    # Verify if existing static IPv6 addresses still exist.
220    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
221      Verify IPv6 On BMC  ${ipv6_network_configuration['Address']}
222    END
223
224    #Verify redfish and CLI data matches.
225    Validate IPv6 Network Config On BMC
226
227
228Get IPv6 Network Configuration
229    [Documentation]  Get Ipv6 network configuration.
230    [Arguments]  ${channel_number}=${CHANNEL_NUMBER}
231
232    # Description of argument(s):
233    # channel_number  Channel number (1 - eth0 and 2 - eth1).
234
235    # Sample output:
236    # {
237    #  "@odata.id": "/redfish/v1/Managers/${MANAGER_ID}/EthernetInterfaces/eth0",
238    #  "@odata.type": "#EthernetInterface.v1_4_1.EthernetInterface",
239    #   "DHCPv4": {
240    #    "DHCPEnabled": false,
241    #    "UseDNSServers": false,
242    #    "UseDomainName": true,
243    #    "UseNTPServers": false
244    #  },
245    #  "DHCPv6": {
246    #    "OperatingMode": "Disabled",
247    #    "UseDNSServers": false,
248    #    "UseDomainName": true,
249    #    "UseNTPServers": false
250    #  },
251    #  "Description": "Management Network Interface",
252    #  "FQDN": "localhost",
253    #  "HostName": "localhost",
254    #  "IPv4Addresses": [
255    #    {
256    #      "Address": "xx.xx.xx.xx",
257    #      "AddressOrigin": "Static",
258    #      "Gateway": "xx.xx.xx.1",
259    #      "SubnetMask": "xx.xx.xx.0"
260    #    },
261    #    {
262    #      "Address": "169.254.xx.xx",
263    #      "AddressOrigin": "IPv4LinkLocal",
264    #      "Gateway": "0.0.0.0",
265    #      "SubnetMask": "xx.xx.0.0"
266    #    },
267    #  ],
268    #  "IPv4StaticAddresses": [
269    #    {
270    #      "Address": "xx.xx.xx.xx",
271    #      "AddressOrigin": "Static",
272    #      "Gateway": "xx.xx.xx.1",
273    #      "SubnetMask": "xx.xx.0.0"
274    #    }
275    # }
276    #  ],
277    #  "IPv6AddressPolicyTable": [],
278    #  "IPv6Addresses": [
279    #    {
280    #      "Address": "fe80::xxxx:xxxx:xxxx:xxxx",
281    #      "AddressOrigin": "LinkLocal",
282    #      "AddressState": null,
283    #      "PrefixLength": xx
284    #    }
285    #  ],
286    #  "IPv6DefaultGateway": "",
287    #  "IPv6StaticAddresses": [
288    #    { "Address": "xxxx:xxxx:xxxx:xxxx::xxxx",
289    #      "AddressOrigin": "Static",
290    #      "AddressState": null,
291    #      "PrefixLength": xxx
292    #    }
293    #  ],
294    #  "Id": "eth0",
295    #  "InterfaceEnabled": true,
296    #  "LinkStatus": "LinkUp",
297    #  "MACAddress": "xx:xx:xx:xx:xx:xx",
298    #  "Name": "Manager Ethernet Interface",
299    #  "NameServers": [],
300    #  "SpeedMbps": 0,
301    #  "StaticNameServers": [],
302    #  "Status": {
303    #    "Health": "OK",
304    #    "HealthRollup": "OK",
305    #    "State": "Enabled"
306    #  },
307    #  "VLANs": {
308    #    "@odata.id": "/redfish/v1/Managers/${MANAGER_ID}/EthernetInterfaces/eth0/VLANs"
309
310
311    ${active_channel_config}=  Get Active Channel Config
312    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${active_channel_config['${channel_number}']['name']}
313
314    @{ipv6_network_configurations}=  Get From Dictionary  ${resp.dict}  IPv6StaticAddresses
315    RETURN  @{ipv6_network_configurations}
316
317
318Verify IPv6 And PrefixLength
319    [Documentation]  Verify IPv6 address and prefix length on BMC.
320    [Arguments]  ${ipv6_addr}  ${prefix_len}
321
322    # Description of the argument(s):
323    # ipv6_addr   IPv6 address to be verified.
324    # prefix_len  PrefixLength value to be verified.
325
326    # Catenate IPv6 address and its prefix length.
327    ${ipv6_with_prefix}=  Catenate  ${ipv6_addr}/${prefix_len}
328
329    # Get IPv6 address details on BMC using IP command.
330    @{ip_data}=  Get BMC IPv6 Info
331
332    # Verify if IPv6 and prefix length is configured on BMC.
333
334    Should Contain  ${ip_data}  ${ipv6_with_prefix}
335    ...  msg=IPv6 and prefix length pair does not exist.
336
337
338Validate IPv6 Network Config On BMC
339    [Documentation]  Check that IPv6 network info obtained via redfish matches info
340    ...              obtained via CLI.
341
342    @{ipv6_network_configurations}=  Get IPv6 Network Configuration
343    ${ipv6_data}=  Get BMC IPv6 Info
344    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
345      Should Contain Match  ${ipv6_data}  ${ipv6_network_configuration['Address']}/*
346      ...  msg=IPv6 address does not exist.
347    END
348