diff --git a/dvaas/packet_injection.cc b/dvaas/packet_injection.cc index d108caac..57a78bc2 100644 --- a/dvaas/packet_injection.cc +++ b/dvaas/packet_injection.cc @@ -153,10 +153,19 @@ absl::StatusOr SendTestPacketsAndCollectOutputs( if (packet_test_vector.input().type() == SwitchInput::DATAPLANE) { const Packet& packet = packet_test_vector.input().packet(); + // Get corresponding control switch port for the packet's ingress port. + ASSIGN_OR_RETURN(const P4rtPortId sut_ingress_port, + P4rtPortId::MakeFromP4rtEncoding(packet.port())); + ASSIGN_OR_RETURN( + const P4rtPortId control_switch_port, + parameters.mirror_testbed_port_map + .GetControlSwitchPortConnectedToSutPort(sut_ingress_port)); + // Inject to egress of control switch. RETURN_IF_ERROR(pins::InjectEgressPacket( - packet.port(), absl::HexStringToBytes(packet.hex()), - control_ir_p4info, &control_switch, injection_delay)); + control_switch_port.GetP4rtEncoding(), + absl::HexStringToBytes(packet.hex()), control_ir_p4info, + &control_switch, injection_delay)); } else { return absl::UnimplementedError( absl::StrCat("Test vector input type not supported\n", diff --git a/dvaas/port_id_map.cc b/dvaas/port_id_map.cc index 0ca38f43..ac393fb3 100644 --- a/dvaas/port_id_map.cc +++ b/dvaas/port_id_map.cc @@ -88,9 +88,28 @@ MirrorTestbedP4rtPortIdMap::GetSutPortConnectedToControlSwitchPort( absl::Substitute("Control port '$0' was not found in control switch " "to SUT P4RT port ID map.", control_port)); - } else { - return it->second; } + return it->second; +} + +absl::StatusOr +MirrorTestbedP4rtPortIdMap::GetControlSwitchPortConnectedToSutPort( + const pins_test::P4rtPortId& sut_port) const { + // Handle implicit identity map. + if (!control_to_sut_port_map_.has_value()) return sut_port; + + // Handle explicit map. + const auto it = absl::c_find_if(*control_to_sut_port_map_, + [&](const auto& control_sut_port) { + return control_sut_port.second == sut_port; + }); + if (it == control_to_sut_port_map_->end()) { + return absl::NotFoundError( + absl::Substitute("SUT port '$0' was not found in control switch " + "to control switch P4RT port ID map.", + sut_port)); + } + return it->first; } absl::Status CheckAndStoreMappedAndUnmappedPortIds( diff --git a/dvaas/port_id_map.h b/dvaas/port_id_map.h index 0246b5c0..38922d83 100644 --- a/dvaas/port_id_map.h +++ b/dvaas/port_id_map.h @@ -66,6 +66,12 @@ class MirrorTestbedP4rtPortIdMap { absl::StatusOr GetSutPortConnectedToControlSwitchPort( const pins_test::P4rtPortId& control_port) const; + // Returns the P4RT port ID of the control switch interface connected to the + // interface on the SUT with the given P4RT port ID according to the port + // mapping. + absl::StatusOr GetControlSwitchPortConnectedToSutPort( + const pins_test::P4rtPortId& sut_port) const; + private: MirrorTestbedP4rtPortIdMap( absl::flat_hash_map diff --git a/dvaas/port_id_map_test.cc b/dvaas/port_id_map_test.cc index 8d023d53..3e265b9f 100644 --- a/dvaas/port_id_map_test.cc +++ b/dvaas/port_id_map_test.cc @@ -43,10 +43,17 @@ TEST(MirrorTestbedP4rtPortIdMap, MirrorTestbedP4rtPortIdMap::CreateFromControlSwitchToSutPortMap( {{port_1, port_2}})); + // Control -> SUT. ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_2), StatusIs(absl::StatusCode::kNotFound)); ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_3), StatusIs(absl::StatusCode::kNotFound)); + + // SUT -> Control. + ASSERT_THAT(port_id_map.GetControlSwitchPortConnectedToSutPort(port_1), + StatusIs(absl::StatusCode::kNotFound)); + ASSERT_THAT(port_id_map.GetControlSwitchPortConnectedToSutPort(port_3), + StatusIs(absl::StatusCode::kNotFound)); } TEST(MirrorTestbedP4rtPortIdMap, @@ -79,10 +86,17 @@ TEST(MirrorTestbedP4rtPortIdMap, MirrorTestbedP4rtPortIdMap::CreateFromSutToControlSwitchPortMap( {{port_1, port_2}})); + // Control -> SUT. ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_1), StatusIs(absl::StatusCode::kNotFound)); ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_3), StatusIs(absl::StatusCode::kNotFound)); + + // SUT -> Control. + ASSERT_THAT(port_id_map.GetControlSwitchPortConnectedToSutPort(port_2), + StatusIs(absl::StatusCode::kNotFound)); + ASSERT_THAT(port_id_map.GetControlSwitchPortConnectedToSutPort(port_3), + StatusIs(absl::StatusCode::kNotFound)); } TEST(MirrorTestbedP4rtPortIdMap, @@ -101,32 +115,7 @@ TEST(MirrorTestbedP4rtPortIdMap, StatusIs(absl::StatusCode::kInvalidArgument)); } -TEST(MirrorTestbedP4rtPortIdMap, - RetrunsCorrectSutPortGivenControlPortGivenControlToSutMapping) { - ASSERT_OK_AND_ASSIGN(const auto port_1, - P4rtPortId::MakeFromP4rtEncoding("1")); - ASSERT_OK_AND_ASSIGN(const auto port_2, - P4rtPortId::MakeFromP4rtEncoding("2")); - ASSERT_OK_AND_ASSIGN(const auto port_3, - P4rtPortId::MakeFromP4rtEncoding("3")); - ASSERT_OK_AND_ASSIGN(const auto port_4, - P4rtPortId::MakeFromP4rtEncoding("4")); - - ASSERT_OK_AND_ASSIGN( - const auto port_id_map, - MirrorTestbedP4rtPortIdMap::CreateFromControlSwitchToSutPortMap({ - {port_1, port_2}, - {port_3, port_4}, - })); - - ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_1), - IsOkAndHolds(Eq(port_2))); - ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_3), - IsOkAndHolds(Eq(port_4))); -} - -TEST(MirrorTestbedP4rtPortIdMap, - RetrunsCorrectSutPortGivenControlPortGivenSutToControlMapping) { +TEST(MirrorTestbedP4rtPortIdMap, ReturnsCorrectPortGivenSutToControlMapping) { ASSERT_OK_AND_ASSIGN(const auto port_1, P4rtPortId::MakeFromP4rtEncoding("1")); ASSERT_OK_AND_ASSIGN(const auto port_2, @@ -143,23 +132,37 @@ TEST(MirrorTestbedP4rtPortIdMap, {port_3, port_4}, })); + // Control -> SUT. ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_2), IsOkAndHolds(Eq(port_1))); ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_4), IsOkAndHolds(Eq(port_3))); + + // SUT -> Control. + ASSERT_THAT(port_id_map.GetControlSwitchPortConnectedToSutPort(port_1), + IsOkAndHolds(Eq(port_2))); + ASSERT_THAT(port_id_map.GetControlSwitchPortConnectedToSutPort(port_3), + IsOkAndHolds(Eq(port_4))); } -TEST(MirrorTestbedP4rtPortIdMap, RetrunsCorrectSutPortWithImplicitIdentityMap) { +TEST(MirrorTestbedP4rtPortIdMap, ReturnsCorrectPortWithImplicitIdentityMap) { const auto port_id_map = MirrorTestbedP4rtPortIdMap::CreateIdentityMap(); ASSERT_OK_AND_ASSIGN(const auto port_1, P4rtPortId::MakeFromP4rtEncoding("1")); ASSERT_OK_AND_ASSIGN(const auto port_2, P4rtPortId::MakeFromP4rtEncoding("2")); + // Control -> SUT. ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_1), IsOkAndHolds(Eq(port_1))); ASSERT_THAT(port_id_map.GetSutPortConnectedToControlSwitchPort(port_2), IsOkAndHolds(Eq(port_2))); + + // SUT -> Control. + ASSERT_THAT(port_id_map.GetControlSwitchPortConnectedToSutPort(port_1), + IsOkAndHolds(Eq(port_1))); + ASSERT_THAT(port_id_map.GetControlSwitchPortConnectedToSutPort(port_2), + IsOkAndHolds(Eq(port_2))); } } // namespace