1 # Copyright (c) 2016 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:
6 # http://www.apache.org/licenses/LICENSE-2.0
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.
14 """L2 Utilities Library."""
16 from robot.api.deco import keyword
17 from resources.libraries.python.topology import Topology
18 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
19 from resources.libraries.python.ssh import exec_cmd_no_error
22 """Utilities for l2 configuration"""
25 def vpp_add_l2fib_entry(node, mac, interface, bd_id):
26 """ Create a static L2FIB entry on a vpp node.
28 :param node: Node to add L2FIB entry on.
29 :param mac: Destination mac address.
30 :param interface: Interface name or sw_if_index.
31 :param bd_id: Bridge domain id.
34 :type interface: str or int
37 if isinstance(interface, basestring):
38 sw_if_index = Topology.get_interface_sw_index(node, interface)
40 sw_if_index = interface
41 VatExecutor.cmd_from_template(node, "add_l2_fib_entry.vat",
43 interface=sw_if_index)
46 def create_l2_bd(node, bd_id, flood=1, uu_flood=1, forward=1, learn=1,
48 """Create a l2 bridge domain on the chosen VPP node
50 Execute "bridge_domain_add_del bd_id {bd_id} flood {flood} uu-flood 1
51 forward {forward} learn {learn} arp-term {arp_term}" VAT command on
54 :param node: node where we wish to crate the l2 bridge domain
55 :param bd_id: bridge domain index number
56 :param flood: enable flooding
57 :param uu_flood: enable uu_flood
58 :param forward: enable forwarding
59 :param learn: enable mac address learning to fib
60 :param arp_term: enable arp_termination
69 VatExecutor.cmd_from_template(node, "l2_bd_create.vat",
70 bd_id=bd_id, flood=flood,
71 uu_flood=uu_flood, forward=forward,
72 learn=learn, arp_term=arp_term)
75 def add_interface_to_l2_bd(node, interface, bd_id, shg=0):
76 """Add a interface to the l2 bridge domain.
78 Get SW IF ID and add it to the bridge domain.
80 :param node: node where we want to execute the command that does this
81 :param interface: interface name
82 :param bd_id: bridge domain index number to add Interface name to
83 :param shg: split horizon group
89 sw_if_index = Topology.get_interface_sw_index(node, interface)
90 L2Util.add_sw_if_index_to_l2_bd(node, sw_if_index, bd_id, shg)
93 def add_sw_if_index_to_l2_bd(node, sw_if_index, bd_id, shg=0):
94 """Add interface with sw_if_index to l2 bridge domain.
96 Execute the "sw_interface_set_l2_bridge sw_if_index {sw_if_index}
97 bd_id {bd_id} shg {shg} enable" VAT command on the given node.
99 :param node: node where we want to execute the command that does this
100 :param sw_if_index: interface index
101 :param bd_id: bridge domain index number to add SW IF ID to
102 :param shg: split horizon group
104 :type sw_if_index: int
109 VatExecutor.cmd_from_template(node, "l2_bd_add_sw_if_index.vat",
110 bd_id=bd_id, sw_if_index=sw_if_index,
114 @keyword('Create dict used in bridge domain template file for node '
115 '"${node}" with links "${link_names}" and bd_id "${bd_id}"')
116 def create_bridge_domain_vat_dict(node, link_names, bd_id):
117 """Create dictionary that can be used in l2 bridge domain template.
119 :param node: node data dictionary
120 :param link_names: list of names of links the bridge domain should be
122 :param bd_id: bridge domain index number
124 :type link_names: list
125 :return: dictionary used to generate l2 bridge domain VAT configuration
127 The resulting dictionary looks like this:
128 'interface1': interface name of first interface
129 'interface2': interface name of second interface
130 'bd_id': bridge domain index
132 bd_dict = Topology().get_interfaces_by_link_names(node, link_names)
133 bd_dict['bd_id'] = bd_id
137 def vpp_add_l2_bridge_domain(node, bd_id, port_1, port_2, learn=True):
138 """Add L2 bridge domain with 2 interfaces to the VPP node.
140 :param node: Node to add L2BD on.
141 :param bd_id: Bridge domain ID.
142 :param port_1: First interface name added to L2BD.
143 :param port_2: Second interface name added to L2BD.
144 :param learn: Enable/disable MAC learn.
151 sw_if_index1 = Topology.get_interface_sw_index(node, port_1)
152 sw_if_index2 = Topology.get_interface_sw_index(node, port_2)
153 VatExecutor.cmd_from_template(node,
154 'l2_bridge_domain.vat',
155 sw_if_id1=sw_if_index1,
156 sw_if_id2=sw_if_index2,
161 def vpp_setup_bidirectional_cross_connect(node, interface1, interface2):
162 """Create bidirectional cross-connect between 2 interfaces on vpp node.
164 :param node: Node to add bidirectional cross-connect
165 :param interface1: first interface name or sw_if_index
166 :param interface2: second interface name or sw_if_index
168 :type interface1: str or int
169 :type interface2: str or int
172 if isinstance(interface1, basestring):
173 sw_iface1 = Topology().get_interface_sw_index(node, interface1)
175 sw_iface1 = interface1
177 if isinstance(interface2, basestring):
178 sw_iface2 = Topology().get_interface_sw_index(node, interface2)
180 sw_iface2 = interface2
182 with VatTerminal(node) as vat:
183 vat.vat_terminal_exec_cmd_from_template('l2_xconnect.vat',
184 interface1=sw_iface1,
185 interface2=sw_iface2)
186 vat.vat_terminal_exec_cmd_from_template('l2_xconnect.vat',
187 interface1=sw_iface2,
188 interface2=sw_iface1)
191 def linux_add_bridge(node, br_name, if_1, if_2):
192 """Bridge two interfaces on linux node.
194 :param node: Node to add bridge on.
195 :param br_name: Bridge name.
196 :param if_1: First interface to be added to the bridge.
197 :param if_2: Second interface to be added to the bridge.
203 cmd = 'brctl addbr {0}'.format(br_name)
204 exec_cmd_no_error(node, cmd, sudo=True)
205 cmd = 'brctl addif {0} {1}'.format(br_name, if_1)
206 exec_cmd_no_error(node, cmd, sudo=True)
207 cmd = 'brctl addif {0} {1}'.format(br_name, if_2)
208 exec_cmd_no_error(node, cmd, sudo=True)
211 def linux_del_bridge(node, br_name):
212 """Delete bridge from linux node.
214 :param node: Node to delete bridge from.
215 :param br_name: Bridge name.
216 .. note:: The network interface corresponding to the bridge must be
217 down before it can be deleted!
219 cmd = 'brctl delbr {0}'.format(br_name)
220 exec_cmd_no_error(node, cmd, sudo=True)