X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_mpls.py;h=5b3054801e7889a9391688fea31b49fb7be492e4;hb=983ebaa3ee58f93729ad96d6af24e93784ae43d8;hp=d068bc37ee231de539419cea6db0928ec7dcfa71;hpb=097fa66b986f06281f603767d321ab13ab6c88c3;p=vpp.git diff --git a/test/test_mpls.py b/test/test_mpls.py index d068bc37ee2..5b3054801e7 100644 --- a/test/test_mpls.py +++ b/test/test_mpls.py @@ -4,7 +4,7 @@ import unittest import socket from framework import VppTestCase, VppTestRunner -from vpp_ip import DpoProto +from vpp_ip import DpoProto, INVALID_INDEX from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \ VppMplsIpBind, VppIpMRoute, VppMRoutePath, \ MRouteItfFlags, MRouteEntryFlags, VppIpTable, VppMplsTable, \ @@ -379,6 +379,30 @@ class TestMPLS(VppTestCase): except: raise + def verify_capture_fragmented_labelled_ip4(self, src_if, capture, sent, + mpls_labels, ip_ttl=None): + try: + capture = verify_filter(capture, sent) + + for i in range(len(capture)): + tx = sent[0] + rx = capture[i] + tx_ip = tx[IP] + rx_ip = rx[IP] + + verify_mpls_stack(self, rx, mpls_labels) + + self.assertEqual(rx_ip.src, tx_ip.src) + self.assertEqual(rx_ip.dst, tx_ip.dst) + if not ip_ttl: + # IP processing post pop has decremented the TTL + self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl) + else: + self.assertEqual(rx_ip.ttl, ip_ttl) + + except: + raise + def test_swap(self): """ MPLS label swap tests """ @@ -851,6 +875,38 @@ class TestMPLS(VppTestCase): route_10_0_0_2.remove_vpp_config() route_10_0_0_1.remove_vpp_config() + def test_imposition_fragmentation(self): + """ MPLS label imposition fragmentation test """ + + # + # Add a ipv4 non-recursive route with a single out label + # + route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32, + [VppRoutePath(self.pg0.remote_ip4, + self.pg0.sw_if_index, + labels=[VppMplsLabel(32)])]) + route_10_0_0_1.add_vpp_config() + + # + # a stream that matches the route for 10.0.0.1 + # PG0 is in the default table + # + tx = self.create_stream_ip4(self.pg0, "10.0.0.1") + for i in range(0, 257): + self.extend_packet(tx[i], 10000) + + # + # 5 fragments per packet (257*5=1285) + # + rx = self.send_and_expect(self.pg0, tx, self.pg0, 1285) + self.verify_capture_fragmented_labelled_ip4(self.pg0, rx, tx, + [VppMplsLabel(32)]) + + # + # cleanup + # + route_10_0_0_1.remove_vpp_config() + def test_tunnel_pipe(self): """ MPLS Tunnel Tests - Pipe """ @@ -1394,6 +1450,57 @@ class TestMPLS(VppTestCase): dst_ip="ff01::1") self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56") + def test_6pe(self): + """ MPLS 6PE """ + + # + # Add a non-recursive route with a single out label + # + route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32, + [VppRoutePath(self.pg0.remote_ip4, + self.pg0.sw_if_index, + labels=[VppMplsLabel(45)])]) + route_10_0_0_1.add_vpp_config() + + # bind a local label to the route + binding = VppMplsIpBind(self, 44, "10.0.0.1", 32) + binding.add_vpp_config() + + # + # a labelled v6 route that resolves through the v4 + # + route_2001_3 = VppIpRoute( + self, "2001::3", 128, + [VppRoutePath("10.0.0.1", + INVALID_INDEX, + labels=[VppMplsLabel(32)])]) + route_2001_3.add_vpp_config() + + tx = self.create_stream_ip6(self.pg0, "2001::3") + rx = self.send_and_expect(self.pg0, tx, self.pg0) + + self.verify_capture_labelled_ip6(self.pg0, rx, tx, + [VppMplsLabel(45), + VppMplsLabel(32)]) + + # + # and a v4 recursive via the v6 + # + route_20_3 = VppIpRoute( + self, "20.0.0.3", 32, + [VppRoutePath("2001::3", + INVALID_INDEX, + labels=[VppMplsLabel(99)])]) + route_20_3.add_vpp_config() + + tx = self.create_stream_ip4(self.pg0, "20.0.0.3") + rx = self.send_and_expect(self.pg0, tx, self.pg0) + + self.verify_capture_labelled_ip4(self.pg0, rx, tx, + [VppMplsLabel(45), + VppMplsLabel(32), + VppMplsLabel(99)]) + class TestMPLSDisabled(VppTestCase): """ MPLS disabled """ @@ -2043,89 +2150,133 @@ class TestMPLSL2(VppTestCase): def test_vpls(self): """ Virtual Private LAN Service """ # - # Create an L2 MPLS tunnel + # Create a L2 MPLS tunnels # - mpls_tun = VppMPLSTunnelInterface( + mpls_tun1 = VppMPLSTunnelInterface( self, [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[VppMplsLabel(42)])], is_l2=1) - mpls_tun.add_vpp_config() - mpls_tun.admin_up() + mpls_tun1.add_vpp_config() + mpls_tun1.admin_up() + + mpls_tun2 = VppMPLSTunnelInterface( + self, + [VppRoutePath(self.pg0.remote_ip4, + self.pg0.sw_if_index, + labels=[VppMplsLabel(43)])], + is_l2=1) + mpls_tun2.add_vpp_config() + mpls_tun2.admin_up() # - # Create a label entry to for 55 that does L2 input to the tunnel + # Create a label entries, 55 and 56, that do L2 input to the tunnel + # the latter includes a Psuedo Wire Control Word # route_55_eos = VppMplsRoute( self, 55, 1, [VppRoutePath("0.0.0.0", - mpls_tun.sw_if_index, + mpls_tun1.sw_if_index, type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX, proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)], eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET) + + route_56_eos = VppMplsRoute( + self, 56, 1, + [VppRoutePath("0.0.0.0", + mpls_tun2.sw_if_index, + type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX, + flags=FibPathFlags.FIB_PATH_FLAG_POP_PW_CW, + proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)], + eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET) + + # move me + route_56_eos.add_vpp_config() route_55_eos.add_vpp_config() + self.logger.info(self.vapi.cli("sh mpls fib 56")) + # # add to tunnel to the customers bridge-domain # self.vapi.sw_interface_set_l2_bridge( - rx_sw_if_index=mpls_tun.sw_if_index, bd_id=1) + rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1) + self.vapi.sw_interface_set_l2_bridge( + rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1) self.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=self.pg1.sw_if_index, bd_id=1) # - # Packet from the customer interface and from the core - # - p_cust = (Ether(dst="00:00:de:ad:ba:be", - src="00:00:de:ad:be:ef") / - IP(src="10.10.10.10", dst="11.11.11.11") / - UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) - p_core = (Ether(src="00:00:de:ad:ba:be", - dst="00:00:de:ad:be:ef") / - IP(dst="10.10.10.10", src="11.11.11.11") / - UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + # Packet from host on the customer interface to each host + # reachable over the core, and vice-versa + # + p_cust1 = (Ether(dst="00:00:de:ad:ba:b1", + src="00:00:de:ad:be:ef") / + IP(src="10.10.10.10", dst="11.11.11.11") / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + p_cust2 = (Ether(dst="00:00:de:ad:ba:b2", + src="00:00:de:ad:be:ef") / + IP(src="10.10.10.10", dst="11.11.11.12") / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + p_core1 = (Ether(dst=self.pg0.local_mac, + src=self.pg0.remote_mac) / + MPLS(label=55, ttl=64) / + Ether(src="00:00:de:ad:ba:b1", + dst="00:00:de:ad:be:ef") / + IP(dst="10.10.10.10", src="11.11.11.11") / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + p_core2 = (Ether(dst=self.pg0.local_mac, + src=self.pg0.remote_mac) / + MPLS(label=56, ttl=64) / + Raw('\x01' * 4) / # PW CW + Ether(src="00:00:de:ad:ba:b2", + dst="00:00:de:ad:be:ef") / + IP(dst="10.10.10.10", src="11.11.11.12") / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) # # The BD is learning, so send in one of each packet to learn # - p_core_encap = (Ether(dst=self.pg0.local_mac, - src=self.pg0.remote_mac) / - MPLS(label=55, ttl=64) / - p_core) - self.pg1.add_stream(p_cust) - self.pg_enable_capture(self.pg_interfaces) - self.pg_start() - self.pg0.add_stream(p_core_encap) - self.pg_enable_capture(self.pg_interfaces) - self.pg_start() + # 2 packets due to BD flooding + rx = self.send_and_expect(self.pg1, p_cust1, self.pg0, n_rx=2) + rx = self.send_and_expect(self.pg1, p_cust2, self.pg0, n_rx=2) - # we've learnt this so expect it be be forwarded - rx0 = self.pg1.get_capture(1) + # we've learnt this so expect it be be forwarded not flooded + rx = self.send_and_expect(self.pg0, [p_core1], self.pg1) + self.assertEqual(rx[0][Ether].dst, p_cust1[Ether].src) + self.assertEqual(rx[0][Ether].src, p_cust1[Ether].dst) - self.assertEqual(rx0[0][Ether].dst, p_core[Ether].dst) - self.assertEqual(rx0[0][Ether].src, p_core[Ether].src) + rx = self.send_and_expect(self.pg0, [p_core2], self.pg1) + self.assertEqual(rx[0][Ether].dst, p_cust2[Ether].src) + self.assertEqual(rx[0][Ether].src, p_cust2[Ether].dst) # - # now a stream in each direction + # now a stream in each direction from each host # - self.pg1.add_stream(p_cust * NUM_PKTS) - self.pg_enable_capture(self.pg_interfaces) - self.pg_start() + rx = self.send_and_expect(self.pg1, p_cust1 * NUM_PKTS, self.pg0) + self.verify_capture_tunneled_ethernet(rx, p_cust1 * NUM_PKTS, + [VppMplsLabel(42)]) - rx0 = self.pg0.get_capture(NUM_PKTS) + rx = self.send_and_expect(self.pg1, p_cust2 * NUM_PKTS, self.pg0) + self.verify_capture_tunneled_ethernet(rx, p_cust2 * NUM_PKTS, + [VppMplsLabel(43)]) - self.verify_capture_tunneled_ethernet(rx0, p_cust*NUM_PKTS, - [VppMplsLabel(42)]) + rx = self.send_and_expect(self.pg0, p_core1 * NUM_PKTS, self.pg1) + rx = self.send_and_expect(self.pg0, p_core2 * NUM_PKTS, self.pg1) # # remove interfaces from customers bridge-domain # self.vapi.sw_interface_set_l2_bridge( - rx_sw_if_index=mpls_tun.sw_if_index, bd_id=1, enable=0) + rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1, enable=0) + self.vapi.sw_interface_set_l2_bridge( + rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1, enable=0) self.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0)