Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bazel/BUILD.otg-models.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ cc_proto_library(
cc_grpc_library(
name = "otg_grpc_proto",
srcs = [":otg_proto"],
generate_mocks = True,
grpc_only = True,
deps = [":otg_cc_proto"],
)
11 changes: 6 additions & 5 deletions dvaas/dataplane_validation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1121,16 +1121,17 @@ absl::StatusOr<ValidationResult> DataplaneValidator::ValidateDataplane(
pins_test::MirrorSutP4rtPortIdConfigToControlSwitch(testbed));

// Ensure that all enabled ports are up for control switch.
RETURN_IF_ERROR(
pins_test::WaitForEnabledInterfacesToBeUp(testbed.ControlSwitch()))
RETURN_IF_ERROR(pins_test::WaitForEnabledEthernetInterfacesToBeUp(
testbed.ControlSwitch()))
.SetPrepend()
<< "expected enabled interfaces on control switch to be up: ";
<< "expected enabled ethernet interfaces on control switch to be up: ";
}

// Ensure that all enabled ports are up for SUT.
RETURN_IF_ERROR(pins_test::WaitForEnabledInterfacesToBeUp(testbed.Sut()))
RETURN_IF_ERROR(
pins_test::WaitForEnabledEthernetInterfacesToBeUp(testbed.Sut()))
.SetPrepend()
<< "expected enabled interfaces on SUT to be up: ";
<< "expected enabled ethernet interfaces on SUT to be up: ";

// Do not return on error in order to restore the original control switch
// gNMI interface config's P4RT IDs.
Expand Down
7 changes: 4 additions & 3 deletions dvaas/mirror_testbed_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -422,11 +422,12 @@ absl::Status MirrorTestbedConfigurator::ConfigureForForwardingTest(

// Ensure that all enabled ports are up.
if (params.wait_for_all_enabled_interfaces_to_be_up) {
RETURN_IF_ERROR(pins_test::WaitForEnabledInterfacesToBeUp(testbed_.Sut()))
RETURN_IF_ERROR(
pins_test::WaitForEnabledEthernetInterfacesToBeUp(testbed_.Sut()))
.SetPrepend()
<< "expected enabled interfaces on SUT to be up: ";
RETURN_IF_ERROR(
pins_test::WaitForEnabledInterfacesToBeUp(testbed_.ControlSwitch()))
RETURN_IF_ERROR(pins_test::WaitForEnabledEthernetInterfacesToBeUp(
testbed_.ControlSwitch()))
.SetPrepend()
<< "expected enabled interfaces on control switch to be up: ";
}
Expand Down
31 changes: 31 additions & 0 deletions lib/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,34 @@ cc_test(
],
)

cc_library(
name = "otg_helper",
testonly = True,
srcs = ["otg_helper.cc"],
hdrs = ["otg_helper.h"],
deps = [
"//gutil/gutil:status",
"@com_github_grpc_grpc//:grpc++",
"@com_github_otg_models//:otg_cc_proto",
"@com_github_otg_models//:otg_grpc_proto",
"@com_google_absl//absl/log",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:string_view",
],
)

cc_test(
name = "otg_helper_test",
srcs = ["otg_helper_test.cc"],
deps = [
":otg_helper",
"//gutil/gutil:proto_matchers",
"//gutil/gutil:status_matchers",
"@com_github_grpc_grpc//:grpc++",
"@com_github_otg_models//:otg_cc_proto",
"@com_github_otg_models//:otg_grpc_proto",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:string_view",
"@com_google_googletest//:gtest_main",
],
)
46 changes: 46 additions & 0 deletions lib/gnmi/gnmi_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,52 @@ GetAllInterfaceCounters(gnmi::gNMI::StubInterface& gnmi_stub) {
return counters;
}

