+ :type bd_id: int or str
+ :type shg: int or str
+ :type port_type: int or str
+ """
+
+ sw_if_index = Topology.get_interface_sw_index(node, interface)
+
+ cmd = 'sw_interface_set_l2_bridge'
+ err_msg = 'Failed to add interface {ifc} to L2 bridge domain on host ' \
+ '{host}'.format(ifc=interface, host=node['host'])
+ args = dict(rx_sw_if_index=sw_if_index,
+ bd_id=int(bd_id),
+ shg=int(shg),
+ port_type=int(port_type),
+ enable=1)
+ with PapiExecutor(node) as papi_exec:
+ papi_exec.add(cmd, **args).get_replies(err_msg).\
+ verify_reply(err_msg=err_msg)
+
+ @staticmethod
+ def vpp_add_l2_bridge_domain(node, bd_id, port_1, port_2, learn=True):
+ """Add L2 bridge domain with 2 interfaces to the VPP node.
+
+ :param node: Node to add L2BD on.
+ :param bd_id: Bridge domain ID.
+ :param port_1: First interface name added to L2BD.
+ :param port_2: Second interface name added to L2BD.
+ :param learn: Enable/disable MAC learn.
+ :type node: dict
+ :type bd_id: int
+ :type port_1: str
+ :type port_2: str
+ :type learn: bool
+ """
+
+ sw_if_index1 = Topology.get_interface_sw_index(node, port_1)
+ sw_if_index2 = Topology.get_interface_sw_index(node, port_2)
+ learn_int = 1 if learn else 0
+
+ cmd1 = 'bridge_domain_add_del'
+ args1 = dict(bd_id=int(bd_id),
+ flood=1,
+ uu_flood=1,
+ forward=1,
+ learn=learn_int,
+ arp_term=0,
+ is_add=1)
+
+ cmd2 = 'sw_interface_set_l2_bridge'
+ args2 = dict(rx_sw_if_index=sw_if_index1,
+ bd_id=int(bd_id),
+ shg=0,
+ port_type=0,
+ enable=1)
+
+ args3 = dict(rx_sw_if_index=sw_if_index2,
+ bd_id=int(bd_id),
+ shg=0,
+ port_type=0,
+ enable=1)
+
+ err_msg = 'Failed to add L2 bridge domain with 2 interfaces on host' \
+ ' {host}'.format(host=node['host'])
+
+ with PapiExecutor(node) as papi_exec:
+ papi_exec.add(cmd1, **args1).add(cmd2, **args2).add(cmd2, **args3).\
+ get_replies(err_msg).verify_replies(err_msg=err_msg)
+
+ @staticmethod
+ def vpp_setup_bidirectional_cross_connect(node, interface1, interface2):
+ """Create bidirectional cross-connect between 2 interfaces on vpp node.
+
+ :param node: Node to add bidirectional cross-connect.
+ :param interface1: First interface name or sw_if_index.
+ :param interface2: Second interface name or sw_if_index.
+ :type node: dict
+ :type interface1: str or int
+ :type interface2: str or int
+ """
+
+ if isinstance(interface1, basestring):
+ sw_iface1 = Topology().get_interface_sw_index(node, interface1)
+ else:
+ sw_iface1 = interface1
+
+ if isinstance(interface2, basestring):
+ sw_iface2 = Topology().get_interface_sw_index(node, interface2)
+ else:
+ sw_iface2 = interface2
+
+ cmd = 'sw_interface_set_l2_xconnect'
+ args1 = dict(rx_sw_if_index=sw_iface1,
+ tx_sw_if_index=sw_iface2,
+ enable=1)
+ args2 = dict(rx_sw_if_index=sw_iface2,
+ tx_sw_if_index=sw_iface1,
+ enable=1)
+
+ err_msg = 'Failed to add L2 cross-connect between two interfaces on' \
+ ' host {host}'.format(host=node['host'])
+
+ with PapiExecutor(node) as papi_exec:
+ papi_exec.add(cmd, **args1).add(cmd, **args2).get_replies(err_msg).\
+ verify_replies(err_msg=err_msg)
+
+ @staticmethod
+ def vpp_setup_bidirectional_l2_patch(node, interface1, interface2):
+ """Create bidirectional l2 patch between 2 interfaces on vpp node.
+
+ :param node: Node to add bidirectional l2 patch.
+ :param interface1: First interface name or sw_if_index.
+ :param interface2: Second interface name or sw_if_index.
+ :type node: dict
+ :type interface1: str or int
+ :type interface2: str or int
+ """
+
+ if isinstance(interface1, basestring):
+ sw_iface1 = Topology().get_interface_sw_index(node, interface1)
+ else:
+ sw_iface1 = interface1
+
+ if isinstance(interface2, basestring):
+ sw_iface2 = Topology().get_interface_sw_index(node, interface2)
+ else:
+ sw_iface2 = interface2
+
+ cmd = 'l2_patch_add_del'
+ args1 = dict(rx_sw_if_index=sw_iface1,
+ tx_sw_if_index=sw_iface2,
+ is_add=1)
+ args2 = dict(rx_sw_if_index=sw_iface2,
+ tx_sw_if_index=sw_iface1,
+ is_add=1)
+
+ err_msg = 'Failed to add L2 patch between two interfaces on' \
+ ' host {host}'.format(host=node['host'])
+
+ with PapiExecutor(node) as papi_exec:
+ papi_exec.add(cmd, **args1).add(cmd, **args2).get_replies(err_msg).\
+ verify_replies(err_msg=err_msg)
+
+ @staticmethod
+ def linux_add_bridge(node, br_name, if_1, if_2, set_up=True):
+ """Bridge two interfaces on linux node.
+
+ :param node: Node to add bridge on.
+ :param br_name: Bridge name.
+ :param if_1: First interface to be added to the bridge.
+ :param if_2: Second interface to be added to the bridge.
+ :param set_up: Change bridge interface state to up after create bridge.
+ Optional. Default: True.
+ :type node: dict
+ :type br_name: str
+ :type if_1: str
+ :type if_2: str
+ :type set_up: bool
+ """
+
+ cmd = 'brctl addbr {0}'.format(br_name)
+ exec_cmd_no_error(node, cmd, sudo=True)
+ cmd = 'brctl addif {0} {1}'.format(br_name, if_1)
+ exec_cmd_no_error(node, cmd, sudo=True)
+ cmd = 'brctl addif {0} {1}'.format(br_name, if_2)
+ exec_cmd_no_error(node, cmd, sudo=True)
+ if set_up:
+ cmd = 'ip link set dev {0} up'.format(br_name)
+ exec_cmd_no_error(node, cmd, sudo=True)
+
+ @staticmethod
+ def linux_del_bridge(node, br_name, set_down=True):
+ """Delete bridge from linux node.
+
+ ..note:: The network interface corresponding to the bridge must be
+ down before it can be deleted!
+
+ :param node: Node to delete bridge from.
+ :param br_name: Bridge name.
+ :param set_down: Change bridge interface state to down before delbr
+ command. Optional. Default: True.
+ :type node: dict
+ :type br_name: str
+ :type set_down: bool