6 from scapy.contrib.lacp import LACP, SlowProtocol, MarkerProtocol
7 from scapy.layers.l2 import Ether
9 from framework import VppTestCase, VppTestRunner
10 from vpp_memif import remove_all_memif_vpp_config, VppSocketFilename, VppMemif
11 from vpp_bond_interface import VppBondInterface
12 from vpp_papi import VppEnum, MACAddress
14 bond_mac = "02:02:02:02:02:02"
15 lacp_dst_mac = "01:80:c2:00:00:02"
16 LACP_COLLECTION_AND_DISTRIBUTION_STATE = 63
19 class TestMarker(VppTestCase):
20 """LACP Marker Protocol Test Case"""
26 cls.pkts_per_burst = 257 # Number of packets per burst
27 # create 3 pg interfaces
28 cls.create_pg_interfaces(range(1))
31 cls.pg_if_packet_sizes = [64, 512, 1518] # , 9018]
33 # setup all interfaces
34 for i in cls.pg_interfaces:
38 def tearDownClass(cls):
39 super().tearDownClass()
47 def show_commands_at_teardown(self):
48 self.logger.info(self.vapi.ppcli("show interface"))
50 def test_marker_request(self):
51 """Marker Request test"""
56 # memif1 -----|B| |B|---- memif11
63 socket1 = VppSocketFilename(
64 self, socket_id=1, socket_filename="%s/memif.sock1" % self.tempdir
66 socket1.add_vpp_config()
68 socket11 = VppSocketFilename(
69 self, socket_id=2, socket_filename="%s/memif.sock1" % self.tempdir
71 socket11.add_vpp_config()
75 role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
76 mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
79 memif1.add_vpp_config()
84 role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
85 mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
88 memif11.add_vpp_config()
91 bond0 = VppBondInterface(
93 mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP,
98 bond0.add_vpp_config()
101 bond1 = VppBondInterface(
102 self, mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP
104 bond1.add_vpp_config()
107 bond0.add_member_vpp_bond_interface(sw_if_index=memif1.sw_if_index)
108 bond1.add_member_vpp_bond_interface(sw_if_index=memif11.sw_if_index)
110 # wait for memif protocol exchange and hardware carrier to come up
111 self.assertEqual(memif1.wait_for_link_up(10), True)
112 self.assertEqual(memif11.wait_for_link_up(10), True)
114 # verify memif1 in bond0
115 intfs = self.vapi.sw_member_interface_dump(sw_if_index=bond0.sw_if_index)
117 self.assertEqual(intf.sw_if_index, memif1.sw_if_index)
119 # verify memif11 in bond1
120 intfs = self.vapi.sw_member_interface_dump(sw_if_index=bond1.sw_if_index)
122 self.assertEqual(intf.sw_if_index, memif11.sw_if_index)
124 self.vapi.ppcli("trace add memif-input 100")
126 # create marker request
128 Ether(src=bond_mac, dst=lacp_dst_mac)
133 requester_system=bond_mac,
134 requester_transaction_id=1,
138 bond1.add_member_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index)
139 self.pg0.add_stream(marker)
140 self.pg_enable_capture(self.pg_interfaces)
143 show_trace = self.vapi.ppcli("show trace max 100")
144 self.assertIn("Marker Information TLV:", show_trace)
146 bond0.remove_vpp_config()
147 bond1.remove_vpp_config()
150 class TestLACP(VppTestCase):
158 def tearDownClass(cls):
159 super().tearDownClass()
167 def show_commands_at_teardown(self):
168 self.logger.info(self.vapi.ppcli("show interface"))
170 def wait_for_lacp_connect(self, timeout, step=1):
172 intfs = self.vapi.sw_interface_lacp_dump()
175 if (intf.actor_state != LACP_COLLECTION_AND_DISTRIBUTION_STATE) or (
176 intf.partner_state != LACP_COLLECTION_AND_DISTRIBUTION_STATE
186 def wait_for_member_detach(self, bond, timeout, count, step=1):
188 intfs = self.vapi.sw_bond_interface_dump(sw_if_index=bond.sw_if_index)
190 if (intf.members == count) and (intf.active_members == count):
198 def test_lacp_connect(self):
199 """LACP protocol connect test"""
204 # memif1 -----|B| |B|---- memif11
208 # memif2 -----|0| |1|---- memif12
211 socket1 = VppSocketFilename(
212 self, socket_id=1, socket_filename="%s/memif.sock1" % self.tempdir
214 socket1.add_vpp_config()
216 socket11 = VppSocketFilename(
217 self, socket_id=2, socket_filename="%s/memif.sock1" % self.tempdir
219 socket11.add_vpp_config()
221 socket2 = VppSocketFilename(
222 self, socket_id=3, socket_filename="%s/memif.sock2" % self.tempdir
224 socket2.add_vpp_config()
226 socket22 = VppSocketFilename(
227 self, socket_id=4, socket_filename="%s/memif.sock2" % self.tempdir
229 socket22.add_vpp_config()
233 role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
234 mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
237 memif1.add_vpp_config()
242 role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
243 mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
246 memif11.add_vpp_config()
251 role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
252 mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
255 memif2.add_vpp_config()
260 role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
261 mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
264 memif12.add_vpp_config()
267 self.logger.info(self.vapi.ppcli("debug lacp on"))
268 bond0 = VppBondInterface(
270 mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP,
272 mac_address=bond_mac,
275 bond0.add_vpp_config()
278 bond1 = VppBondInterface(
279 self, mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP
281 bond1.add_vpp_config()
284 # add member memif1 and memif2 to bond0
285 bond0.add_member_vpp_bond_interface(sw_if_index=memif1.sw_if_index)
286 bond0.add_member_vpp_bond_interface(sw_if_index=memif2.sw_if_index)
288 # add member memif11 and memif12 to bond1
289 bond1.add_member_vpp_bond_interface(sw_if_index=memif11.sw_if_index)
290 bond1.add_member_vpp_bond_interface(sw_if_index=memif12.sw_if_index)
292 # wait for memif protocol exchange and hardware carrier to come up
293 self.assertEqual(memif1.wait_for_link_up(10), True)
294 self.assertEqual(memif2.wait_for_link_up(10), True)
295 self.assertEqual(memif11.wait_for_link_up(10), True)
296 self.assertEqual(memif12.wait_for_link_up(10), True)
298 # verify memif1 and memif2 in bond0
299 intfs = self.vapi.sw_member_interface_dump(sw_if_index=bond0.sw_if_index)
301 self.assertIn(intf.sw_if_index, (memif1.sw_if_index, memif2.sw_if_index))
303 # verify memif11 and memif12 in bond1
304 intfs = self.vapi.sw_member_interface_dump(sw_if_index=bond1.sw_if_index)
306 self.assertIn(intf.sw_if_index, (memif11.sw_if_index, memif12.sw_if_index))
307 self.assertEqual(intf.is_long_timeout, 0)
308 self.assertEqual(intf.is_passive, 0)
310 # Let LACP create the bundle
311 self.wait_for_lacp_connect(30)
313 intfs = self.vapi.sw_interface_lacp_dump()
315 self.assertEqual(intf.actor_state, LACP_COLLECTION_AND_DISTRIBUTION_STATE)
316 self.assertEqual(intf.partner_state, LACP_COLLECTION_AND_DISTRIBUTION_STATE)
318 intfs = self.vapi.sw_bond_interface_dump(sw_if_index=0xFFFFFFFF)
320 self.assertEqual(intf.members, 2)
321 self.assertEqual(intf.active_members, 2)
322 self.assertEqual(intf.mode, VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP)
324 self.logger.info(self.vapi.ppcli("show lacp"))
325 self.logger.info(self.vapi.ppcli("show lacp details"))
327 # detach member memif1
328 bond0.detach_vpp_bond_interface(sw_if_index=memif1.sw_if_index)
330 self.wait_for_member_detach(bond0, timeout=10, count=1)
331 intfs = self.vapi.sw_bond_interface_dump(sw_if_index=bond0.sw_if_index)
333 self.assertEqual(intf.members, 1)
334 self.assertEqual(intf.active_members, 1)
335 self.assertEqual(intf.mode, VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP)
337 # detach member memif2
338 bond0.detach_vpp_bond_interface(sw_if_index=memif2.sw_if_index)
339 self.wait_for_member_detach(bond0, timeout=10, count=0)
341 intfs = self.vapi.sw_bond_interface_dump(sw_if_index=bond0.sw_if_index)
343 self.assertEqual(intf.members, 0)
344 self.assertEqual(intf.active_members, 0)
346 bond0.remove_vpp_config()
347 bond1.remove_vpp_config()
350 if __name__ == "__main__":
351 unittest.main(testRunner=VppTestRunner)