Counters Counters::operator-(const Counters& other) const {
return Counters{
in_pkts - other.in_pkts,
out_pkts - other.out_pkts,
in_octets - other.in_octets,
out_octets - other.out_octets,
in_unicast_pkts - other.in_unicast_pkts,
out_unicast_pkts - other.out_unicast_pkts,
in_multicast_pkts - other.in_multicast_pkts,
out_multicast_pkts - other.out_multicast_pkts,
in_broadcast_pkts - other.in_broadcast_pkts,
out_broadcast_pkts - other.out_broadcast_pkts,
in_errors - other.in_errors,
out_errors - other.out_errors,
in_discards - other.in_discards,
out_discards - other.out_discards,
in_buffer_discards - other.in_buffer_discards,
in_maxsize_exceeded - other.in_maxsize_exceeded,
in_fcs_errors - other.in_fcs_errors,
in_ipv4_pkts - other.in_ipv4_pkts,
out_ipv4_pkts - other.out_ipv4_pkts,
in_ipv6_pkts - other.in_ipv6_pkts,
out_ipv6_pkts - other.out_ipv6_pkts,
in_ipv6_discarded_pkts - other.in_ipv6_discarded_pkts,
out_ipv6_discarded_pkts - other.out_ipv6_discarded_pkts,
timestamp_ns - other.timestamp_ns,
};
}

absl::StatusOr<Counters> GetCountersForInterface(
absl::string_view interface_name, gnmi::gNMI::StubInterface& gnmi_stub) {
ASSIGN_OR_RETURN(
std::string interface_info,
GetGnmiStatePathInfo(
&gnmi_stub,
absl::StrCat("interfaces/interface[name=", interface_name, "]"),
"openconfig-interfaces:interface"));
ASSIGN_OR_RETURN(json interface_json, json_yang::ParseJson(interface_info));
if (!interface_json.is_array() || interface_json.empty()) {
return absl::InternalError(absl::StrCat(
"Expecting counters for interface ", interface_name,
" to have a non-zero JSON array, but got: ", interface_info));
}
return GetCountersForInterface(interface_json[0]);
}

