Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | import time |
| 4 | import unittest |
| 5 | |
| 6 | from scapy.contrib.lacp import LACP, SlowProtocol, MarkerProtocol |
| 7 | from scapy.layers.l2 import Ether |
| 8 | |
| 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 |
| 13 | |
| 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 |
| 17 | |
| 18 | |
| 19 | class TestMarker(VppTestCase): |
| 20 | """LACP Marker Protocol Test Case |
| 21 | |
| 22 | """ |
| 23 | |
| 24 | @classmethod |
| 25 | def setUpClass(cls): |
| 26 | super().setUpClass() |
| 27 | # Test variables |
| 28 | cls.pkts_per_burst = 257 # Number of packets per burst |
| 29 | # create 3 pg interfaces |
| 30 | cls.create_pg_interfaces(range(1)) |
| 31 | |
| 32 | # packet sizes |
| 33 | cls.pg_if_packet_sizes = [64, 512, 1518] # , 9018] |
| 34 | |
| 35 | # setup all interfaces |
| 36 | for i in cls.pg_interfaces: |
| 37 | i.admin_up() |
| 38 | |
| 39 | @classmethod |
| 40 | def tearDownClass(cls): |
| 41 | super().tearDownClass() |
| 42 | |
| 43 | def setUp(self): |
| 44 | super().setUp() |
| 45 | |
| 46 | def tearDown(self): |
| 47 | super().tearDown() |
| 48 | |
| 49 | def show_commands_at_teardown(self): |
| 50 | self.logger.info(self.vapi.ppcli("show interface")) |
| 51 | |
| 52 | def test_marker_request(self): |
| 53 | """ Marker Request test """ |
| 54 | |
| 55 | # topology |
| 56 | # |
| 57 | # +-+ +-+ |
| 58 | # memif1 -----|B| |B|---- memif11 |
| 59 | # |o| |o| |
| 60 | # |n|------|n| |
| 61 | # |d| |d| |
| 62 | # pg0 -----|0| |1| |
| 63 | # +-+ +-+ |
| 64 | |
| 65 | socket1 = VppSocketFilename( |
| 66 | self, |
| 67 | socket_id=1, |
| 68 | socket_filename="%s/memif.sock1" % self.tempdir) |
| 69 | socket1.add_vpp_config() |
| 70 | |
| 71 | socket11 = VppSocketFilename( |
| 72 | self, |
| 73 | socket_id=2, |
| 74 | socket_filename="%s/memif.sock1" % self.tempdir) |
| 75 | socket11.add_vpp_config() |
| 76 | |
| 77 | memif1 = VppMemif( |
| 78 | self, |
| 79 | role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER, |
| 80 | mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET, |
| 81 | socket_id=1) |
| 82 | memif1.add_vpp_config() |
| 83 | memif1.admin_up() |
| 84 | |
| 85 | memif11 = VppMemif( |
| 86 | self, |
| 87 | role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE, |
| 88 | mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET, |
| 89 | socket_id=2) |
| 90 | memif11.add_vpp_config() |
| 91 | memif11.admin_up() |
| 92 | |
| 93 | bond0 = VppBondInterface( |
| 94 | self, |
| 95 | mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP, |
| 96 | use_custom_mac=1, |
| 97 | mac_address=bond_mac) |
| 98 | |
| 99 | bond0.add_vpp_config() |
| 100 | bond0.admin_up() |
| 101 | |
| 102 | bond1 = VppBondInterface( |
| 103 | self, |
| 104 | mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP) |
| 105 | bond1.add_vpp_config() |
| 106 | bond1.admin_up() |
| 107 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 108 | bond0.add_member_vpp_bond_interface(sw_if_index=memif1.sw_if_index) |
| 109 | bond1.add_member_vpp_bond_interface(sw_if_index=memif11.sw_if_index) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 110 | |
| 111 | # wait for memif protocol exchange and hardware carrier to come up |
| 112 | self.assertEqual(memif1.wait_for_link_up(10), True) |
| 113 | self.assertEqual(memif11.wait_for_link_up(10), True) |
| 114 | |
| 115 | # verify memif1 in bond0 |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 116 | intfs = self.vapi.sw_member_interface_dump( |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 117 | sw_if_index=bond0.sw_if_index) |
| 118 | for intf in intfs: |
| 119 | self.assertEqual(intf.sw_if_index, memif1.sw_if_index) |
| 120 | |
| 121 | # verify memif11 in bond1 |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 122 | intfs = self.vapi.sw_member_interface_dump( |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 123 | sw_if_index=bond1.sw_if_index) |
| 124 | for intf in intfs: |
| 125 | self.assertEqual(intf.sw_if_index, memif11.sw_if_index) |
| 126 | |
| 127 | self.vapi.ppcli("trace add memif-input 100") |
| 128 | |
| 129 | # create marker request |
| 130 | marker = (Ether(src=bond_mac, dst=lacp_dst_mac) / |
| 131 | SlowProtocol() / |
| 132 | MarkerProtocol(marker_type=1, |
| 133 | requester_port=1, |
| 134 | requester_system=bond_mac, |
| 135 | requester_transaction_id=1)) |
| 136 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 137 | bond1.add_member_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 138 | self.pg0.add_stream(marker) |
| 139 | self.pg_enable_capture(self.pg_interfaces) |
| 140 | self.pg_start() |
| 141 | |
| 142 | show_trace = self.vapi.ppcli("show trace max 100") |
| 143 | self.assertIn("Marker Information TLV:", show_trace) |
| 144 | |
| 145 | bond0.remove_vpp_config() |
| 146 | bond1.remove_vpp_config() |
| 147 | |
| 148 | |
| 149 | class TestLACP(VppTestCase): |
| 150 | """LACP Test Case |
| 151 | |
| 152 | """ |
| 153 | |
| 154 | @classmethod |
| 155 | def setUpClass(cls): |
| 156 | super().setUpClass() |
| 157 | |
| 158 | @classmethod |
| 159 | def tearDownClass(cls): |
| 160 | super().tearDownClass() |
| 161 | |
| 162 | def setUp(self): |
| 163 | super().setUp() |
| 164 | |
| 165 | def tearDown(self): |
| 166 | super().tearDown() |
| 167 | |
| 168 | def show_commands_at_teardown(self): |
| 169 | self.logger.info(self.vapi.ppcli("show interface")) |
| 170 | |
| 171 | def wait_for_lacp_connect(self, timeout, step=1): |
| 172 | while 1: |
| 173 | intfs = self.vapi.sw_interface_lacp_dump() |
| 174 | all_good = 1 |
| 175 | for intf in intfs: |
| 176 | if ((intf.actor_state != |
| 177 | LACP_COLLECTION_AND_DISTRIBUTION_STATE) or |
| 178 | (intf.partner_state != |
| 179 | LACP_COLLECTION_AND_DISTRIBUTION_STATE)): |
| 180 | all_good = 0 |
| 181 | if (all_good == 1): |
| 182 | return 1 |
| 183 | self.sleep(step) |
| 184 | timeout -= step |
| 185 | if timeout <= 0: |
| 186 | return 0 |
| 187 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 188 | def wait_for_member_detach(self, bond, timeout, count, step=1): |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 189 | while 1: |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 190 | intfs = self.vapi.sw_bond_interface_dump( |
| 191 | sw_if_index=bond.sw_if_index) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 192 | for intf in intfs: |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 193 | if ((intf.members == count) and |
| 194 | (intf.active_members == count)): |
| 195 | return 1 |
| 196 | else: |
| 197 | self.sleep(1) |
| 198 | timeout -= step |
| 199 | if (timeouut <= 0): |
| 200 | return 0 |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 201 | |
| 202 | def test_lacp_connect(self): |
| 203 | """ LACP protocol connect test """ |
| 204 | |
| 205 | # topology |
| 206 | # |
| 207 | # +-+ +-+ |
| 208 | # memif1 -----|B| |B|---- memif11 |
| 209 | # |o| |o| |
| 210 | # |n|------|n| |
| 211 | # |d| |d| |
| 212 | # memif2 -----|0| |1|---- memif12 |
| 213 | # +-+ +-+ |
| 214 | |
| 215 | socket1 = VppSocketFilename( |
| 216 | self, |
| 217 | socket_id=1, |
| 218 | socket_filename="%s/memif.sock1" % self.tempdir) |
| 219 | socket1.add_vpp_config() |
| 220 | |
| 221 | socket11 = VppSocketFilename( |
| 222 | self, |
| 223 | socket_id=2, |
| 224 | socket_filename="%s/memif.sock1" % self.tempdir) |
| 225 | socket11.add_vpp_config() |
| 226 | |
| 227 | socket2 = VppSocketFilename( |
| 228 | self, |
| 229 | socket_id=3, |
| 230 | socket_filename="%s/memif.sock2" % self.tempdir) |
| 231 | socket2.add_vpp_config() |
| 232 | |
| 233 | socket22 = VppSocketFilename( |
| 234 | self, |
| 235 | socket_id=4, |
| 236 | socket_filename="%s/memif.sock2" % self.tempdir) |
| 237 | socket22.add_vpp_config() |
| 238 | |
| 239 | memif1 = VppMemif( |
| 240 | self, |
| 241 | role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER, |
| 242 | mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET, |
| 243 | socket_id=1) |
| 244 | memif1.add_vpp_config() |
| 245 | memif1.admin_up() |
| 246 | |
| 247 | memif11 = VppMemif( |
| 248 | self, |
| 249 | role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE, |
| 250 | mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET, |
| 251 | socket_id=2) |
| 252 | memif11.add_vpp_config() |
| 253 | memif11.admin_up() |
| 254 | |
| 255 | memif2 = VppMemif( |
| 256 | self, |
| 257 | role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER, |
| 258 | mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET, |
| 259 | socket_id=3) |
| 260 | memif2.add_vpp_config() |
| 261 | memif2.admin_up() |
| 262 | |
| 263 | memif12 = VppMemif( |
| 264 | self, |
| 265 | role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE, |
| 266 | mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET, |
| 267 | socket_id=4) |
| 268 | memif12.add_vpp_config() |
| 269 | memif12.admin_up() |
| 270 | |
| 271 | self.logger.info(self.vapi.ppcli("debug lacp on")) |
| 272 | bond0 = VppBondInterface( |
| 273 | self, |
| 274 | mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP, |
| 275 | use_custom_mac=1, |
| 276 | mac_address=bond_mac) |
| 277 | |
| 278 | bond0.add_vpp_config() |
| 279 | bond0.admin_up() |
| 280 | |
| 281 | bond1 = VppBondInterface( |
| 282 | self, |
| 283 | mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP) |
| 284 | bond1.add_vpp_config() |
| 285 | bond1.admin_up() |
| 286 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 287 | # add member memif1 and memif2 to bond0 |
| 288 | bond0.add_member_vpp_bond_interface(sw_if_index=memif1.sw_if_index) |
| 289 | bond0.add_member_vpp_bond_interface(sw_if_index=memif2.sw_if_index) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 290 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 291 | # add member memif11 and memif12 to bond1 |
| 292 | bond1.add_member_vpp_bond_interface(sw_if_index=memif11.sw_if_index) |
| 293 | bond1.add_member_vpp_bond_interface(sw_if_index=memif12.sw_if_index) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 294 | |
| 295 | # wait for memif protocol exchange and hardware carrier to come up |
| 296 | self.assertEqual(memif1.wait_for_link_up(10), True) |
| 297 | self.assertEqual(memif2.wait_for_link_up(10), True) |
| 298 | self.assertEqual(memif11.wait_for_link_up(10), True) |
| 299 | self.assertEqual(memif12.wait_for_link_up(10), True) |
| 300 | |
| 301 | # verify memif1 and memif2 in bond0 |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 302 | intfs = self.vapi.sw_member_interface_dump( |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 303 | sw_if_index=bond0.sw_if_index) |
| 304 | for intf in intfs: |
| 305 | self.assertIn( |
| 306 | intf.sw_if_index, (memif1.sw_if_index, memif2.sw_if_index)) |
| 307 | |
| 308 | # verify memif11 and memif12 in bond1 |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 309 | intfs = self.vapi.sw_member_interface_dump( |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 310 | sw_if_index=bond1.sw_if_index) |
| 311 | for intf in intfs: |
| 312 | self.assertIn( |
| 313 | intf.sw_if_index, (memif11.sw_if_index, memif12.sw_if_index)) |
| 314 | self.assertEqual(intf.is_long_timeout, 0) |
| 315 | self.assertEqual(intf.is_passive, 0) |
| 316 | |
| 317 | # Let LACP create the bundle |
| 318 | self.wait_for_lacp_connect(30) |
| 319 | |
| 320 | intfs = self.vapi.sw_interface_lacp_dump() |
| 321 | for intf in intfs: |
| 322 | self.assertEqual( |
| 323 | intf.actor_state, LACP_COLLECTION_AND_DISTRIBUTION_STATE) |
| 324 | self.assertEqual( |
| 325 | intf.partner_state, LACP_COLLECTION_AND_DISTRIBUTION_STATE) |
| 326 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 327 | intfs = self.vapi.sw_bond_interface_dump(sw_if_index=0xFFFFFFFF) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 328 | for intf in intfs: |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 329 | self.assertEqual(intf.members, 2) |
| 330 | self.assertEqual(intf.active_members, 2) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 331 | self.assertEqual( |
| 332 | intf.mode, VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP) |
| 333 | |
| 334 | self.logger.info(self.vapi.ppcli("show lacp")) |
| 335 | self.logger.info(self.vapi.ppcli("show lacp details")) |
| 336 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 337 | # detach member memif1 |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 338 | bond0.detach_vpp_bond_interface(sw_if_index=memif1.sw_if_index) |
| 339 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 340 | self.wait_for_member_detach(bond0, timeout=10, count=1) |
| 341 | intfs = self.vapi.sw_bond_interface_dump( |
| 342 | sw_if_index=bond0.sw_if_index) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 343 | for intf in intfs: |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 344 | self.assertEqual(intf.members, 1) |
| 345 | self.assertEqual(intf.active_members, 1) |
| 346 | self.assertEqual( |
| 347 | intf.mode, VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 348 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 349 | # detach member memif2 |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 350 | bond0.detach_vpp_bond_interface(sw_if_index=memif2.sw_if_index) |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 351 | self.wait_for_member_detach(bond0, timeout=10, count=0) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 352 | |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 353 | intfs = self.vapi.sw_bond_interface_dump( |
| 354 | sw_if_index=bond0.sw_if_index) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 355 | for intf in intfs: |
Steven Luong | 4c4223e | 2020-07-15 08:44:54 -0700 | [diff] [blame] | 356 | self.assertEqual(intf.members, 0) |
| 357 | self.assertEqual(intf.active_members, 0) |
Steven Luong | a4611b8 | 2020-05-15 12:21:50 -0700 | [diff] [blame] | 358 | |
| 359 | bond0.remove_vpp_config() |
| 360 | bond1.remove_vpp_config() |
| 361 | |
| 362 | |
| 363 | if __name__ == '__main__': |
| 364 | unittest.main(testRunner=VppTestRunner) |