X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_l2_fib.py;h=9249a2ced235c6b9cff3409fb42c7c8bfbb77e17;hb=4df97165159b3b115b31eb1cad55782ac97e3c7e;hp=3d5d21292e9c047b579a0b5bb6e59b8ef00b6c3a;hpb=da505f608e0919c45089dc80f9e3e16330a6551a;p=vpp.git diff --git a/test/test_l2_fib.py b/test/test_l2_fib.py index 3d5d21292e9..9249a2ced23 100644 --- a/test/test_l2_fib.py +++ b/test/test_l2_fib.py @@ -74,6 +74,10 @@ from util import Host, ppp class TestL2fib(VppTestCase): """ L2 FIB Test Case """ + @classmethod + def bd_ifs(cls, bd_id): + return range((bd_id - 1) * cls.n_ifs_per_bd, bd_id * cls.n_ifs_per_bd) + @classmethod def setUpClass(cls): """ @@ -82,49 +86,52 @@ class TestL2fib(VppTestCase): variables and configure VPP. :var int bd_id: Bridge domain ID. - :var int mac_entries_count: Number of MAC entries for bridge-domain. """ super(TestL2fib, cls).setUpClass() - # Test variables - cls.bd_id = 1 - cls.mac_entries_count = 200 - try: + n_brs = cls.n_brs = range(1, 3) + cls.n_ifs_per_bd = 4 + n_ifs = range(cls.n_ifs_per_bd * len(cls.n_brs)) # Create 4 pg interfaces - cls.create_pg_interfaces(range(4)) + cls.create_pg_interfaces(n_ifs) - # Packet flows mapping pg0 -> pg1, pg2, pg3 etc. cls.flows = dict() - cls.flows[cls.pg0] = [cls.pg1, cls.pg2, cls.pg3] - cls.flows[cls.pg1] = [cls.pg0, cls.pg2, cls.pg3] - cls.flows[cls.pg2] = [cls.pg0, cls.pg1, cls.pg3] - cls.flows[cls.pg3] = [cls.pg0, cls.pg1, cls.pg2] + for bd_id in n_brs: + # Packet flows mapping pg0 -> pg1, pg2, pg3 etc. + ifs = cls.bd_ifs(bd_id) + for j in ifs: + cls.flows[cls.pg_interfaces[j]] = [ + cls.pg_interfaces[x] for x in ifs if x != j] # Packet sizes cls.pg_if_packet_sizes = [64, 512, 1518, 9018] - # Create BD with MAC learning and unknown unicast flooding disabled - # and put interfaces to this BD - cls.vapi.bridge_domain_add_del( - bd_id=cls.bd_id, uu_flood=0, learn=0) - for pg_if in cls.pg_interfaces: - cls.vapi.sw_interface_set_l2_bridge(pg_if.sw_if_index, - bd_id=cls.bd_id) + for bd_id in n_brs: + # Create BD with MAC learning and unknown unicast flooding + # disabled and put interfaces to this BD + cls.vapi.bridge_domain_add_del( + bd_id=bd_id, uu_flood=0, learn=0) + ifs = [cls.pg_interfaces[i] for i in cls.bd_ifs(bd_id)] + for pg_if in ifs: + cls.vapi.sw_interface_set_l2_bridge(pg_if.sw_if_index, + bd_id=bd_id) # Set up all interfaces for i in cls.pg_interfaces: i.admin_up() # Mapping between packet-generator index and lists of test hosts - cls.hosts_by_pg_idx = dict() - for pg_if in cls.pg_interfaces: - cls.hosts_by_pg_idx[pg_if.sw_if_index] = [] - - # Create list of deleted hosts - cls.deleted_hosts_by_pg_idx = dict() + cls.hosts = dict() + cls.learned_hosts = dict() + cls.fib_hosts = dict() + cls.deleted_hosts = dict() for pg_if in cls.pg_interfaces: - cls.deleted_hosts_by_pg_idx[pg_if.sw_if_index] = [] + swif = pg_if.sw_if_index + cls.hosts[swif] = [] + cls.learned_hosts[swif] = [] + cls.fib_hosts[swif] = [] + cls.deleted_hosts[swif] = [] except Exception: super(TestL2fib, cls).tearDownClass() @@ -141,81 +148,144 @@ class TestL2fib(VppTestCase): super(TestL2fib, self).tearDown() if not self.vpp_dead: self.logger.info(self.vapi.ppcli("show l2fib verbose")) - self.logger.info(self.vapi.ppcli("show bridge-domain %s detail" - % self.bd_id)) + for bd_id in self.n_brs: + self.logger.info(self.vapi.ppcli("show bridge-domain %s detail" + % bd_id)) - def create_hosts(self, count, start=0): + def create_hosts(self, n_hosts_per_if, subnet): """ Create required number of host MAC addresses and distribute them among interfaces. Create host IPv4 address for every host MAC address. - :param int count: Number of hosts to create MAC/IPv4 addresses for. - :param int start: Number to start numbering from. + :param int n_hosts_per_if: Number of per interface hosts to + create MAC/IPv4 addresses for. """ - n_int = len(self.pg_interfaces) - macs_per_if = count / n_int - i = -1 + for pg_if in self.pg_interfaces: - i += 1 - start_nr = macs_per_if * i + start - end_nr = count + start if i == (n_int - 1) \ - else macs_per_if * (i + 1) + start - hosts = self.hosts_by_pg_idx[pg_if.sw_if_index] - for j in range(start_nr, end_nr): - host = Host( - "00:00:00:ff:%02x:%02x" % (pg_if.sw_if_index, j), - "172.17.1%02x.%u" % (pg_if.sw_if_index, j)) - hosts.append(host) - - def config_l2_fib_entries(self, count, start=0): + swif = pg_if.sw_if_index + + def mac(j): return "00:00:%02x:ff:%02x:%02x" % (subnet, swif, j) + + def ip(j): return "172.%02u.1%02x.%u" % (subnet, swif, j) + + def h(j): return Host(mac(j), ip(j)) + self.hosts[swif] = [h(j) for j in range(n_hosts_per_if)] + + def learn_hosts(self, bd_id, n_hosts_per_if): + """ + Create L2 MAC packet stream with host MAC addresses per interface to + let the bridge domain learn these MAC addresses. + + :param int bd_id: BD to teach + :param int n_hosts_per_if: number of hosts + """ + self.vapi.bridge_flags(bd_id, 1, 1) + ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] + for pg_if in ifs: + swif = pg_if.sw_if_index + hosts = self.hosts[swif] + lhosts = self.learned_hosts[swif] + packets = [] + for j in range(n_hosts_per_if): + host = hosts.pop() + lhosts.append(host) + packet = (Ether(dst="ff:ff:ff:ff:ff:ff", src=host.mac)) + packets.append(packet) + pg_if.add_stream(packets) + self.logger.info("Sending broadcast eth frames for MAC learning") + self.pg_start() + + def config_l2_fib_entries(self, bd_id, n_hosts_per_if): """ - Create required number of L2 FIB entries. + Config required number of L2 FIB entries. + :param int bd_id: BD's id :param int count: Number of L2 FIB entries to be created. :param int start: Starting index of the host list. (Default value = 0) """ - n_int = len(self.pg_interfaces) - percent = 0 - counter = 0.0 - for pg_if in self.pg_interfaces: - end_nr = start + count / n_int - for j in range(start, end_nr): - host = self.hosts_by_pg_idx[pg_if.sw_if_index][j] + ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] + for pg_if in ifs: + swif = pg_if.sw_if_index + hosts = self.hosts[swif] + fhosts = self.fib_hosts[swif] + for j in range(n_hosts_per_if): + host = hosts.pop() self.vapi.l2fib_add_del( - host.mac, self.bd_id, pg_if.sw_if_index, static_mac=1) - counter += 1 - percentage = counter / count * 100 - if percentage > percent: - self.logger.info("Configure %d L2 FIB entries .. %d%% done" - % (count, percentage)) - percent += 1 + host.mac, bd_id, swif, static_mac=1) + fhosts.append(host) + # del hosts[0] + self.logger.info("Configure %d L2 FIB entries .." % + len(self.pg_interfaces) * n_hosts_per_if) self.logger.info(self.vapi.ppcli("show l2fib")) - def delete_l2_fib_entry(self, count): + def delete_l2_fib_entry(self, bd_id, n_hosts_per_if): """ Delete required number of L2 FIB entries. :param int count: Number of L2 FIB entries to be created. """ - n_int = len(self.pg_interfaces) - percent = 0 - counter = 0.0 - for pg_if in self.pg_interfaces: - for j in range(count / n_int): - host = self.hosts_by_pg_idx[pg_if.sw_if_index][0] + ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] + for pg_if in ifs: + swif = pg_if.sw_if_index + hosts = self.fib_hosts[swif] + dhosts = self.deleted_hosts[swif] + for j in range(n_hosts_per_if): + host = hosts.pop() self.vapi.l2fib_add_del( - host.mac, self.bd_id, pg_if.sw_if_index, is_add=0) - self.deleted_hosts_by_pg_idx[pg_if.sw_if_index].append(host) - del self.hosts_by_pg_idx[pg_if.sw_if_index][0] - counter += 1 - percentage = counter / count * 100 - if percentage > percent: - self.logger.info("Delete %d L2 FIB entries .. %d%% done" - % (count, percentage)) - percent += 1 + host.mac, bd_id, swif, is_add=0) + dhosts.append(host) self.logger.info(self.vapi.ppcli("show l2fib")) - def create_stream(self, src_if, packet_sizes, deleted=False): + def flush_int(self, swif): + """ + Flush swif L2 FIB entries. + + :param int swif: sw if index. + """ + flushed = dict() + self.vapi.l2fib_flush_int(swif) + self.deleted_hosts[swif] = self.learned_hosts[swif] + \ + self.deleted_hosts[swif] + flushed[swif] = self.learned_hosts[swif] + self.learned_hosts[swif] = [] + self.logger.info(self.vapi.ppcli("show l2fib")) + return flushed + + def flush_bd(self, bd_id): + """ + Flush bd_id L2 FIB entries. + + :param int bd_id: Bridge Domain id. + """ + self.vapi.l2fib_flush_bd(bd_id) + flushed = dict() + ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] + for pg_if in ifs: + swif = pg_if.sw_if_index + self.deleted_hosts[swif] = self.learned_hosts[swif] + \ + self.deleted_hosts[swif] + flushed[swif] = self.learned_hosts[swif] + self.learned_hosts[swif] = [] + self.logger.info(self.vapi.ppcli("show l2fib")) + return flushed + + def flush_all(self): + """ + Flush All L2 FIB entries. + """ + self.vapi.l2fib_flush_all() + flushed = dict() + for pg_if in self.pg_interfaces: + swif = pg_if.sw_if_index + self.deleted_hosts[swif] = self.learned_hosts[swif] + \ + self.deleted_hosts[swif] + flushed[swif] = self.learned_hosts[swif] + self.learned_hosts[swif] = [] + self.logger.info(self.vapi.ppcli("show l2fib")) + return flushed + + def create_stream(self, src_if, packet_sizes, if_src_hosts=None, + if_dst_hosts=None): """ Create input packet stream for defined interface using hosts or deleted_hosts list. @@ -225,13 +295,20 @@ class TestL2fib(VppTestCase): :param boolean deleted: Set to True if deleted_hosts list required. :return: Stream of packets. """ + if not if_src_hosts: + if_src_hosts = self.fib_hosts + if not if_dst_hosts: + if_dst_hosts = self.fib_hosts + src_hosts = if_src_hosts[src_if.sw_if_index] + if not src_hosts: + return [] pkts = [] - src_hosts = self.hosts_by_pg_idx[src_if.sw_if_index] for dst_if in self.flows[src_if]: - dst_hosts = self.deleted_hosts_by_pg_idx[dst_if.sw_if_index]\ - if deleted else self.hosts_by_pg_idx[dst_if.sw_if_index] - n_int = len(dst_hosts) - for i in range(0, n_int): + dst_swif = dst_if.sw_if_index + if dst_swif not in if_dst_hosts: + continue + dst_hosts = if_dst_hosts[dst_swif] + for i in range(0, len(dst_hosts)): dst_host = dst_hosts[i] src_host = random.choice(src_hosts) pkt_info = self.create_packet_info(src_if, dst_if) @@ -289,90 +366,158 @@ class TestL2fib(VppTestCase): "Port %u: Packet expected from source %u didn't arrive" % (dst_sw_if_index, i.sw_if_index)) - def run_verify_test(self): + def run_verify_test(self, bd_id, dst_hosts=None): # Test # Create incoming packet streams for packet-generator interfaces - for i in self.pg_interfaces: - pkts = self.create_stream(i, self.pg_if_packet_sizes) + if not dst_hosts: + dst_hosts = self.fib_hosts + self.reset_packet_infos() + ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] + for i in ifs: + pkts = self.create_stream( + i, self.pg_if_packet_sizes, if_dst_hosts=dst_hosts) i.add_stream(pkts) + self.vapi.bridge_flags(bd_id, 0, 1) # Enable packet capture and start packet sending - self.pg_enable_capture(self.pg_interfaces) + self.pg_enable_capture(ifs) self.pg_start() # Verify # Verify outgoing packet streams per packet-generator interface - for i in self.pg_interfaces: + for i in ifs: + if not dst_hosts[i.sw_if_index]: + continue capture = i.get_capture() self.logger.info("Verifying capture on interface %s" % i.name) self.verify_capture(i, capture) - def run_verify_negat_test(self): + def run_verify_negat_test(self, bd_id, dst_hosts=None): # Test # Create incoming packet streams for packet-generator interfaces for # deleted MAC addresses + if not dst_hosts: + dst_hosts = self.deleted_hosts self.reset_packet_infos() - for i in self.pg_interfaces: - pkts = self.create_stream(i, self.pg_if_packet_sizes, deleted=True) - i.add_stream(pkts) - + ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] + for i in ifs: + pkts = self.create_stream( + i, self.pg_if_packet_sizes, if_dst_hosts=dst_hosts) + if pkts: + i.add_stream(pkts) + + self.vapi.bridge_flags(bd_id, 0, 1) # Enable packet capture and start packet sending - self.pg_enable_capture(self.pg_interfaces) + self.pg_enable_capture(ifs) self.pg_start() # Verify # Verify outgoing packet streams per packet-generator interface - for i in self.pg_interfaces: + timeout = 1 + for i in ifs: + i.get_capture(0, timeout=timeout) i.assert_nothing_captured(remark="outgoing interface") + timeout = 0.1 def test_l2_fib_01(self): """ L2 FIB test 1 - program 100 MAC addresses """ # Config 1 # Create test host entries - self.create_hosts(100) + self.create_hosts(100, subnet=17) # Add first 100 MAC entries to L2 FIB - self.config_l2_fib_entries(100) + self.config_l2_fib_entries(bd_id=1, n_hosts_per_if=100) # Test 1 - self.run_verify_test() + self.run_verify_test(bd_id=1) def test_l2_fib_02(self): """ L2 FIB test 2 - delete 12 MAC entries """ # Config 2 - # Delete 12 MAC entries (3 per interface) from L2 FIB - self.delete_l2_fib_entry(12) + # Delete 12 MAC entries per interface from L2 FIB + self.delete_l2_fib_entry(bd_id=1, n_hosts_per_if=12) # Test 2a - self.run_verify_test() + self.run_verify_test(bd_id=1) # Verify 2a - self.run_verify_negat_test() + self.run_verify_negat_test(bd_id=1) def test_l2_fib_03(self): """ L2 FIB test 3 - program new 100 MAC addresses """ # Config 3 # Create new test host entries - self.create_hosts(100, start=100) + self.create_hosts(100, subnet=22) # Add new 100 MAC entries to L2 FIB - self.config_l2_fib_entries(100, start=22) + self.config_l2_fib_entries(bd_id=1, n_hosts_per_if=100) # Test 3 - self.run_verify_test() + self.run_verify_test(bd_id=1) def test_l2_fib_04(self): """ L2 FIB test 4 - delete 160 MAC entries """ # Config 4 - # Delete 160 MAC entries (40 per interface) from L2 FIB - self.delete_l2_fib_entry(160) + # Delete 160 MAC entries per interface from L2 FIB + self.delete_l2_fib_entry(bd_id=1, n_hosts_per_if=160) # Test 4a - self.run_verify_negat_test() + self.run_verify_negat_test(bd_id=1) + + def test_l2_fib_05(self): + """ L2 FIB test 5 - Program 10 new MAC entries, learn 10 + """ + self.create_hosts(20, subnet=35) + + self.learn_hosts(bd_id=1, n_hosts_per_if=10) + self.learn_hosts(bd_id=2, n_hosts_per_if=10) + self.config_l2_fib_entries(bd_id=1, n_hosts_per_if=10) + self.config_l2_fib_entries(bd_id=2, n_hosts_per_if=10) + self.run_verify_test(bd_id=1, dst_hosts=self.learned_hosts) + self.run_verify_test(bd_id=2, dst_hosts=self.learned_hosts) + + def test_l2_fib_06(self): + """ L2 FIB test 6 - flush first interface + """ + self.create_hosts(20, subnet=36) + + self.learn_hosts(bd_id=1, n_hosts_per_if=10) + self.learn_hosts(bd_id=2, n_hosts_per_if=10) + self.config_l2_fib_entries(bd_id=1, n_hosts_per_if=10) + self.config_l2_fib_entries(bd_id=2, n_hosts_per_if=10) + flushed = self.flush_int(self.pg_interfaces[0].sw_if_index) + self.run_verify_test(bd_id=1, dst_hosts=self.learned_hosts) + self.run_verify_negat_test(bd_id=1, dst_hosts=flushed) + + def test_l2_fib_07(self): + """ L2 FIB test 7 - flush bd_id + """ + self.create_hosts(20, subnet=37) + + self.learn_hosts(bd_id=1, n_hosts_per_if=10) + self.learn_hosts(bd_id=2, n_hosts_per_if=10) + self.config_l2_fib_entries(bd_id=1, n_hosts_per_if=10) + self.config_l2_fib_entries(bd_id=2, n_hosts_per_if=10) + flushed = self.flush_bd(bd_id=1) + self.run_verify_negat_test(bd_id=1, dst_hosts=flushed) + self.run_verify_test(bd_id=2, dst_hosts=self.learned_hosts) + + def test_l2_fib_08(self): + """ L2 FIB test 8 - flush all + """ + self.create_hosts(20, subnet=38) + + self.learn_hosts(bd_id=1, n_hosts_per_if=10) + self.learn_hosts(bd_id=2, n_hosts_per_if=10) + self.config_l2_fib_entries(bd_id=1, n_hosts_per_if=10) + self.config_l2_fib_entries(bd_id=2, n_hosts_per_if=10) + flushed = self.flush_all() + self.run_verify_negat_test(bd_id=1, dst_hosts=flushed) + self.run_verify_negat_test(bd_id=2, dst_hosts=flushed) if __name__ == '__main__':