absl::StatusOr<uint64_t> GetBadIntervalsCounter(
absl::string_view interface_name, gnmi::gNMI::StubInterface& gnmi_stub) {
ASSIGN_OR_RETURN(json port_counters_json,
Expand Down
48 changes: 48 additions & 0 deletions lib/gnmi/gnmi_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,50 @@ struct Counters {
std::optional<uint64_t> carrier_transitions;
uint64_t timestamp_ns = 0;
std::optional<BlackholePortCounters> blackhole_counters;
// Returns the difference between two counters.
Counters operator-(const Counters& other) const;
template <typename Sink>
friend void AbslStringify(Sink& sink, const Counters& c) {
absl::Format(&sink, "in_pkts: %v\n", c.in_pkts);
absl::Format(&sink, "out_pkts: %v\n", c.out_pkts);
absl::Format(&sink, "in_octets: %v\n", c.in_octets);
absl::Format(&sink, "out_octets: %v\n", c.out_octets);
absl::Format(&sink, "in_unicast_pkts: %v\n", c.in_unicast_pkts);
absl::Format(&sink, "out_unicast_pkts: %v\n", c.out_unicast_pkts);
absl::Format(&sink, "in_multicast_pkts: %v\n", c.in_multicast_pkts);
absl::Format(&sink, "out_multicast_pkts: %v\n", c.out_multicast_pkts);
absl::Format(&sink, "in_broadcast_pkts: %v\n", c.in_broadcast_pkts);
absl::Format(&sink, "out_broadcast_pkts: %v\n", c.out_broadcast_pkts);
absl::Format(&sink, "in_errors: %v\n", c.in_errors);
absl::Format(&sink, "out_errors: %v\n", c.out_errors);
absl::Format(&sink, "in_discards: %v\n", c.in_discards);
absl::Format(&sink, "out_discards: %v\n", c.out_discards);
absl::Format(&sink, "in_buffer_discards: %v\n", c.in_buffer_discards);
absl::Format(&sink, "in_maxsize_exceeded: %v\n", c.in_maxsize_exceeded);
absl::Format(&sink, "in_fcs_errors: %v\n", c.in_fcs_errors);
absl::Format(&sink, "in_ipv4_pkts: %v\n", c.in_ipv4_pkts);
absl::Format(&sink, "out_ipv4_pkts: %v\n", c.out_ipv4_pkts);
absl::Format(&sink, "in_ipv6_pkts: %v\n", c.in_ipv6_pkts);
absl::Format(&sink, "out_ipv6_pkts: %v\n", c.out_ipv6_pkts);
absl::Format(&sink, "in_ipv6_discarded_pkts: %v\n",
c.in_ipv6_discarded_pkts);
absl::Format(&sink, "out_ipv6_discarded_pkts: %v\n",
c.out_ipv6_discarded_pkts);
if (c.carrier_transitions.has_value()) {
absl::Format(&sink, "carrier_transitions: %v\n", *c.carrier_transitions);
}
absl::Format(&sink, "timestamp_ns: %v\n", c.timestamp_ns);
if (c.blackhole_counters.has_value()) {
absl::Format(&sink, "blackhole_counters.in_discard_events: %v\n",
c.blackhole_counters.value().in_discard_events);
absl::Format(&sink, "blackhole_counters.out_discard_events: %v\n",
c.blackhole_counters.value().out_discard_events);
absl::Format(&sink, "blackhole_counters.in_error_events: %v\n",
c.blackhole_counters.value().in_error_events);
absl::Format(&sink, "blackhole_counters.fec_not_correctable_events: %v\n",
c.blackhole_counters.value().fec_not_correctable_events);
}
}
};

struct BlackholeSwitchCounters {
Expand Down Expand Up @@ -640,6 +684,10 @@ absl::StatusOr<std::string> GetPortPfcRxEnable(
absl::StatusOr<absl::flat_hash_map<std::string, Counters>>
GetAllInterfaceCounters(gnmi::gNMI::StubInterface& gnmi_stub);

// Gets counters for an interface.
absl::StatusOr<Counters> GetCountersForInterface(
absl::string_view interface_name, gnmi::gNMI::StubInterface& gnmi_stub);

// Gets blackhole counters for an interface.
absl::StatusOr<BlackholePortCounters> GetBlackholePortCounters(
absl::string_view interface_name, gnmi::gNMI::StubInterface& gnmi_stub);
Expand Down
117 changes: 117 additions & 0 deletions lib/otg_helper.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include "lib/otg_helper.h"

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "artifacts/otg.grpc.pb.h"
#include "artifacts/otg.pb.h"
#include "grpcpp/client_context.h"
#include "gutil/gutil/status.h"

namespace pins_test::otg_helper {

void AddPorts(otg::Config& config, absl::string_view src_port_name,
absl::string_view dst_port_name,
absl::string_view src_port_location,
absl::string_view dst_port_location) {
otg::Port* src_port = config.add_ports();
otg::Port* dst_port = config.add_ports();
src_port->set_name(src_port_name);
dst_port->set_name(dst_port_name);
src_port->set_location(src_port_location);
dst_port->set_location(dst_port_location);
}

otg::Flow& CreateFlow(otg::Config& config, absl::string_view src_port_name,
absl::string_view dst_port_name,
absl::string_view flow_name) {
otg::Flow* flow = config.add_flows();
flow->set_name(flow_name);
flow->mutable_tx_rx()->set_choice(otg::FlowTxRx::Choice::port);
flow->mutable_tx_rx()->mutable_port()->set_tx_name(src_port_name);
flow->mutable_tx_rx()->mutable_port()->set_rx_name(dst_port_name);
return *flow;
}

void SetFlowSize(otg::Flow& flow, int flow_size) {
flow.mutable_size()->set_choice(otg::FlowSize::Choice::fixed);
flow.mutable_size()->set_fixed(flow_size);
}

void SetFlowDuration(otg::Flow& flow, int pkt_count) {
flow.mutable_duration()->set_choice(otg::FlowDuration::Choice::fixed_packets);
flow.mutable_duration()->mutable_fixed_packets()->set_packets(pkt_count);
}

void SetFlowRatePps(otg::Flow& flow, int flow_rate) {
flow.mutable_rate()->set_choice(otg::FlowRate::Choice::pps);
flow.mutable_rate()->set_pps(flow_rate);
}

otg::FlowEthernet& AddEthernetHeader(otg::Flow& flow, absl::string_view src_mac,
absl::string_view dst_mac) {
otg::FlowHeader* eth_packet = flow.add_packet();
eth_packet->set_choice(otg::FlowHeader::Choice::ethernet);
otg::FlowEthernet* eth_header = eth_packet->mutable_ethernet();
eth_header->mutable_src()->set_choice(
otg::PatternFlowEthernetSrc::Choice::value);
eth_header->mutable_dst()->set_choice(
otg::PatternFlowEthernetDst::Choice::value);
eth_header->mutable_src()->set_value(src_mac);
eth_header->mutable_dst()->set_value(dst_mac);
return *eth_header;
}

otg::FlowIpv4& AddIPv4Header(otg::Flow& flow, absl::string_view src_ipv4,
absl::string_view dst_ipv4) {
otg::FlowHeader* ipv4_packet = flow.add_packet();
ipv4_packet->set_choice(otg::FlowHeader::Choice::ipv4);
otg::FlowIpv4* ipv4_header = ipv4_packet->mutable_ipv4();
ipv4_header->mutable_src()->set_choice(
otg::PatternFlowIpv4Src::Choice::value);
ipv4_header->mutable_dst()->set_choice(
otg::PatternFlowIpv4Dst::Choice::value);
ipv4_header->mutable_src()->set_value(src_ipv4);
ipv4_header->mutable_dst()->set_value(dst_ipv4);
return *ipv4_header;
}

void SetIPv4Priority(otg::FlowIpv4& ip_packet, int dscp, int ecn) {
ip_packet.mutable_priority()->set_choice(otg::FlowIpv4Priority::Choice::dscp);
ip_packet.mutable_priority()->mutable_dscp()->mutable_phb()->set_value(dscp);
ip_packet.mutable_priority()->mutable_dscp()->mutable_ecn()->set_value(ecn);
}

otg::FlowIpv6& AddIPv6Header(otg::Flow& flow, absl::string_view src_ipv6,
absl::string_view dst_ipv6) {
otg::FlowHeader* ipv6_packet = flow.add_packet();
ipv6_packet->set_choice(otg::FlowHeader::Choice::ipv6);
otg::FlowIpv6* ipv6_header = ipv6_packet->mutable_ipv6();
ipv6_header->mutable_src()->set_choice(
otg::PatternFlowIpv6Src::Choice::value);
ipv6_header->mutable_dst()->set_choice(
otg::PatternFlowIpv6Dst::Choice::value);
ipv6_header->mutable_src()->set_value(src_ipv6);
ipv6_header->mutable_dst()->set_value(dst_ipv6);
return *ipv6_header;
}

absl::Status SetTrafficTransmissionState(
otg::Openapi::StubInterface& otg_stub,
otg::StateTrafficFlowTransmit::State::Enum transmission_state) {
otg::SetControlStateRequest set_state_request;
otg::SetControlStateResponse set_state_response;
grpc::ClientContext set_state_context;
set_state_request.mutable_control_state()->set_choice(
otg::ControlState::Choice::traffic);
set_state_request.mutable_control_state()->mutable_traffic()->set_choice(
otg::StateTraffic::Choice::flow_transmit);
set_state_request.mutable_control_state()
->mutable_traffic()
->mutable_flow_transmit()
->set_state(transmission_state);
return gutil::GrpcStatusToAbslStatus(otg_stub.SetControlState(
&set_state_context, set_state_request, &set_state_response));
}

} // namespace pins_test::otg_helper
44 changes: 44 additions & 0 deletions lib/otg_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef PINS_LIB_OTG_HELPER_H_
#define PINS_LIB_OTG_HELPER_H_

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "artifacts/otg.grpc.pb.h"
#include "artifacts/otg.pb.h"

namespace pins_test::otg_helper {

void AddPorts(otg::Config& config, absl::string_view src_port_name,
absl::string_view dst_port_name,
absl::string_view src_port_location,
absl::string_view dst_port_location);

otg::Flow& CreateFlow(otg::Config& config, absl::string_view src_port_name,
absl::string_view dst_port_name,
absl::string_view flow_name);

void SetFlowSize(otg::Flow& flow, int flow_size);

void SetFlowDuration(otg::Flow& flow, int pkt_count);

void SetFlowRatePps(otg::Flow& flow, int flow_rate);

otg::FlowEthernet& AddEthernetHeader(otg::Flow& flow, absl::string_view src_mac,
absl::string_view dst_mac);

otg::FlowIpv4& AddIPv4Header(otg::Flow& flow, absl::string_view src_ipv4,
absl::string_view dst_ipv4);

void SetIPv4Priority(otg::FlowIpv4& ip_packet, int dscp, int ecn);

otg::FlowIpv6& AddIPv6Header(otg::Flow& flow, absl::string_view src_ipv6,
absl::string_view dst_ipv6);

absl::Status SetTrafficTransmissionState(
otg::Openapi::StubInterface& otg_stub,
otg::StateTrafficFlowTransmit::State::Enum transmission_state);

} // namespace pins_test::otg_helper

#endif // PINS_LIB_OTG_HELPER_H_
Loading