interfaces.robot revision fcc77752
1# Copyright (c) 2019 Cisco and/or its affiliates.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at:
5#
6#     http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13*** Settings ***
14| Library | resources.libraries.python.InterfaceUtil
15| Library | resources.libraries.python.NodePath
16
17*** Keywords ***
18| Set interfaces in path up
19| | [Documentation]
20| | ... | *Set UP state on VPP interfaces in path on all DUT nodes and set
21| | ... | maximal MTU.*
22| | ...
23# TODO: Rework KW to set all interfaces in path UP and set MTU (including
24# software interfaces. Run KW at the start phase of VPP setup to split
25# from other "functional" configuration. This will allow modularity of this
26# library
27| | :FOR | ${dut} | IN | @{duts}
28| | | ${if1_status} | ${value}= | Run Keyword And Ignore Error
29| | | ... | Variable Should Exist | ${${dut}_if1}
30| | | Run Keyword If | '${if1_status}' == 'PASS'
31| | | ... | Set Interface State | ${nodes['${dut}']} | ${${dut}_if1} | up
32| | | ... | ELSE
33| | | ... | Set Interface State | ${nodes['${dut}']} | ${${dut}_if1_1} | up
34| | | Run Keyword Unless | '${if1_status}' == 'PASS'
35| | | ... | Set Interface State | ${nodes['${dut}']} | ${${dut}_if1_2} | up
36| | | ${if2_status} | ${value}= | Run Keyword And Ignore Error
37| | | ... | Variable Should Exist | ${${dut}_if2}
38| | | Run Keyword If | '${if2_status}' == 'PASS'
39| | | ... | Set Interface State | ${nodes['${dut}']} | ${${dut}_if2} | up
40| | | ... | ELSE
41| | | ... | Set Interface State | ${nodes['${dut}']} | ${${dut}_if2_1} | up
42| | | Run Keyword Unless | '${if2_status}' == 'PASS'
43| | | ... | Set Interface State | ${nodes['${dut}']} | ${${dut}_if2_2} | up
44| | :FOR | ${dut} | IN | @{duts}
45| | | ${if1_status} | ${value}= | Run Keyword And Ignore Error
46| | | ... | Variable Should Exist | ${${dut}_if1}
47| | | Run Keyword If | '${if1_status}' == 'PASS'
48| | | ... | VPP Set Interface MTU | ${nodes['${dut}']} | ${${dut}_if1}
49| | | ... | ELSE
50| | | ... | VPP Set Interface MTU | ${nodes['${dut}']} | ${${dut}_if1_1}
51| | | Run Keyword Unless | '${if1_status}' == 'PASS'
52| | | ... | VPP Set Interface MTU | ${nodes['${dut}']} | ${${dut}_if1_2}
53| | | ${if2_status} | ${value}= | Run Keyword And Ignore Error
54| | | ... | Variable Should Exist | ${${dut}_if2}
55| | | Run Keyword If | '${if2_status}' == 'PASS'
56| | | ... | VPP Set Interface MTU | ${nodes['${dut}']} | ${${dut}_if2}
57| | | ... | ELSE
58| | | ... | VPP Set Interface MTU | ${nodes['${dut}']} | ${${dut}_if2_1}
59| | | Run Keyword Unless | '${if2_status}' == 'PASS'
60| | | ... | VPP Set Interface MTU | ${nodes['${dut}']} | ${${dut}_if2_2}
61| | All VPP Interfaces Ready Wait | ${nodes} | retries=${300}
62
63| Set single interfaces in path up
64| | [Documentation]
65| | ... | *Set UP state on single VPP interfaces in path on all DUT nodes and set
66| | ... | maximal MTU.*
67| | ...
68# TODO: Rework KW to set all interfaces in path UP and set MTU (including
69# software interfaces. Run KW at the start phase of VPP setup to split
70# from other "functional" configuration. This will allow modularity of this
71# library
72| | :FOR | ${dut} | IN | @{duts}
73| | | ${if1_status} | ${value}= | Run Keyword And Ignore Error
74| | | ... | Variable Should Exist | ${${dut}_if1}
75| | | Run Keyword If | '${if1_status}' == 'PASS'
76| | | ... | Set Interface State | ${nodes['${dut}']} | ${${dut}_if1} | up
77| | | ... | ELSE
78| | | ... | Set Interface State | ${nodes['${dut}']} | ${${dut}_if1_1} | up
79| | | Run Keyword Unless | '${if1_status}' == 'PASS'
80| | | ... | Set Interface State | ${nodes['${dut}']} | ${${dut}_if1_2} | up
81| | :FOR | ${dut} | IN | @{duts}
82| | | ${if1_status} | ${value}= | Run Keyword And Ignore Error
83| | | ... | Variable Should Exist | ${${dut}_if1}
84| | | Run Keyword If | '${if1_status}' == 'PASS'
85| | | ... | VPP Set Interface MTU | ${nodes['${dut}']} | ${${dut}_if1}
86| | | ... | ELSE
87| | | ... | VPP Set Interface MTU | ${nodes['${dut}']} | ${${dut}_if1_1}
88| | | Run Keyword Unless | '${if1_status}' == 'PASS'
89| | | ... | VPP Set Interface MTU | ${nodes['${dut}']} | ${${dut}_if1_2}
90| | All VPP Interfaces Ready Wait | ${nodes}
91
92| Get Vhost dump
93| | [Documentation] | Get vhost-user dump.
94| | ...
95| | ... | *Arguments:*
96| | ... | - node - DUT node data. Type: dictionary
97| | ...
98| | [Arguments] | ${dut_node}
99| | ...
100| | [Return] | ${vhost_dump}
101| | ...
102| | ${vhost_dump}= | Vhost User Dump | ${dut_node}
103
104| Initialize layer interface on node
105| | [Documentation]
106| | ... | Baseline interfaces variables to be created.
107| | ...
108| | ... | *Arguments:*
109| | ... | - dut - DUT node. Type: string
110| | ... | - count - Number of baseline interface variables. Type: integer
111| | ...
112| | ... | *Example:*
113| | ...
114| | ... | \| Initialize layer interface on node \| DUT1 \| 1 \|
115| | ...
116| | [Arguments] | ${dut} | ${count}=${1}
117| | ...
118| | ${dut_str}= | Convert To Lowercase | ${dut}
119| | :FOR | ${id} | IN RANGE | 1 | ${count} + 1
120| | | Set Test Variable | ${${dut_str}_if_${id}_1} | ${${dut_str}_if1}
121| | | Set Test Variable | ${${dut_str}_if_${id}_2} | ${${dut_str}_if2}
122
123| Initialize layer interface
124| | [Documentation]
125| | ... | Physical interfaces variables to be created on all DUTs.
126| | ...
127| | ... | *Arguments:*
128| | ... | - count - Number of untagged interfaces variables. Type: integer
129| | ...
130| | ... | *Example:*
131| | ...
132| | ... | \| Initialize layer interface \| 1 \|
133| | ...
134| | [Arguments] | ${count}=${1}
135| | ...
136| | :FOR | ${dut} | IN | @{duts}
137| | | Initialize layer interface on node | ${dut} | count=${count}
138| | Set Test Variable | ${prev_layer} | if
139| | Set interfaces in path up
140
141| Initialize layer driver
142| | [Documentation]
143| | ... | Initialize driver based interfaces on each DUT. Interfaces are
144| | ... | brought up.
145| | ...
146| | [Arguments] | ${driver}
147| | ...
148# TODO: Introduce the Pre- Initialize layer driver for preparing driver before
149# VPP starts and then Post- Initialize layer driver for preparing interfaces
150# after VPP starts. This way we can control actions needed for proper handling
151# of various driver-based interfaces in VPP.
152| | :FOR | ${dut} | IN | @{duts}
153| | | Run Keyword | Initialize layer ${driver} on node | ${dut}
154| | Set Test Variable | ${prev_layer} | vf
155| | Set interfaces in path up
156
157| Initialize layer vfio-pci on node
158| | [Documentation]
159| | ... | Initialize vfio-pci interfaces on DUT.
160| | ...
161| | ... | *Arguments:*
162| | ... | - dut - DUT node. Type: string
163| | ...
164| | ... | *Example:*
165| | ...
166| | ... | \| Initialize layer vfio-pci on node \| DUT1 \|
167| | ...
168| | [Arguments] | ${dut}
169| | ...
170| | No operation
171
172| Initialize layer avf on node
173| | [Documentation]
174| | ... | Initialize AVF interfaces on DUT.
175| | ...
176| | ... | *Arguments:*
177| | ... | - dut - DUT node. Type: string
178| | ...
179| | ... | *Example:*
180| | ...
181| | ... | \| Initialize layer avf on node \| DUT1 \|
182| | ...
183| | [Arguments] | ${dut}
184| | ...
185| | ${dut_str}= | Convert To Lowercase | ${dut}
186| | ${if1_vlan}= | Get Interface Vlan | ${nodes['${dut}']} | ${${dut}_if1}
187| | ${if2_vlan}= | Get Interface Vlan | ${nodes['${dut}']} | ${${dut}_if2}
188| | Set Test Variable | ${${dut_str}_vlan1} | ${if1_vlan}
189| | Set Test Variable | ${${dut_str}_vlan2} | ${if2_vlan}
190| | ${if1_pci}= | Get Interface PCI Addr | ${nodes['${dut}']}
191| | ... | ${${dut}_if1_vf0}
192| | ${if2_pci}= | Get Interface PCI Addr | ${nodes['${dut}']}
193| | ... | ${${dut}_if2_vf0}
194| | ${dut_eth_vf_if1}= | VPP Create AVF Interface | ${nodes['${dut}']}
195| | ... | ${if1_pci} | ${rxq_count_int}
196| | ${dut_eth_vf_if1_mac}= | Get Interface MAC | ${nodes['${dut}']}
197| | ... | ${dut_eth_vf_if1}
198| | ${dut_eth_vf_if2}= | VPP Create AVF Interface | ${nodes['${dut}']}
199| | ... | ${if2_pci} | ${rxq_count_int}
200| | ${dut_eth_vf_if2_mac}= | Get Interface MAC | ${nodes['${dut}']}
201| | ... | ${dut_eth_vf_if2}
202| | Set Test Variable | ${${dut_str}_if1} | ${dut_eth_vf_if1}
203| | Set Test Variable | ${${dut_str}_if2} | ${dut_eth_vf_if2}
204| | Set Test Variable | ${${dut_str}_if1_mac} | ${dut_eth_vf_if1_mac}
205| | Set Test Variable | ${${dut_str}_if2_mac} | ${dut_eth_vf_if2_mac}
206
207| Initialize layer bonding on node
208| | [Documentation]
209| | ... | Bonded interface and variables to be created on across east and
210| | ... | west DUT's node interfaces.
211| | ...
212| | ... | *Arguments:*
213| | ... | - dut - DUT node. Type: string
214| | ... | - bond_mode - Link bonding mode. Type: string
215| | ... | - lb_mode - Load balance mode. Type: string
216| | ... | - count - Number of bond interface variables. Type: integer
217| | ...
218| | ... | *Example:*
219| | ...
220| | ... | \| Initialize layer bonding on node \| DUT1 \| xor \| l34 \| 1 \|
221| | ...
222| | [Arguments] | ${dut} | ${bond_mode}=xor | ${lb_mode}=l34 | ${count}=${1}
223| | ...
224| | ${dut_str}= | Convert To Lowercase | ${dut}
225| | ${if_index}= | VPP Create Bond Interface
226| | ... | ${nodes['${dut}']} | ${bond_mode} | load_balance=${lb_mode}
227| | ... | mac=00:00:00:01:01:01
228| | Set Interface State | ${nodes['${dut}']} | ${if_index} | up
229| | VPP Enslave Physical Interface
230| | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_1_1} | ${if_index}
231| | VPP Enslave Physical Interface
232| | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_1_2} | ${if_index}
233| | :FOR | ${id} | IN RANGE | 1 | ${count} + 1
234| | | Set Test Variable | ${${dut_str}_bond_${id}_1} | ${if_index}
235| | | Set Test Variable | ${${dut_str}_bond_${id}_2} | ${if_index}
236
237| Initialize layer bonding
238| | [Documentation]
239| | ... | Bonded interfaces and variables to be created on all DUT's interfaces.
240| | ...
241| | ... | *Arguments:*
242| | ... | - bond_mode - Link bonding mode. Type: string
243| | ... | - lb_mode - Load balance mode. Type: string
244| | ... | - count - Number of bond interface variables. Type: integer
245| | ...
246| | ... | *Example:*
247| | ...
248| | ... | \| Initialize layer bonding \| xor \| l34 \| 1 \|
249| | ...
250| | [Arguments] | ${bond_mode}=xor | ${lb_mode}=l34 | ${count}=${1}
251| | ...
252| | :FOR | ${dut} | IN | @{duts}
253| | | Initialize layer bonding on node
254| | | ... | ${dut} | bond_mode=${bond_mode} | lb_mode=${lb_mode}
255| | | ... | count=${count}
256| | Set Test Variable | ${prev_layer} | bond
257
258| Initialize layer dot1q on node for chain
259| | [Documentation]
260| | ... | Optionally create tag popping subinterface per chain.
261| | ... | Return interface indices for dot1q layer interfaces,
262| | ... | or Nones if subinterfaces are not created.
263| | ...
264| | ... | *Arguments:*
265| | ... | - dut - DUT node. Type: string
266| | ... | - id - Positive index of the chain. Type: integer
267| | ... | - vlan_per_chain - Whether to create vlan subinterface for each chain.
268| | ... |     Type: boolean
269| | ...
270| | ... | *Example:*
271| | ...
272| | ... | \| Initialize layer dot1q on node for chain \| DUT1 \| 1 \| True \|
273| | ...
274| | [Arguments] | ${dut} | ${id} | ${vlan_per_chain}=${True}
275| | ...
276| | ${dut_str}= | Convert To Lowercase | ${dut}
277| | Return From Keyword If | ${id} != ${1} and not ${vlan_per_chain}
278| | ... | ${NONE} | ${NONE}
279| | # TODO: Is it worth creating Get Variable Value If Not None keyword?
280| | ${default}= | Evaluate | ${100} + ${id} - ${1}
281| | ${if1_vlan}= | Get Variable Value | \${${dut_str}_vlan1}
282| | ${if1_vlan}= | Set Variable If | '${if1_vlan}' != '${NONE}'
283| | ... | ${if1_vlan} | ${default}
284| | ${default}= | Evaluate | ${200} + ${id} - ${1}
285| | ${if2_vlan}= | Get Variable Value | \${${dut_str}_vlan2}
286| | ${if2_vlan}= | Set Variable If | '${if2_vlan}' != '${NONE}'
287| | ... | ${if2_vlan} | ${default}
288| | ${if1_name} | ${if1_index}= | Create Vlan Subinterface
289| | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_${id}_1}
290| | ... | ${if1_vlan}
291| | ${if2_name} | ${if2_index}= | Create Vlan Subinterface
292| | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_${id}_2}
293| | ... | ${if2_vlan}
294| | Set Interface State | ${nodes['${dut}']} | ${if1_index} | up
295| | Set Interface State | ${nodes['${dut}']} | ${if2_index} | up
296| | Configure L2 tag rewrite method on interfaces
297| | ... | ${nodes['${dut}']} | ${if1_index} | TAG_REWRITE_METHOD=pop-1
298| | Configure L2 tag rewrite method on interfaces
299| | ... | ${nodes['${dut}']} | ${if2_index} | TAG_REWRITE_METHOD=pop-1
300| | Return From Keyword | ${if1_index} | ${if2_index}
301
302| Initialize layer dot1q on node
303| | [Documentation]
304| | ... | Dot1q interfaces and variables to be created on all DUT's node
305| | ... | interfaces.
306| | ...
307| | ... | TODO: Unify names for number of chains/pipelines/instances/interfaces.
308| | ... | Chose names and descriptions that makes sense for both
309| | ... | nf_density and older tests.
310| | ... | Note that with vlan_per_chain=False it is not a number of interfaces.
311| | ... | At least not number of real interfaces, just number of aliases.
312| | ... | This TODO applies also to all keywords with nf_chains argument.
313| | ...
314| | ... | *Arguments:*
315| | ... | - dut - DUT node. Type: string
316| | ... | - count - Number of chains. Type: integer
317| | ... | - vlan_per_chain - Whether to create vlan subinterface for each chain.
318| | ... |     Type: boolean
319| | ... | - start - Id of first chain, allows adding chains during test.
320| | ... |     Type: integer
321| | ...
322| | ... | *Example:*
323| | ...
324| | ... | \| Initialize layer dot1q on node \| DUT1 \| 3 \| True \| 2 \|
325| | ...
326| | [Arguments] | ${dut} | ${count}=${1} | ${vlan_per_chain}=${True}
327| | ... | ${start}=${1}
328| | ...
329| | ${dut_str}= | Convert To Lowercase | ${dut}
330| | :FOR | ${id} | IN RANGE | ${start} | ${count} + 1
331| | | ${if1_index} | ${if2_index}= | Initialize layer dot1q on node for chain
332| | | ... | dut=${dut} | id=${id} | vlan_per_chain=${vlan_per_chain}
333| | | # First id results in non-None indices, after that _1_ are defined.
334| | | ${if1_index}= | Set Variable If | '${if1_index}' == '${NONE}'
335| | | ... | ${${dut_str}_dot1q_1_1} | ${if1_index}
336| | | ${if2_index}= | Set Variable If | '${if2_index}' == '${NONE}'
337| | | ... | ${${dut_str}_dot1q_1_2} | ${if2_index}
338| | | Set Test Variable | ${${dut_str}_dot1q_${id}_1} | ${if1_index}
339| | | Set Test Variable | ${${dut_str}_dot1q_${id}_2} | ${if2_index}
340
341| Initialize layer dot1q
342| | [Documentation]
343| | ... | Dot1q interfaces and variables to be created on all DUT's interfaces.
344| | ...
345| | ... | *Arguments:*
346| | ... | - count - Number of chains. Type: integer
347| | ... | - vlan_per_chain - Whether to create vlan subinterface for each chain.
348| | ... |     Type: boolean
349| | ... | - start - Id of first chain, allows adding chains during test.
350| | ... |     Type: integer
351| | ...
352| | ... | \| Initialize layer dot1q \| 3 \| True \| 2 \|
353| | ...
354| | [Arguments] | ${count}=${1} | ${vlan_per_chain}=${True} | ${start}=${1}
355| | ...
356| | :FOR | ${dut} | IN | @{duts}
357| | | Initialize layer dot1q on node | ${dut} | count=${count}
358| | | ... | vlan_per_chain=${vlan_per_chain} | start=${start}
359| | Set Test Variable | ${prev_layer} | dot1q
360
361| Initialize layer ip4vxlan on node
362| | [Documentation]
363| | ... | Setup VXLANoIPv4 between TG and DUTs and DUT to DUT by connecting
364| | ... | physical and vxlan interfaces on each DUT. All interfaces are brought
365| | ... | up. IPv4 addresses with prefix /24 are configured on interfaces
366| | ... | towards TG. VXLAN sub-interfaces has same IPv4 address as interfaces.
367| | ...
368| | ... | *Arguments:*
369| | ... | - dut - DUT node. Type: string
370| | ... | - count - Number of vxlan interfaces. Type: integer
371| | ... | - start - Id of first chain, allows adding chains during test.
372| | ... |     Type: integer
373| | ...
374| | ... | *Example:*
375| | ...
376| | ... | \| Initialize layer ip4vxlan on node \| DUT1 \| 3 \| 2 \|
377| | ...
378| | [Arguments] | ${dut} | ${count}=${1} | ${start}=${1}
379| | ...
380| | ${dut_str}= | Convert To Lowercase | ${dut}
381| | Run Keyword If | "${start}" == "1" | VPP Interface Set IP Address
382| | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_1_1}
383| | ... | 172.16.0.1 | 24
384| | Run Keyword If | "${start}" == "1" | VPP Interface Set IP Address
385| | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_1_2}
386| | ... | 172.26.0.1 | 24
387| | :FOR | ${id} | IN RANGE | ${start} | ${count} + 1
388| | | ${subnet}= | Evaluate | ${id} - 1
389| | | ${vni}= | Evaluate | ${id} - 1
390| | | ${ip4vxlan_1}= | Create VXLAN interface
391| | | ... | ${nodes['${dut}']} | ${vni} | 172.16.0.1 | 172.17.${subnet}.2
392| | | ${ip4vxlan_2}= | Create VXLAN interface
393| | | ... | ${nodes['${dut}']} | ${vni} | 172.26.0.1 | 172.27.${subnet}.2
394| | | ${prev_mac}= | Set Variable If | '${dut}' == 'DUT1'
395| | | ... | ${tg_if1_mac} | ${dut1_if2_mac}
396| | | ${next_mac}= | Set Variable If | '${dut}' == 'DUT1' and ${duts_count} == 2
397| | | ... | ${dut2_if1_mac} | ${tg_if2_mac}
398| | | VPP Add IP Neighbor
399| | | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_${id}_1}
400| | | ... | 172.16.${subnet}.2 | ${prev_mac}
401| | | VPP Add IP Neighbor
402| | | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_${id}_2}
403| | | ... | 172.26.${subnet}.2 | ${next_mac}
404| | | VPP Route Add
405| | | ... | ${nodes['${dut}']} | 172.17.${subnet}.0 | 24
406| | | ... | gateway=172.16.${subnet}.2
407| | | ... | interface=${${dut_str}_${prev_layer}_${id}_1}
408| | | VPP Route Add
409| | | ... | ${nodes['${dut}']} | 172.27.${subnet}.0 | 24
410| | | ... | gateway=172.26.${subnet}.2
411| | | ... | interface=${${dut_str}_${prev_layer}_${id}_2}
412| | | Set VXLAN Bypass
413| | | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_${id}_1}
414| | | Set VXLAN Bypass
415| | | ... | ${nodes['${dut}']} | ${${dut_str}_${prev_layer}_${id}_2}
416| | | Set Test Variable
417| | | ... | ${${dut_str}_ip4vxlan_${id}_1} | ${ip4vxlan_1}
418| | | Set Test Variable
419| | | ... | ${${dut_str}_ip4vxlan_${id}_2} | ${ip4vxlan_2}
420
421| Initialize layer ip4vxlan
422| | [Documentation]
423| | ... | VXLAN interfaces and variables to be created on all DUT's interfaces.
424| | ...
425| | ... | *Arguments:*
426| | ... | - count - Number of vxlan interfaces. Type: integer
427| | ... | - start - Id of first chain, allows adding chains during test.
428| | ... |     Type: integer
429| | ...
430| | ... | \| Initialize layer ip4vxlan \| 3 \| 2 \|
431| | ...
432| | [Arguments] | ${count}=${1} | ${start}=${1}
433| | ...
434| | :FOR | ${dut} | IN | @{duts}
435| | | Initialize layer ip4vxlan on node | ${dut} | count=${count}
436| | ... | start=${start}
437| | Set Test Variable | ${prev_layer} | ip4vxlan
438
439| Configure vhost interfaces
440| | [Documentation]
441| | ... | Create two Vhost-User interfaces on defined VPP node.
442| | ...
443| | ... | *Arguments:*
444| | ... | - ${dut_node} - DUT node. Type: dictionary
445| | ... | - ${sock1} - Socket path for first Vhost-User interface. Type: string
446| | ... | - ${sock2} - Socket path for second Vhost-User interface. Type: string
447| | ... | - ${vhost_if1} - Name of the first Vhost-User interface (Optional).
448| | ... | Type: string
449| | ... | - ${vhost_if2} - Name of the second Vhost-User interface (Optional).
450| | ... | Type: string
451| | ...
452| | ... | _NOTE:_ This KW sets following test case variable:
453| | ... | - ${${vhost_if1}} - First Vhost-User interface.
454| | ... | - ${${vhost_if2}} - Second Vhost-User interface.
455| | ...
456| | ... | *Example:*
457| | ...
458| | ... | \| Configure vhost interfaces \
459| | ... | \| ${nodes['DUT1']} \| /tmp/sock1 \| /tmp/sock2 \|
460| | ... | \| Configure vhost interfaces \
461| | ... | \| ${nodes['DUT2']} \| /tmp/sock1 \| /tmp/sock2 \| dut2_vhost_if1 \
462| | ... | \| dut2_vhost_if2 \|
463| | ...
464| | [Arguments] | ${dut_node} | ${sock1} | ${sock2} | ${vhost_if1}=vhost_if1
465| | ... | ${vhost_if2}=vhost_if2
466| | ...
467| | ${vhost_1}= | Vpp Create Vhost User Interface | ${dut_node} | ${sock1}
468| | ${vhost_2}= | Vpp Create Vhost User Interface | ${dut_node} | ${sock2}
469| | ${vhost_1_key}= | Get Interface By SW Index | ${dut_node} | ${vhost_1}
470| | ${vhost_2_key}= | Get Interface By SW Index | ${dut_node} | ${vhost_2}
471| | ${vhost_1_mac}= | Get Interface MAC | ${dut_node} | ${vhost_1_key}
472| | ${vhost_2_mac}= | Get Interface MAC | ${dut_node} | ${vhost_2_key}
473| | Set Interface State | ${dut_node} | ${vhost_1} | up
474| | Set Interface State | ${dut_node} | ${vhost_2} | up
475| | Set Test Variable | ${${vhost_if1}} | ${vhost_1}
476| | Set Test Variable | ${${vhost_if2}} | ${vhost_2}
477| | Set Test Variable | ${${vhost_if1}_mac} | ${vhost_1_mac}
478| | Set Test Variable | ${${vhost_if2}_mac} | ${vhost_2_mac}
479