Skip to content

Commit

Permalink
Add a test for looping PFC frames to CPU
Browse files Browse the repository at this point in the history
Summary: Add a test for sending a PFC frame and looping it back to the CPU. The test expects the PFC frame is unmodified.

Reviewed By: nivinl

Differential Revision: D62415045

fbshipit-source-id: 4a75850018ccc82e1825460dff4436b03b59d301
  • Loading branch information
maxwindiff authored and facebook-github-bot committed Sep 18, 2024
1 parent d43f688 commit da92b08
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 1 deletion.
65 changes: 64 additions & 1 deletion fboss/agent/test/agent_hw_tests/AgentPfcTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

#include "fboss/agent/TxPacket.h"
#include "fboss/agent/packet/PktFactory.h"
#include "fboss/agent/packet/PktUtil.h"
#include "fboss/agent/test/AgentHwTest.h"
#include "fboss/agent/test/utils/ConfigUtils.h"
#include "fboss/agent/test/utils/CoppTestUtils.h"
#include "fboss/agent/test/utils/PacketSnooper.h"
#include "fboss/agent/test/utils/PfcTestUtils.h"
#include "fboss/lib/CommonUtils.h"

Expand Down Expand Up @@ -34,7 +37,7 @@ class AgentPfcTest : public AgentHwTest {
0x01, 0x01, 0x00, classVector, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0,
0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0,
};
std::vector<uint8_t> padding(28, 0);
std::vector<uint8_t> padding(26, 0);
payload.insert(payload.end(), padding.begin(), padding.end());

// Send it out
Expand Down Expand Up @@ -89,4 +92,64 @@ TEST_F(AgentPfcTest, verifyPfcCounters) {
verifyAcrossWarmBoots(setup, verify);
}

TEST_F(AgentPfcTest, verifyPfcLoopback) {
// TODO: Investigate if this can be extended to other ASICs
for (auto* asic : getAgentEnsemble()->getL3Asics()) {
if (asic->getAsicType() != cfg::AsicType::ASIC_TYPE_JERICHO3) {
#if defined(GTEST_SKIP)
GTEST_SKIP();
#endif
return;
}
}

std::vector<PortID> portIds = {masterLogicalInterfacePortIds()[0]};
std::vector<int> losslessPgIds = {2};

auto setup = [&]() {
auto cfg = getAgentEnsemble()->getCurrentConfig();
utility::setupPfcBuffers(cfg, portIds, losslessPgIds);
utility::addPuntPfcPacketAcl(
cfg, utility::getCoppMidPriQueueId(getAgentEnsemble()->getL3Asics()));
applyNewConfig(cfg);

for (const auto& switchId : getSw()->getHwAsicTable()->getSwitchIDs()) {
// TODO: Investigate spurious diag command failures.
std::string out;
getAgentEnsemble()->runDiagCommand(
"m DC3MAC_RSV_MASK MASK=0\n"
"m NBU_RX_MLF_DROP_FC_PKTS RX_DROP_FC_PKTS=0\n"
"g DC3MAC_RSV_MASK\n"
"g NBU_RX_MLF_DROP_FC_PKTS\n"
"",
out,
switchId);
XLOG(DBG3) << "==== Diag command output ====\n"
<< out << "\n==== End output ====";
getAgentEnsemble()->runDiagCommand("quit\n", out, switchId);
}
};

auto verify = [&]() {
utility::SwSwitchPacketSnooper snooper(getSw(), "snooper");
sendPfcFrame(portIds, 0xFF);

WITH_RETRIES({
auto frameRx = snooper.waitForPacket(1);
ASSERT_EVENTUALLY_TRUE(frameRx.has_value());

// Received packet should be unmodified.
folly::io::Cursor cursor(frameRx->get());
EthHdr ethHdr(cursor); // Consume ethernet header
EXPECT_EQ(cursor.readBE<uint16_t>(), 0x0101); // PFC opcode
EXPECT_EQ(cursor.readBE<uint16_t>(), 0x00FF); // PFC class vector
for (int i = 0; i < 8; ++i) {
EXPECT_EQ(cursor.readBE<uint16_t>(), 0x00F0); // PFC quanta
}
});
};

verifyAcrossWarmBoots(setup, verify);
}

} // namespace facebook::fboss
1 change: 1 addition & 0 deletions fboss/agent/test/utils/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ cpp_library(
],
exported_deps = [
"fbsource//third-party/googletest:gtest",
":acl_test_utils",
"//fboss/agent:fboss-types",
"//fboss/agent:switch_config-cpp2-types",
"//fboss/agent:utils",
Expand Down
23 changes: 23 additions & 0 deletions fboss/agent/test/utils/PfcTestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "fboss/agent/test/utils/PfcTestUtils.h"
#include "fboss/agent/Utils.h"
#include "fboss/agent/gen-cpp2/switch_config_types.h"
#include "fboss/agent/test/utils/AclTestUtils.h"

#include <gtest/gtest.h>

Expand Down Expand Up @@ -171,4 +172,26 @@ void setupPfcBuffers(
cfg.bufferPoolConfigs() = std::move(bufferPoolCfgMap);
}

void addPuntPfcPacketAcl(cfg::SwitchConfig& cfg, uint16_t queueId) {
cfg::AclEntry entry;
entry.name() = "pfcMacEntry";
entry.actionType() = cfg::AclActionType::PERMIT;
entry.dstMac() = "01:80:C2:00:00:01";
utility::addAclEntry(&cfg, entry, utility::kDefaultAclTable());

cfg::MatchToAction matchToAction;
matchToAction.matcher() = "pfcMacEntry";
cfg::MatchAction& action = matchToAction.action().ensure();
action.toCpuAction() = cfg::ToCpuAction::TRAP;
action.sendToQueue().ensure().queueId() = queueId;
action.setTc().ensure().tcValue() = queueId;
cfg.cpuTrafficPolicy()
.ensure()
.trafficPolicy()
.ensure()
.matchToAction()
.ensure()
.push_back(matchToAction);
}

} // namespace facebook::fboss::utility
2 changes: 2 additions & 0 deletions fboss/agent/test/utils/PfcTestUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ void setupPfcBuffers(
const std::vector<int>& losslessPgIds,
PfcBufferParams buffer = PfcBufferParams{});

void addPuntPfcPacketAcl(cfg::SwitchConfig& cfg, uint16_t queueId);

} // namespace facebook::fboss::utility

0 comments on commit da92b08

Please sign in to comment.