def test_ip_mcast_signal(self): """ IP Multicast Signal """ # # A (*,G). # one accepting interface, pg0, 1 forwarding interfaces # route_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_232_1_1_1.add_vpp_config() route_232_1_1_1.update_entry_flags( MRouteEntryFlags.MFIB_ENTRY_FLAG_SIGNAL) # # Now the (*,G) is present, send from connected source # tx = self._mcast_connected_send_stream("232.1.1.1") # # Constrct a representation of the signal we expect on pg0 # signal_232_1_1_1_itf_0 = VppMFibSignal(self, route_232_1_1_1, self.pg0.sw_if_index, tx[0]) # # read the only expected signal # signals = self.vapi.mfib_signal_dump() self.assertEqual(1, len(signals)) signal_232_1_1_1_itf_0.compare(signals[0]) # # reading the signal allows for the generation of another # so send more packets and expect the next signal # tx = self._mcast_connected_send_stream("232.1.1.1") signals = self.vapi.mfib_signal_dump() self.assertEqual(1, len(signals)) signal_232_1_1_1_itf_0.compare(signals[0]) # # Set the negate-signal on the accepting interval - the signals # should stop # route_232_1_1_1.update_path_flags( self.pg0.sw_if_index, (MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT | MRouteItfFlags.MFIB_ITF_FLAG_NEGATE_SIGNAL)) self.vapi.cli("clear trace") tx = self._mcast_connected_send_stream("232.1.1.1") signals = self.vapi.mfib_signal_dump() self.assertEqual(0, len(signals)) # # Clear the SIGNAL flag on the entry and the signals should # come back since the interface is still NEGATE-SIGNAL # route_232_1_1_1.update_entry_flags( MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE) tx = self._mcast_connected_send_stream("232.1.1.1") signals = self.vapi.mfib_signal_dump() self.assertEqual(1, len(signals)) signal_232_1_1_1_itf_0.compare(signals[0]) # # Lastly remove the NEGATE-SIGNAL from the interface and the # signals should stop # route_232_1_1_1.update_path_flags(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT) tx = self._mcast_connected_send_stream("232.1.1.1") signals = self.vapi.mfib_signal_dump() self.assertEqual(0, len(signals))
def test_ip_mcast_gre(self): """ IP Multicast Replication over GRE""" gre_if_1 = VppGreInterface(self, self.pg1.local_ip4, self.pg1.remote_ip4).add_vpp_config() gre_if_2 = VppGreInterface(self, self.pg2.local_ip4, self.pg2.remote_ip4).add_vpp_config() gre_if_3 = VppGreInterface(self, self.pg3.local_ip4, self.pg3.remote_ip4).add_vpp_config() gre_if_1.admin_up() gre_if_1.config_ip4() gre_if_2.admin_up() gre_if_2.config_ip4() gre_if_3.admin_up() gre_if_3.config_ip4() # # An (S,G). # one accepting interface, pg0, 2 forwarding interfaces # route_1_1_1_1_232_1_1_1 = VppIpMRoute( self, "1.1.1.1", "232.2.2.2", 64, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(gre_if_1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(gre_if_2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(gre_if_3.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_1_1_1_1_232_1_1_1.add_vpp_config() # # a stream that matches the route for (1.1.1.1,232.2.2.2) # small packets # tx = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) / IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) / GRE() / IP(src="1.1.1.1", dst="232.2.2.2") / UDP(sport=1234, dport=1234) / Raw(b'\a5' * 64)) * 63 self.vapi.cli("clear trace") self.pg1.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg2 & 3 # check the encap headers are as expected based on the egress tunnel rxs = self.pg2.get_capture(len(tx)) for rx in rxs: self.assertEqual(rx[IP].src, gre_if_2.t_src) self.assertEqual(rx[IP].dst, gre_if_2.t_dst) self.assert_packet_checksums_valid(rx) rxs = self.pg3.get_capture(len(tx)) for rx in rxs: self.assertEqual(rx[IP].src, gre_if_3.t_src) self.assertEqual(rx[IP].dst, gre_if_3.t_dst) self.assert_packet_checksums_valid(rx)
def test_ip6_mcast(self): """ IPv6 Multicast Replication """ self.vapi.cli("packet mac-filter pg0 on") self.vapi.cli("packet mac-filter pg1 on") self.vapi.cli("packet mac-filter pg2 on") self.vapi.cli("packet mac-filter pg4 on") self.vapi.cli("packet mac-filter pg5 on") self.vapi.cli("packet mac-filter pg6 on") self.vapi.cli("packet mac-filter pg7 on") # # a stream that matches the default route. gets dropped. # self.vapi.cli("clear trace") tx = self.create_stream_ip6(self.pg0, "2001::1", "ff01::1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() self.pg0.assert_nothing_captured( remark="IPv6 multicast packets forwarded on default route") # # A (*,G). # one accepting interface, pg0, 3 forwarding interfaces # route_ff01_1 = VppIpMRoute( self, "::", "ff01::1", 128, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6), VppMRoutePath(self.pg3.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6) ]) route_ff01_1.add_vpp_config() # # An (S,G). # one accepting interface, pg0, 2 forwarding interfaces # route_2001_ff01_1 = VppIpMRoute( self, "2001::1", "ff01::1", 0, # any grp-len is ok when src is set MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6) ]) route_2001_ff01_1.add_vpp_config() # # An (*,G/m). # one accepting interface, pg0, 1 forwarding interface # route_ff01 = VppIpMRoute( self, "::", "ff01::", 16, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6) ]) route_ff01.add_vpp_config() # # a stream that matches the route for (*, ff01::/16) # sent on the non-accepting interface # self.vapi.cli("clear trace") tx = self.create_stream_ip6(self.pg1, "2002::1", "ff01:2::255") self.send_and_assert_no_replies(self.pg1, tx, "RPF miss") # # a stream that matches the route for (*, ff01::/16) # sent on the accepting interface # self.vapi.cli("clear trace") tx = self.create_stream_ip6(self.pg0, "2002::1", "ff01:2::255") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1 self.verify_capture_ip6(self.pg1, tx) # no replications on Pg0, Pg3 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg2.assert_nothing_captured( remark="IP multicast packets forwarded on PG2") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") # # Bounce the interface and it should still work # self.pg1.admin_down() self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() self.pg1.assert_nothing_captured( remark="IP multicast packets forwarded on down PG1") self.pg1.admin_up() self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() self.verify_capture_ip6(self.pg1, tx) # # a stream that matches the route for (*,ff01::1) # self.vapi.cli("clear trace") tx = self.create_stream_ip6(self.pg0, "2002::2", "ff01::1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1, 2, 3. self.verify_capture_ip6(self.pg1, tx) self.verify_capture_ip6(self.pg2, tx) self.verify_capture_ip6(self.pg3, tx) # no replications on Pg0 self.pg0.assert_nothing_captured( remark="IPv6 multicast packets forwarded on PG0") # # a stream that matches the route for (2001::1, ff00::1) # self.vapi.cli("clear trace") tx = self.create_stream_ip6(self.pg0, "2001::1", "ff01::1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1, 2, self.verify_capture_ip6(self.pg1, tx) self.verify_capture_ip6(self.pg2, tx) # no replications on Pg0, Pg3 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") self.vapi.cli("packet mac-filter pg0 off") self.vapi.cli("packet mac-filter pg1 off") self.vapi.cli("packet mac-filter pg2 off") self.vapi.cli("packet mac-filter pg4 off") self.vapi.cli("packet mac-filter pg5 off") self.vapi.cli("packet mac-filter pg6 off") self.vapi.cli("packet mac-filter pg7 off")
def test_ip_mcast_connected(self): """ IP Multicast Connected Source check """ # # A (*,G). # one accepting interface, pg0, 1 forwarding interfaces # route_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_232_1_1_1.add_vpp_config() route_232_1_1_1.update_entry_flags( MRouteEntryFlags.MFIB_ENTRY_FLAG_CONNECTED) # # Now the (*,G) is present, send from connected source # tx = self._mcast_connected_send_stream("232.1.1.1") # # Constrct a representation of the signal we expect on pg0 # signal_232_1_1_1_itf_0 = VppMFibSignal(self, route_232_1_1_1, self.pg0.sw_if_index, tx[0]) # # read the only expected signal # signals = self.vapi.mfib_signal_dump() self.assertEqual(1, len(signals)) signal_232_1_1_1_itf_0.compare(signals[0]) # # reading the signal allows for the generation of another # so send more packets and expect the next signal # tx = self._mcast_connected_send_stream("232.1.1.1") signals = self.vapi.mfib_signal_dump() self.assertEqual(1, len(signals)) signal_232_1_1_1_itf_0.compare(signals[0]) # # A Second entry with connected check # one accepting interface, pg0, 1 forwarding interfaces # route_232_1_1_2 = VppIpMRoute( self, "0.0.0.0", "232.1.1.2", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_232_1_1_2.add_vpp_config() route_232_1_1_2.update_entry_flags( MRouteEntryFlags.MFIB_ENTRY_FLAG_CONNECTED) # # Send traffic to both entries. One read should net us two signals # signal_232_1_1_2_itf_0 = VppMFibSignal(self, route_232_1_1_2, self.pg0.sw_if_index, tx[0]) tx = self._mcast_connected_send_stream("232.1.1.1") tx2 = self._mcast_connected_send_stream("232.1.1.2") # # read the only expected signal # signals = self.vapi.mfib_signal_dump() self.assertEqual(2, len(signals)) signal_232_1_1_1_itf_0.compare(signals[1]) signal_232_1_1_2_itf_0.compare(signals[0]) route_232_1_1_1.update_entry_flags( MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE) route_232_1_1_2.update_entry_flags( MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE)
def test_bier_tail_o_udp(self): """BIER Tail over UDP""" # # Add a BIER table for sub-domain 0, set 0, and BSL 256 # bti = VppBierTableID(1, 0, BIERLength.BIER_LEN_256) bt = VppBierTable(self, bti, MPLS_LABEL_INVALID) bt.add_vpp_config() # # disposition table # bdt = VppBierDispTable(self, 8) bdt.add_vpp_config() # # BIER route in table that's for-us # bier_route_1 = VppBierRoute(self, bti, 1, [ VppRoutePath("0.0.0.0", 0xffffffff, proto=DpoProto.DPO_PROTO_BIER, nh_table_id=8) ]) bier_route_1.add_vpp_config() # # An entry in the disposition table # bier_de_1 = VppBierDispEntry(self, bdt.id, 99, BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4, DpoProto.DPO_PROTO_BIER, "0.0.0.0", 0, rpf_id=8192) bier_de_1.add_vpp_config() # # A multicast route to forward post BIER disposition # route_eg_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_eg_232_1_1_1.add_vpp_config() route_eg_232_1_1_1.update_rpf_id(8192) # # A packet with all bits set gets spat out to BP:1 # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) / UDP(sport=333, dport=8138) / BIFT(sd=1, set=0, bsl=2, ttl=255) / BIER(length=BIERLength.BIER_LEN_256, BitString=scapy.compat.chb(255) * 32, BFRID=99) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234) / Raw()) rx = self.send_and_expect(self.pg0, [p], self.pg1)
def test_ip_mcast(self): """ IP Multicast Replication """ # # a stream that matches the default route. gets dropped. # self.vapi.cli("clear trace") self.vapi.cli("packet mac-filter pg0 on") self.vapi.cli("packet mac-filter pg1 on") self.vapi.cli("packet mac-filter pg2 on") self.vapi.cli("packet mac-filter pg4 on") self.vapi.cli("packet mac-filter pg5 on") self.vapi.cli("packet mac-filter pg6 on") self.vapi.cli("packet mac-filter pg7 on") tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on default route") # # A (*,G). # one accepting interface, pg0, 7 forwarding interfaces # many forwarding interfaces test the case where the replicate DPO # needs to use extra cache lines for the buckets. # route_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg3.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg4.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg5.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg6.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg7.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_232_1_1_1.add_vpp_config() # # An (S,G). # one accepting interface, pg0, 2 forwarding interfaces # route_1_1_1_1_232_1_1_1 = VppIpMRoute( self, "1.1.1.1", "232.1.1.1", 27, # any grp-len is ok when src is set MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_1_1_1_1_232_1_1_1.add_vpp_config() # # An (S,G). # one accepting interface, pg0, 2 forwarding interfaces # that use unicast next-hops # route_1_1_1_1_232_1_1_2 = VppIpMRoute( self, "1.1.1.1", "232.1.1.2", 64, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, nh=self.pg1.remote_ip4), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, nh=self.pg2.remote_ip4) ]) route_1_1_1_1_232_1_1_2.add_vpp_config() # # An (*,G/m). # one accepting interface, pg0, 1 forwarding interfaces # route_232 = VppIpMRoute( self, "0.0.0.0", "232.0.0.0", 8, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_232.add_vpp_config() # # a stream that matches the route for (1.1.1.1,232.1.1.1) # small packets # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() self.assertEqual(route_1_1_1_1_232_1_1_1.get_stats()['packets'], len(tx)) # We expect replications on Pg1->7 self.verify_capture_ip4(self.pg1, tx) self.verify_capture_ip4(self.pg2, tx) # no replications on Pg0 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") # # a stream that matches the route for (1.1.1.1,232.1.1.1) # large packets # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1", payload_size=1024) self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1->7 self.verify_capture_ip4(self.pg1, tx) self.verify_capture_ip4(self.pg2, tx) self.assertEqual(route_1_1_1_1_232_1_1_1.get_stats()['packets'], 2 * len(tx)) # no replications on Pg0 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") # # a stream to the unicast next-hops # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.2") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1->7 self.verify_capture_ip4(self.pg1, tx, dst_mac=self.pg1.remote_mac) self.verify_capture_ip4(self.pg2, tx, dst_mac=self.pg2.remote_mac) # no replications on Pg0 nor pg3 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") # # a stream that matches the route for (*,232.0.0.0/8) # Send packets with the 9th bit set so we test the correct clearing # of that bit in the mac rewrite # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.255.255.255") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1 only self.verify_capture_ip4(self.pg1, tx) self.assertEqual(route_232.get_stats()['packets'], len(tx)) # no replications on Pg0, Pg2 not Pg3 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg2.assert_nothing_captured( remark="IP multicast packets forwarded on PG2") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") # # a stream that matches the route for (*,232.1.1.1) # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "232.1.1.1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1->7 self.verify_capture_ip4(self.pg1, tx) self.verify_capture_ip4(self.pg2, tx) self.verify_capture_ip4(self.pg3, tx) self.verify_capture_ip4(self.pg4, tx) self.verify_capture_ip4(self.pg5, tx) self.verify_capture_ip4(self.pg6, tx) self.verify_capture_ip4(self.pg7, tx) # no replications on Pg0 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.vapi.cli("packet mac-filter pg0 off") self.vapi.cli("packet mac-filter pg1 off") self.vapi.cli("packet mac-filter pg2 off") self.vapi.cli("packet mac-filter pg4 off") self.vapi.cli("packet mac-filter pg5 off") self.vapi.cli("packet mac-filter pg6 off") self.vapi.cli("packet mac-filter pg7 off")
def bier_e2e(self, hdr_len_id, n_bytes, max_bp): """ BIER end-to-end""" # # Add a BIER table for sub-domain 0, set 0, and BSL 256 # bti = VppBierTableID(0, 0, hdr_len_id) bt = VppBierTable(self, bti, 77) bt.add_vpp_config() lowest = [b'\0'] * (n_bytes) lowest[-1] = scapy.compat.chb(1) highest = [b'\0'] * (n_bytes) highest[0] = scapy.compat.chb(128) # # Impostion Sets bit strings # bi_low = VppBierImp(self, bti, 333, lowest) bi_low.add_vpp_config() bi_high = VppBierImp(self, bti, 334, highest) bi_high.add_vpp_config() # # Add a multicast route that will forward into the BIER doamin # route_ing_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(0xffffffff, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=DpoProto.DPO_PROTO_BIER, bier_imp=bi_low.bi_index) ]) route_ing_232_1_1_1.add_vpp_config() route_ing_232_1_1_2 = VppIpMRoute( self, "0.0.0.0", "232.1.1.2", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(0xffffffff, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=DpoProto.DPO_PROTO_BIER, bier_imp=bi_high.bi_index) ]) route_ing_232_1_1_2.add_vpp_config() # # disposition table 8 # bdt = VppBierDispTable(self, 8) bdt.add_vpp_config() # # BIER routes in table that are for-us, resolving through # disp table 8. # bier_route_1 = VppBierRoute(self, bti, 1, [ VppRoutePath("0.0.0.0", 0xffffffff, proto=DpoProto.DPO_PROTO_BIER, nh_table_id=8) ]) bier_route_1.add_vpp_config() bier_route_max = VppBierRoute( self, bti, max_bp, [VppRoutePath("0.0.0.0", 0xffffffff, nh_table_id=8)]) bier_route_max.add_vpp_config() # # An entry in the disposition table for sender 333 # lookup in VRF 10 # bier_de_1 = VppBierDispEntry(self, bdt.id, 333, BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4, DpoProto.DPO_PROTO_BIER, "0.0.0.0", 10, rpf_id=8192) bier_de_1.add_vpp_config() bier_de_1 = VppBierDispEntry(self, bdt.id, 334, BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4, DpoProto.DPO_PROTO_BIER, "0.0.0.0", 10, rpf_id=8193) bier_de_1.add_vpp_config() # # Add a multicast routes that will forward the traffic # post-disposition # route_eg_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, table_id=10, paths=[ VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_eg_232_1_1_1.add_vpp_config() route_eg_232_1_1_1.update_rpf_id(8192) route_eg_232_1_1_2 = VppIpMRoute( self, "0.0.0.0", "232.1.1.2", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, table_id=10, paths=[ VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_eg_232_1_1_2.add_vpp_config() route_eg_232_1_1_2.update_rpf_id(8193) # # inject a packet in VRF-0. We expect it to be BIER encapped, # replicated, then hit the disposition and be forwarded # out of VRF 10, i.e. on pg1 # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(5) * 32)) rx = self.send_and_expect(self.pg0, p * 65, self.pg1) self.assertEqual(rx[0][IP].src, "1.1.1.1") self.assertEqual(rx[0][IP].dst, "232.1.1.1") p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src="1.1.1.1", dst="232.1.1.2") / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(5) * 512)) rx = self.send_and_expect(self.pg0, p * 65, self.pg1) self.assertEqual(rx[0][IP].src, "1.1.1.1") self.assertEqual(rx[0][IP].dst, "232.1.1.2")
def test_bier_head(self): """BIER head""" # # Add a BIER table for sub-domain 0, set 0, and BSL 256 # bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256) bt = VppBierTable(self, bti, 77) bt.add_vpp_config() # # 2 bit positions via two next hops # nh1 = "10.0.0.1" nh2 = "10.0.0.2" ip_route_1 = VppIpRoute(self, nh1, 32, [ VppRoutePath( self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[2001]) ]) ip_route_2 = VppIpRoute(self, nh2, 32, [ VppRoutePath( self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[2002]) ]) ip_route_1.add_vpp_config() ip_route_2.add_vpp_config() bier_route_1 = VppBierRoute(self, bti, 1, nh1, 101) bier_route_2 = VppBierRoute(self, bti, 2, nh2, 102) bier_route_1.add_vpp_config() bier_route_2.add_vpp_config() # # An imposition object with both bit-positions set # bi = VppBierImp(self, bti, 333, chr(0x3) * 32) bi.add_vpp_config() # # Add a multicast route that will forward into the BIER doamin # route_ing_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(0xffffffff, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=DpoProto.DPO_PROTO_BIER, bier_imp=bi.bi_index) ]) route_ing_232_1_1_1.add_vpp_config() # # inject a packet an IP. We expect it to be BIER encapped, # replicated. # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234)) self.pg0.add_stream([p]) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(2)
def test_ip6_mcast(self): """ IPv6 Multicast Replication """ # # a stream that matches the default route. gets dropped. # self.vapi.cli("clear trace") tx = self.create_stream_ip6(self.pg0, "2001::1", "ff01::1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() self.pg0.assert_nothing_captured( remark="IPv6 multicast packets forwarded on default route") # # A (*,G). # one accepting interface, pg0, 3 forwarding interfaces # route_ff01_1 = VppIpMRoute( self, "::", "ff01::1", 128, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg3.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ], is_ip6=1) route_ff01_1.add_vpp_config() # # An (S,G). # one accepting interface, pg0, 2 forwarding interfaces # route_2001_ff01_1 = VppIpMRoute( self, "2001::1", "ff01::1", 256, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ], is_ip6=1) route_2001_ff01_1.add_vpp_config() # # An (*,G/m). # one accepting interface, pg0, 1 forwarding interface # route_ff01 = VppIpMRoute( self, "::", "ff01::", 16, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ], is_ip6=1) route_ff01.add_vpp_config() # # a stream that matches the route for (*, ff01::/16) # self.vapi.cli("clear trace") tx = self.create_stream_ip6(self.pg0, "2002::1", "ff01:2::255") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1 self.verify_capture_ip6(self.pg1, tx) # no replications on Pg0, Pg3 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg2.assert_nothing_captured( remark="IP multicast packets forwarded on PG2") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") # # a stream that matches the route for (*,ff01::1) # self.vapi.cli("clear trace") tx = self.create_stream_ip6(self.pg0, "2002::2", "ff01::1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1, 2, 3. self.verify_capture_ip6(self.pg1, tx) self.verify_capture_ip6(self.pg2, tx) self.verify_capture_ip6(self.pg3, tx) # no replications on Pg0 self.pg0.assert_nothing_captured( remark="IPv6 multicast packets forwarded on PG0") # # a stream that matches the route for (2001::1, ff00::1) # self.vapi.cli("clear trace") tx = self.create_stream_ip6(self.pg0, "2001::1", "ff01::1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1, 2, self.verify_capture_ip6(self.pg1, tx) self.verify_capture_ip6(self.pg2, tx) # no replications on Pg0, Pg3 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") route_ff01.remove_vpp_config() route_ff01_1.remove_vpp_config() route_2001_ff01_1.remove_vpp_config()
def test_ip_mcast_vrf(self): """IP Multicast Replication in non-default table""" MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t # # An (S,G). # one accepting interface, pg0, 2 forwarding interfaces # route_1_1_1_1_232_1_1_1 = VppIpMRoute( self, "1.1.1.1", "232.1.1.1", 64, MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg8.sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD), ], table_id=10, ) route_1_1_1_1_232_1_1_1.add_vpp_config() # # a stream that matches the route for (1.1.1.1,232.1.1.1) # small packets # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg8, "1.1.1.1", "232.1.1.1") self.pg8.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1 & 2 self.verify_capture_ip4(self.pg1, tx) self.verify_capture_ip4(self.pg2, tx) # # An (S,G). for for-us # route_0_0_0_0_224_0_0_5 = VppIpMRoute( self, "0.0.0.0", "224.0.0.5", 32, MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg8.sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT), VppMRoutePath( 0xFFFFFFFF, MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD, type=FibPathType.FIB_PATH_TYPE_LOCAL, ), ], table_id=10, ) route_0_0_0_0_224_0_0_5.add_vpp_config() # # a stream that matches the route for (0.0.0.0, 224.0.0.5) # small packets # self.vapi.cli("clear trace") self.pg8.resolve_arp() # # send a ping to mcast address from peer on pg8 # expect a response # icmp_id = 0xB icmp_seq = 5 icmp_load = b"\x0a" * 18 tx = (Ether(dst=getmacbyip("224.0.0.5"), src=self.pg8.remote_mac) / IP(src=self.pg8.remote_ip4, dst="224.0.0.5") / ICMP(id=icmp_id, seq=icmp_seq) / Raw(load=icmp_load)) * 2 self.send_and_expect(self.pg8, tx, self.pg8)
def test_ip_disabled(self): """ IP Disabled """ # # An (S,G). # one accepting interface, pg0, 2 forwarding interfaces # route_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)]) route_232_1_1_1.add_vpp_config() pu = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / IP(src="10.10.10.10", dst=self.pg0.remote_ip4) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) pm = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / IP(src="10.10.10.10", dst="232.1.1.1") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) # # PG1 does not forward IP traffic # self.send_and_assert_no_replies(self.pg1, pu, "IP disabled") self.send_and_assert_no_replies(self.pg1, pm, "IP disabled") # # IP enable PG1 # self.pg1.config_ip4() # # Now we get packets through # self.pg1.add_stream(pu) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg0.get_capture(1) self.pg1.add_stream(pm) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg0.get_capture(1) # # Disable PG1 # self.pg1.unconfig_ip4() # # PG1 does not forward IP traffic # self.send_and_assert_no_replies(self.pg1, pu, "IP disabled") self.send_and_assert_no_replies(self.pg1, pm, "IP disabled")
def test_bier_tail(self): """BIER Tail""" # # Add a BIER table for sub-domain 0, set 0, and BSL 256 # bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256) bt = VppBierTable(self, bti, 77) bt.add_vpp_config() # # disposition table # bdt = VppBierDispTable(self, 8) bdt.add_vpp_config() # # BIER route in table that's for-us # bier_route_1 = VppBierRoute(self, bti, 1, [ VppRoutePath("0.0.0.0", 0xffffffff, proto=DpoProto.DPO_PROTO_BIER, nh_table_id=8) ]) bier_route_1.add_vpp_config() # # An entry in the disposition table # bier_de_1 = VppBierDispEntry(self, bdt.id, 99, BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4, DpoProto.DPO_PROTO_BIER, "0.0.0.0", 0, rpf_id=8192) bier_de_1.add_vpp_config() # # A multicast route to forward post BIER disposition # route_eg_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_eg_232_1_1_1.add_vpp_config() route_eg_232_1_1_1.update_rpf_id(8192) # # A packet with all bits set gets spat out to BP:1 # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / MPLS(label=77, ttl=255) / BIER(length=BIERLength.BIER_LEN_256, BitString=chr(255) * 32, BFRID=99) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234) / Raw()) self.send_and_expect(self.pg0, [p], self.pg1) # # A packet that does not match the Disposition entry gets dropped # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / MPLS(label=77, ttl=255) / BIER(length=BIERLength.BIER_LEN_256, BitString=chr(255) * 32, BFRID=77) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234) / Raw()) self.send_and_assert_no_replies(self.pg0, p * 2, "no matching disposition entry") # # Add the default route to the disposition table # bier_de_2 = VppBierDispEntry(self, bdt.id, 0, BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4, DpoProto.DPO_PROTO_BIER, "0.0.0.0", 0, rpf_id=8192) bier_de_2.add_vpp_config() # # now the previous packet is forwarded # self.send_and_expect(self.pg0, [p], self.pg1)
def test_bier_e2e(self): """ BIER end-to-end """ # # Add a BIER table for sub-domain 0, set 0, and BSL 256 # bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256) bt = VppBierTable(self, bti, 77) bt.add_vpp_config() # # Impostion Sets bit string 101010101.... # sender 333 # bi = VppBierImp(self, bti, 333, chr(0x5) * 32) bi.add_vpp_config() # # Add a multicast route that will forward into the BIER doamin # route_ing_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(0xffffffff, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=DpoProto.DPO_PROTO_BIER, bier_imp=bi.bi_index) ]) route_ing_232_1_1_1.add_vpp_config() # # disposition table 8 # bdt = VppBierDispTable(self, 8) bdt.add_vpp_config() # # BIER route in table that's for-us, resolving through # disp table 8. # bier_route_1 = VppBierRoute(self, bti, 1, "0.0.0.0", MPLS_LABEL_INVALID, disp_table=8) bier_route_1.add_vpp_config() # # An entry in the disposition table for sender 333 # lookup in VRF 10 # bier_de_1 = VppBierDispEntry(self, bdt.id, 333, BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4, "0.0.0.0", 10, rpf_id=8192) bier_de_1.add_vpp_config() # # Add a multicast route that will forward the traffic # post-disposition # route_eg_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, table_id=10, paths=[ VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_eg_232_1_1_1.add_vpp_config() route_eg_232_1_1_1.update_rpf_id(8192) # # inject a packet in VRF-0. We expect it to be BIER encapped, # replicated, then hit the disposition and be forwarded # out of VRF 10, i.e. on pg1 # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234)) self.send_and_expect(self.pg0, p * 65, self.pg1)
def test_bier_head(self): """BIER head""" MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t # # Add a BIER table for sub-domain 0, set 0, and BSL 256 # bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256) bt = VppBierTable(self, bti, 77) bt.add_vpp_config() # # 2 bit positions via two next hops # nh1 = "10.0.0.1" nh2 = "10.0.0.2" ip_route_1 = VppIpRoute(self, nh1, 32, [ VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[VppMplsLabel(2001)]) ]) ip_route_2 = VppIpRoute(self, nh2, 32, [ VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[VppMplsLabel(2002)]) ]) ip_route_1.add_vpp_config() ip_route_2.add_vpp_config() bier_route_1 = VppBierRoute( self, bti, 1, [VppRoutePath(nh1, 0xffffffff, labels=[VppMplsLabel(101)])]) bier_route_2 = VppBierRoute( self, bti, 2, [VppRoutePath(nh2, 0xffffffff, labels=[VppMplsLabel(102)])]) bier_route_1.add_vpp_config() bier_route_2.add_vpp_config() # # An imposition object with both bit-positions set # bi = VppBierImp(self, bti, 333, scapy.compat.chb(0x3) * 32) bi.add_vpp_config() # # Add a multicast route that will forward into the BIER doamin # route_ing_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT), VppMRoutePath(0xffffffff, MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD, proto=FibPathProto.FIB_PATH_NH_PROTO_BIER, type=FibPathType.FIB_PATH_TYPE_BIER_IMP, bier_imp=bi.bi_index) ]) route_ing_232_1_1_1.add_vpp_config() # # inject an IP packet. We expect it to be BIER encapped and # replicated. # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234)) self.pg0.add_stream([p]) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(2) # # Encap Stack is; eth, MPLS, MPLS, BIER # igp_mpls = rx[0][MPLS] self.assertEqual(igp_mpls.label, 2001) self.assertEqual(igp_mpls.ttl, 64) self.assertEqual(igp_mpls.s, 0) bier_mpls = igp_mpls[MPLS].payload self.assertEqual(bier_mpls.label, 101) self.assertEqual(bier_mpls.ttl, 64) self.assertEqual(bier_mpls.s, 1) self.assertEqual(rx[0][BIER].length, 2) igp_mpls = rx[1][MPLS] self.assertEqual(igp_mpls.label, 2002) self.assertEqual(igp_mpls.ttl, 64) self.assertEqual(igp_mpls.s, 0) bier_mpls = igp_mpls[MPLS].payload self.assertEqual(bier_mpls.label, 102) self.assertEqual(bier_mpls.ttl, 64) self.assertEqual(bier_mpls.s, 1) self.assertEqual(rx[0][BIER].length, 2)
def test_bier_head_o_udp(self): """BIER head over UDP""" # # Add a BIER table for sub-domain 1, set 0, and BSL 256 # bti = VppBierTableID(1, 0, BIERLength.BIER_LEN_256) bt = VppBierTable(self, bti, 77) bt.add_vpp_config() # # 1 bit positions via 1 next hops # nh1 = "10.0.0.1" ip_route = VppIpRoute(self, nh1, 32, [ VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[VppMplsLabel(2001)]) ]) ip_route.add_vpp_config() udp_encap = VppUdpEncap(self, self.pg0.local_ip4, nh1, 330, 8138) udp_encap.add_vpp_config() bier_route = VppBierRoute(self, bti, 1, [ VppRoutePath("0.0.0.0", 0xFFFFFFFF, is_udp_encap=1, next_hop_id=udp_encap.id) ]) bier_route.add_vpp_config() # # An 2 imposition objects with all bit-positions set # only use the second, but creating 2 tests with a non-zero # value index in the route add # bi = VppBierImp(self, bti, 333, scapy.compat.chb(0xff) * 32) bi.add_vpp_config() bi2 = VppBierImp(self, bti, 334, scapy.compat.chb(0xff) * 32) bi2.add_vpp_config() # # Add a multicast route that will forward into the BIER doamin # route_ing_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(0xffffffff, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=DpoProto.DPO_PROTO_BIER, bier_imp=bi2.bi_index) ]) route_ing_232_1_1_1.add_vpp_config() # # inject a packet an IP. We expect it to be BIER and UDP encapped, # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234)) self.pg0.add_stream([p]) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) # # Encap Stack is, eth, IP, UDP, BIFT, BIER # self.assertEqual(rx[0][IP].src, self.pg0.local_ip4) self.assertEqual(rx[0][IP].dst, nh1) self.assertEqual(rx[0][UDP].sport, 330) self.assertEqual(rx[0][UDP].dport, 8138) self.assertEqual(rx[0][BIFT].bsl, BIERLength.BIER_LEN_256) self.assertEqual(rx[0][BIFT].sd, 1) self.assertEqual(rx[0][BIFT].set, 0) self.assertEqual(rx[0][BIFT].ttl, 64) self.assertEqual(rx[0][BIER].length, 2)
def test_bier_tail(self): """BIER Tail""" MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t # # Add a BIER table for sub-domain 0, set 0, and BSL 256 # bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256) bt = VppBierTable(self, bti, 77) bt.add_vpp_config() # # disposition table # bdt = VppBierDispTable(self, 8) bdt.add_vpp_config() # # BIER route in table that's for-us # bier_route_1 = VppBierRoute(self, bti, 1, [ VppRoutePath("0.0.0.0", 0xffffffff, proto=FibPathProto.FIB_PATH_NH_PROTO_BIER, nh_table_id=8) ]) bier_route_1.add_vpp_config() # # An entry in the disposition table # bier_de_1 = VppBierDispEntry(self, bdt.id, 99, BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4, FibPathProto.FIB_PATH_NH_PROTO_BIER, "0.0.0.0", 0, rpf_id=8192) bier_de_1.add_vpp_config() # # A multicast route to forward post BIER disposition # route_eg_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD) ]) route_eg_232_1_1_1.add_vpp_config() route_eg_232_1_1_1.update_rpf_id(8192) # # A packet with all bits set gets spat out to BP:1 # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / MPLS(label=77, ttl=255) / BIER(length=BIERLength.BIER_LEN_256, BitString=scapy.compat.chb(255) * 32, BFRID=99) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234) / Raw()) self.send_and_expect(self.pg0, [p], self.pg1) # # A packet that does not match the Disposition entry gets dropped # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / MPLS(label=77, ttl=255) / BIER(length=BIERLength.BIER_LEN_256, BitString=scapy.compat.chb(255) * 32, BFRID=77) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234) / Raw()) self.send_and_assert_no_replies(self.pg0, p * 2, "no matching disposition entry") # # Add the default route to the disposition table # bier_de_2 = VppBierDispEntry(self, bdt.id, 0, BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4, FibPathProto.FIB_PATH_NH_PROTO_BIER, "0.0.0.0", 0, rpf_id=8192) bier_de_2.add_vpp_config() # # now the previous packet is forwarded # self.send_and_expect(self.pg0, [p], self.pg1) # # A multicast route to forward post BIER disposition that needs # a check against sending back into the BIER core # bi = VppBierImp(self, bti, 333, scapy.compat.chb(0x3) * 32) bi.add_vpp_config() route_eg_232_1_1_2 = VppIpMRoute( self, "0.0.0.0", "232.1.1.2", 32, MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(0xffffffff, MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD, proto=DpoProto.DPO_PROTO_BIER, type=FibPathType.FIB_PATH_TYPE_BIER_IMP, bier_imp=bi.bi_index), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD) ]) route_eg_232_1_1_2.add_vpp_config() route_eg_232_1_1_2.update_rpf_id(8192) p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / MPLS(label=77, ttl=255) / BIER(length=BIERLength.BIER_LEN_256, BitString=scapy.compat.chb(255) * 32, BFRID=77) / IP(src="1.1.1.1", dst="232.1.1.2") / UDP(sport=1234, dport=1234) / Raw()) self.send_and_expect(self.pg0, [p], self.pg1)
def test_ip_mcast(self): """ IP Multicast Replication """ # # a stream that matches the default route. gets dropped. # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on default route") # # A (*,G). # one accepting interface, pg0, 3 forwarding interfaces # route_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg3.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_232_1_1_1.add_vpp_config() # # An (S,G). # one accepting interface, pg0, 2 forwarding interfaces # route_1_1_1_1_232_1_1_1 = VppIpMRoute( self, "1.1.1.1", "232.1.1.1", 64, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), VppMRoutePath(self.pg2.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_1_1_1_1_232_1_1_1.add_vpp_config() # # An (*,G/m). # one accepting interface, pg0, 1 forwarding interfaces # route_232 = VppIpMRoute( self, "0.0.0.0", "232.0.0.0", 8, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(self.pg1.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD) ]) route_232.add_vpp_config() # # a stream that matches the route for (1.1.1.1,232.1.1.1) # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1, 2, self.verify_capture_ip4(self.pg1, tx) self.verify_capture_ip4(self.pg2, tx) # no replications on Pg0 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") # # a stream that matches the route for (*,232.0.0.0/8) # Send packets with the 9th bit set so we test the correct clearing # of that bit in the mac rewrite # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.255.255.255") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1 only self.verify_capture_ip4(self.pg1, tx) # no replications on Pg0, Pg2 not Pg3 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") self.pg2.assert_nothing_captured( remark="IP multicast packets forwarded on PG2") self.pg3.assert_nothing_captured( remark="IP multicast packets forwarded on PG3") # # a stream that matches the route for (*,232.1.1.1) # self.vapi.cli("clear trace") tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "232.1.1.1") self.pg0.add_stream(tx) self.pg_enable_capture(self.pg_interfaces) self.pg_start() # We expect replications on Pg1, 2, 3. self.verify_capture_ip4(self.pg1, tx) self.verify_capture_ip4(self.pg2, tx) self.verify_capture_ip4(self.pg3, tx) # no replications on Pg0 self.pg0.assert_nothing_captured( remark="IP multicast packets forwarded on PG0") route_232_1_1_1.remove_vpp_config() route_1_1_1_1_232_1_1_1.remove_vpp_config() route_232.remove_vpp_config()