55
55
#include " platforms/networking/gpins/testing/blackbox/p4/dvaas/gpins_dvaas.h"
56
56
#include " platforms/networking/gpins/testing/lib/test_util.h"
57
57
#include " sai_p4/instantiations/google/test_tools/test_entries.h"
58
+ #include " tests/lib/p4info_helper.h"
58
59
#include " tests/lib/switch_test_setup_helpers.h"
59
60
#include " thinkit/switch.h"
60
61
#include " util/gtl/value_or_die.h"
@@ -83,6 +84,8 @@ struct ReplicaPair {
83
84
int instance;
84
85
};
85
86
87
+ enum class IpmcGroupAssignmentMechanism { kAclRedirect , kIpMulticastTable };
88
+
86
89
// Multicast IPv4 addresses of the form 226.10.#.#. The last two bytes
87
90
// are computed based on the multicast group ID.
88
91
absl::StatusOr<netaddr::Ipv4Address> GetIpv4AddressForReplica (
@@ -162,7 +165,7 @@ absl::StatusOr<std::vector<std::string>> GetNUpInterfaceIDs(
162
165
}
163
166
164
167
// Add table entries for multicast_router_interface_table.
165
- inline absl::StatusOr<std::vector<p4::v1::Entity>> CreateRifTableEntities (
168
+ absl::StatusOr<std::vector<p4::v1::Entity>> CreateRifTableEntities (
166
169
const pdpi::IrP4Info& ir_p4info, const std::string& port_id,
167
170
const int instance, const netaddr::MacAddress& src_mac) {
168
171
ASSIGN_OR_RETURN (std::vector<p4::v1::Entity> entities,
@@ -194,11 +197,9 @@ absl::StatusOr<std::vector<p4::v1::Entity>> CreateMulticastGroupEntities(
194
197
}
195
198
196
199
// Add table entries for ipv4_multicast_table.
197
- inline absl::StatusOr<std::vector<p4::v1::Entity>>
198
- CreateIpv4MulticastTableEntities (const pdpi::IrP4Info& ir_p4info,
199
- const std::string& vrf_id,
200
- const netaddr::Ipv4Address& ip_address,
201
- int multicast_group_id) {
200
+ absl::StatusOr<std::vector<p4::v1::Entity>> CreateIpv4MulticastTableEntities (
201
+ const pdpi::IrP4Info& ir_p4info, const std::string& vrf_id,
202
+ const netaddr::Ipv4Address& ip_address, int multicast_group_id) {
202
203
ASSIGN_OR_RETURN (
203
204
std::vector<p4::v1::Entity> entities,
204
205
sai::EntryBuilder ()
@@ -209,11 +210,9 @@ CreateIpv4MulticastTableEntities(const pdpi::IrP4Info& ir_p4info,
209
210
}
210
211
211
212
// Add table entries for ipv6_multicast_table.
212
- inline absl::StatusOr<std::vector<p4::v1::Entity>>
213
- CreateIpv6MulticastTableEntities (const pdpi::IrP4Info& ir_p4info,
214
- const std::string& vrf_id,
215
- const netaddr::Ipv6Address& ip_address,
216
- int multicast_group_id) {
213
+ absl::StatusOr<std::vector<p4::v1::Entity>> CreateIpv6MulticastTableEntities (
214
+ const pdpi::IrP4Info& ir_p4info, const std::string& vrf_id,
215
+ const netaddr::Ipv6Address& ip_address, int multicast_group_id) {
217
216
ASSIGN_OR_RETURN (
218
217
std::vector<p4::v1::Entity> entities,
219
218
sai::EntryBuilder ()
@@ -257,6 +256,7 @@ absl::Status SetupDefaultMulticastProgramming(
257
256
pdpi::P4RuntimeSession& session, const pdpi::IrP4Info& ir_p4info,
258
257
const p4::v1::Update_Type& update_type, int number_multicast_groups,
259
258
int replicas_per_group, const std::vector<std::string>& port_ids,
259
+ IpmcGroupAssignmentMechanism assignment_mechanism,
260
260
std::vector<p4::v1::Entity>& entities_created) {
261
261
if (port_ids.size () < replicas_per_group) {
262
262
return gutil::InternalErrorBuilder ()
@@ -314,6 +314,25 @@ absl::Status SetupDefaultMulticastProgramming(
314
314
RETURN_IF_ERROR (pdpi::InstallPiEntities (&session, ir_p4info, mc_entities));
315
315
entities_created.insert (entities_created.end (), mc_entities.begin (),
316
316
mc_entities.end ());
317
+
318
+ if (assignment_mechanism == IpmcGroupAssignmentMechanism::kAclRedirect ) {
319
+ // Setup multicast group assignment (ACL redirect).
320
+ // In the default traffic test setup, we only send traffic on one port
321
+ // (port_index 0), so we only need to add one ACL entry.
322
+ const std::string& port_id = port_ids[0 ];
323
+ ASSIGN_OR_RETURN (std::vector<p4::v1::Entity> acl_entities,
324
+ sai::EntryBuilder ()
325
+ .AddIngressAclEntryRedirectingToMulticastGroup (
326
+ /* multicast_group_id=*/ 1 ,
327
+ {.in_port = port_id, .ipmc_table_hit = false })
328
+ .LogPdEntries ()
329
+ .GetDedupedPiEntities (ir_p4info));
330
+ RETURN_IF_ERROR (pdpi::InstallPiEntities (&session, ir_p4info, acl_entities));
331
+ entities_created.insert (entities_created.end (), acl_entities.begin (),
332
+ acl_entities.end ());
333
+ return absl::OkStatus ();
334
+ }
335
+
317
336
// Setup multicast group assignment (IPMC entries).
318
337
std::vector<p4::v1::Entity> ipmc_entities;
319
338
for (int m = 0 ; m < number_multicast_groups; ++m) {
@@ -541,11 +560,11 @@ TEST_P(L3MulticastTestFixture, InsertMulticastGroupBeforeRifFails) {
541
560
/* multicast_group_id=*/ 2 , replicas));
542
561
EXPECT_THAT (
543
562
pdpi::InstallPiEntities (sut_p4rt_session_.get (), ir_p4info_, entities),
544
- StatusIs (
545
- absl::StatusCode:: kUnknown ,
546
- AllOf ( HasSubstr (" #1: NOT_FOUND " ),
547
- HasSubstr ( " [OrchAgent] Multicast group member " ),
548
- HasSubstr ( " does not have an associated RIF available yet " ))));
563
+ StatusIs (absl::StatusCode:: kUnknown ,
564
+ AllOf ( HasSubstr ( " #1: NOT_FOUND " ) ,
565
+ HasSubstr (" [OrchAgent] No corresponding "
566
+ " FIXED_MULTICAST_ROUTER_INTERFACE_TABLE " ),
567
+ HasSubstr ( " entry found for multicast group " ))));
549
568
}
550
569
551
570
TEST_P (L3MulticastTestFixture,
@@ -679,7 +698,8 @@ TEST_P(L3MulticastTestFixture, BasicReplicationProgramming) {
679
698
ASSERT_OK (SetupDefaultMulticastProgramming (
680
699
*sut_p4rt_session_, ir_p4info_, p4::v1::Update::INSERT,
681
700
kNumberMulticastGroupsInTest , /* replicas_per_group=*/ kPortsToUseInTest ,
682
- sut_ports_ids, entities_created));
701
+ sut_ports_ids, IpmcGroupAssignmentMechanism::kIpMulticastTable ,
702
+ entities_created));
683
703
LOG (INFO) << " Added " << entities_created.size () << " entities." ;
684
704
// Build test packets.
685
705
ASSERT_OK_AND_ASSIGN (
@@ -738,6 +758,64 @@ TEST_P(L3MulticastTestFixture, BasicReplicationProgramming) {
738
758
// EXPECT_OK(validation_result_del.HasSuccessRateOfAtLeast(1.0));
739
759
}
740
760
761
+ TEST_P (L3MulticastTestFixture, BasicReplicationProgrammingWithAclRedirect) {
762
+ GetParam ().mirror_testbed ->GetMirrorTestbed ().Environment ().SetTestCaseID (
763
+ " f0cae11a-7829-4be3-b84a-497f86d5d7ca" );
764
+
765
+ if (!gpins::TableHasMatchField (
766
+ ir_p4info_, " acl_ingress_mirror_and_redirect_table" , " in_port" )) {
767
+ GTEST_SKIP ()
768
+ << " Skipping because match field 'in_port' is not available in table "
769
+ << " 'acl_ingress_mirror_and_redirect_table'" ;
770
+ }
771
+
772
+ thinkit::MirrorTestbed& testbed =
773
+ GetParam ().mirror_testbed ->GetMirrorTestbed ();
774
+ constexpr int kNumberMulticastGroupsInTest = 1 ;
775
+ constexpr int kPortsToUseInTest = 2 ;
776
+
777
+ // Get set of ports on the SUT and control switch to test on.
778
+ ASSERT_OK_AND_ASSIGN (
779
+ const std::vector<std::string> sut_ports_ids,
780
+ GetNUpInterfaceIDs (GetParam ().mirror_testbed ->GetMirrorTestbed ().Sut (),
781
+ kPortsToUseInTest + 1 ));
782
+
783
+ std::vector<p4::v1::Entity> entities_created;
784
+ ASSERT_OK (SetupDefaultMulticastProgramming (
785
+ *sut_p4rt_session_, ir_p4info_, p4::v1::Update::INSERT,
786
+ kNumberMulticastGroupsInTest , /* replicas_per_group=*/ kPortsToUseInTest ,
787
+ sut_ports_ids, IpmcGroupAssignmentMechanism::kAclRedirect ,
788
+ entities_created));
789
+ LOG (INFO) << " Added " << entities_created.size () << " entities." ;
790
+
791
+ // Build test packets.
792
+ ASSERT_OK_AND_ASSIGN (
793
+ auto vectors,
794
+ BuildTestVectors (sut_ports_ids, kNumberMulticastGroupsInTest ,
795
+ /* replicas_per_group=*/ kPortsToUseInTest ,
796
+ /* expect_output_packets=*/ true ));
797
+
798
+ // Send test packets.
799
+ LOG (INFO) << " Sending traffic to verify added multicast programming." ;
800
+ dvaas::DataplaneValidationParams dvaas_params =
801
+ dvaas::DefaultGpinsDataplaneValidationParams ();
802
+ // Ensure the port map for the control switch can map to the SUT (for
803
+ // situations where the config differs for SUT and control switch).
804
+ auto interface_to_peer_entity_map = gtl::ValueOrDie (
805
+ gpins::ControlP4rtPortIdBySutP4rtPortIdFromSwitchConfig ());
806
+ dvaas_params.mirror_testbed_port_map_override = gtl::ValueOrDie (
807
+ dvaas::MirrorTestbedP4rtPortIdMap::CreateFromControlSwitchToSutPortMap (
808
+ interface_to_peer_entity_map));
809
+ dvaas_params.packet_test_vector_override = vectors;
810
+
811
+ ASSERT_OK_AND_ASSIGN (
812
+ dvaas::ValidationResult validation_result,
813
+ GetParam ().dvaas ->ValidateDataplane (testbed, dvaas_params));
814
+ // Validate traffic.
815
+ validation_result.LogStatistics ();
816
+ EXPECT_OK (validation_result.HasSuccessRateOfAtLeast (1.0 ));
817
+ }
818
+
741
819
// TEST_P(L3MulticastTestFixture, UnregisteredParticipantProgramming) {
742
820
// GetParam().mirror_testbed->GetMirrorTestbed().Environment().SetTestCaseID(
743
821
// "83344582-5437-48fc-86a9-417c6c48541a");
@@ -800,11 +878,11 @@ TEST_P(L3MulticastTestFixture, AddMulticastReplicaForUnknownPortInstanceFails) {
800
878
801
879
EXPECT_THAT (
802
880
pdpi::InstallPiEntities (sut_p4rt_session_.get (), ir_p4info_, mc_entities),
803
- StatusIs (
804
- absl::StatusCode:: kUnknown ,
805
- AllOf ( HasSubstr (" #1: NOT_FOUND " ),
806
- HasSubstr ( " [OrchAgent] Multicast group member " ),
807
- HasSubstr ( " does not have an associated RIF available yet " ))));
881
+ StatusIs (absl::StatusCode:: kUnknown ,
882
+ AllOf ( HasSubstr ( " #1: NOT_FOUND " ) ,
883
+ HasSubstr (" [OrchAgent] No corresponding "
884
+ " FIXED_MULTICAST_ROUTER_INTERFACE_TABLE " ),
885
+ HasSubstr ( " entry found for multicast group " ))));
808
886
809
887
// Clean up.
810
888
EXPECT_OK (ClearEntities (*sut_p4rt_session_, ir_p4info_, rif_entities));
@@ -983,7 +1061,7 @@ TEST_P(L3MulticastTestFixture, AddIpmcEntryWithInvalidIPv4AddressFails) {
983
1061
ipmc_entities),
984
1062
StatusIs (absl::StatusCode::kUnknown ,
985
1063
AllOf (HasSubstr (" #1: INVALID_ARGUMENT" ),
986
- HasSubstr (" [SAI] SWSS_RC_INVALID_PARAM " ))));
1064
+ HasSubstr (" All entries must satisfy " ))));
987
1065
988
1066
// Clean up.
989
1067
EXPECT_OK (ClearEntities (*sut_p4rt_session_, ir_p4info_, vrf_entities));
@@ -1093,11 +1171,10 @@ TEST_P(L3MulticastTestFixture, DeleteMulticastGroupWhileInUseFails) {
1093
1171
// Attempting to delete multicast group while in use results in an error.
1094
1172
EXPECT_THAT (
1095
1173
ClearEntities (*sut_p4rt_session_, ir_p4info_, mc_entities),
1096
- StatusIs (
1097
- absl::StatusCode::kUnknown ,
1098
- AllOf (HasSubstr (" #1: INVALID_ARGUMENT" ),
1099
- HasSubstr (
1100
- " [OrchAgent] Multicast group 0x0001 cannot be deleted" ))));
1174
+ StatusIs (absl::StatusCode::kUnknown ,
1175
+ AllOf (HasSubstr (" #1: INVALID_ARGUMENT" ),
1176
+ HasSubstr (" [OrchAgent] Multicast group" ),
1177
+ HasSubstr (" cannot be deleted because route entries" ))));
1101
1178
1102
1179
// Clean up.
1103
1180
EXPECT_OK (ClearEntities (*sut_p4rt_session_, ir_p4info_, ipmc_entities));
0 commit comments