From 393060266e9337a3c39d2077aa6b05ee34e2bdce Mon Sep 17 00:00:00 2001 From: Srikrishna Gopu Date: Sun, 1 Dec 2024 22:09:48 -0800 Subject: [PATCH 01/12] make sflow packet in packet factory Summary: As titled, make sflow packet in packet factory Reviewed By: jasmeetbagga Differential Revision: D66344563 fbshipit-source-id: 9e322bf45a7bce0898d45969c33ee3ad8c5ec682 --- cmake/AgentPacket.cmake | 1 + fboss/agent/packet/BUCK | 1 + fboss/agent/packet/PktFactory.cpp | 260 ++++++++++++++++++++++++++++++ fboss/agent/packet/PktFactory.h | 55 ++++++- 4 files changed, 316 insertions(+), 1 deletion(-) diff --git a/cmake/AgentPacket.cmake b/cmake/AgentPacket.cmake index f804c3f543d6f..d5c30a25e452b 100644 --- a/cmake/AgentPacket.cmake +++ b/cmake/AgentPacket.cmake @@ -60,4 +60,5 @@ target_link_libraries(packet_factory ctrl_cpp2 switch_config_cpp2 Folly::folly + sflow_structs ) diff --git a/fboss/agent/packet/BUCK b/fboss/agent/packet/BUCK index df015b6dc1654..d7998861ac057 100644 --- a/fboss/agent/packet/BUCK +++ b/fboss/agent/packet/BUCK @@ -85,6 +85,7 @@ cpp_library( "//fboss/agent:fboss-types", "//fboss/agent:hw_switch", "//fboss/agent:packet", + "//fboss/agent/packet:sflow_structs", "//folly:network_address", "//folly/io:iobuf", ], diff --git a/fboss/agent/packet/PktFactory.cpp b/fboss/agent/packet/PktFactory.cpp index 447d7427d0b72..b25f8548e8967 100644 --- a/fboss/agent/packet/PktFactory.cpp +++ b/fboss/agent/packet/PktFactory.cpp @@ -789,4 +789,264 @@ std::unique_ptr makeTCPTxPacket( 255, payload); } + +template +std::unique_ptr makeSflowV5Packet( + const AllocatePktFn& allocatePacket, + const EthHdr& ethHdr, + const IPHDR& ipHdr, + const UDPHeader& udpHdr, + bool computeChecksum, + folly::IPAddress agentIp, + uint32_t ingressInterface, + uint32_t egressInterface, + uint32_t samplingRate, + const std::vector& payload) { + auto txPacket = allocatePacket( + ethHdr.size() + ipHdr.size() + udpHdr.size() + 104 + payload.size()); + + folly::io::RWPrivateCursor rwCursor(txPacket->buf()); + // Write EthHdr + writeEthHeader( + txPacket, + &rwCursor, + ethHdr.getDstMac(), + ethHdr.getSrcMac(), + ethHdr.getVlanTags(), + ethHdr.getEtherType()); + ipHdr.serialize(&rwCursor); + + // write UDP header, payload and compute checksum + rwCursor.writeBE(udpHdr.srcPort); + rwCursor.writeBE(udpHdr.dstPort); + rwCursor.writeBE(udpHdr.length); + // Skip 2 bytes and compuete checksum later + rwCursor.skip(2); + + sflow::SampleDatagram datagram; + sflow::SampleDatagramV5 datagramV5; + sflow::SampleRecord record; + sflow::FlowSample fsample; + sflow::FlowRecord frecord; + sflow::SampledHeader hdr; + + int bufSize = 1024; + + hdr.protocol = sflow::HeaderProtocol::ETHERNET_ISO88023; + hdr.frameLength = 0; + hdr.stripped = 0; + hdr.header = payload.data(); + hdr.headerLength = payload.size(); + auto hdrSize = hdr.size(); + if (hdrSize % sflow::XDR_BASIC_BLOCK_SIZE > 0) { + hdrSize = (hdrSize / sflow::XDR_BASIC_BLOCK_SIZE + 1) * + sflow::XDR_BASIC_BLOCK_SIZE; + } + + std::vector hb(bufSize); + auto hbuf = folly::IOBuf::wrapBuffer(hb.data(), bufSize); + auto hc = std::make_shared(hbuf.get()); + hdr.serialize(hc.get()); + + frecord.flowFormat = 1; // single flow sample + frecord.flowDataLen = hdrSize; + frecord.flowData = hb.data(); + + fsample.sequenceNumber = 0; + fsample.sourceID = 0; + fsample.samplingRate = samplingRate; + fsample.samplePool = 0; + fsample.drops = 0; + fsample.input = ingressInterface; + fsample.output = egressInterface; + fsample.flowRecordsCnt = 1; + fsample.flowRecords = &frecord; + + std::vector fsb(bufSize); + auto fbuf = folly::IOBuf::wrapBuffer(fsb.data(), bufSize); + auto fc = std::make_shared(fbuf.get()); + fsample.serialize(fc.get()); + size_t fsampleSize = bufSize - fc->length(); + + record.sampleType = 1; // raw header + record.sampleDataLen = fsampleSize; + record.sampleData = fsb.data(); + + datagramV5.agentAddress = agentIp; + datagramV5.subAgentID = 0; // no sub agent + datagramV5.sequenceNumber = 0; // not used + datagramV5.uptime = 0; // not used + datagramV5.samplesCnt = 1; // So far only 1 sample encapsuled + datagramV5.samples = &record; + + datagram.datagramV5 = datagramV5; + datagram.serialize(&rwCursor); + + if (computeChecksum) { + // Need to revisit when we compute the checksum of UDP payload + // folly::io::Cursor payloadStart(rwCursor); + // uint16_t csum = udpHdr.computeChecksum(ipHdr, payloadStart); + // csumCursor.writeBE(csum); + } + return txPacket; +} + +std::unique_ptr makeSflowV5Packet( + const AllocatePktFn& allocator, + std::optional vlan, + folly::MacAddress srcMac, + folly::MacAddress dstMac, + const folly::IPAddressV4& srcIp, + const folly::IPAddressV4& dstIp, + uint16_t srcPort, + uint16_t dstPort, + uint8_t dscp, + uint8_t ttl, + uint32_t ingressInterface, + uint32_t egressInterface, + uint32_t samplingRate, + bool computeChecksum, + std::optional> payload) { + if (!payload) { + payload = kDefaultPayload; + } + const auto& payloadBytes = payload.value(); + // EthHdr + auto ethHdr = makeEthHdr(srcMac, dstMac, vlan, ETHERTYPE::ETHERTYPE_IPV4); + // TODO: This assumes the Sflow V5 packet contains one sample header + // and one sample record. Need to be computed dynamically. + auto sampleHdrSize = 104; + + // IPv4Hdr - total_length field includes the payload + UDP hdr + ip hdr + IPv4Hdr ipHdr( + srcIp, + dstIp, + static_cast(IP_PROTO::IP_PROTO_UDP), + payloadBytes.size() + UDPHeader::size() + sampleHdrSize); + ipHdr.dscp = dscp; + ipHdr.ttl = ttl; + ipHdr.computeChecksum(); + // UDPHeader + UDPHeader udpHdr( + srcPort, + dstPort, + UDPHeader::size() + payloadBytes.size() + sampleHdrSize); + + return makeSflowV5Packet( + allocator, + ethHdr, + ipHdr, + udpHdr, + computeChecksum, + folly::IPAddress(srcIp), + ingressInterface, + egressInterface, + samplingRate, + payloadBytes); +} + +std::unique_ptr makeSflowV5Packet( + const AllocatePktFn& allocator, + std::optional vlan, + folly::MacAddress srcMac, + folly::MacAddress dstMac, + const folly::IPAddressV6& srcIp, + const folly::IPAddressV6& dstIp, + uint16_t srcPort, + uint16_t dstPort, + uint8_t trafficClass, + uint8_t hopLimit, + uint32_t ingressInterface, + uint32_t egressInterface, + uint32_t samplingRate, + bool computeChecksum, + std::optional> payload) { + if (!payload) { + payload = kDefaultPayload; + } + const auto& payloadBytes = payload.value(); + // EthHdr + auto ethHdr = makeEthHdr(srcMac, dstMac, vlan, ETHERTYPE::ETHERTYPE_IPV6); + // TODO: This assumes the Sflow V5 packet contains one sample header + // and one sample record. Need to be computed dynamically. + auto sampleHdrSize = 104; + + // IPv6Hdr + IPv6Hdr ipHdr(srcIp, dstIp); + ipHdr.nextHeader = static_cast(IP_PROTO::IP_PROTO_UDP); + ipHdr.trafficClass = trafficClass; + ipHdr.payloadLength = UDPHeader::size() + payloadBytes.size() + sampleHdrSize; + ipHdr.hopLimit = hopLimit; + // UDPHeader + UDPHeader udpHdr( + srcPort, + dstPort, + UDPHeader::size() + payloadBytes.size() + sampleHdrSize); + + return makeSflowV5Packet( + allocator, + ethHdr, + ipHdr, + udpHdr, + computeChecksum, + folly::IPAddress(srcIp), + ingressInterface, + egressInterface, + samplingRate, + payloadBytes); +} + +std::unique_ptr makeSflowV5Packet( + const AllocatePktFn& allocator, + std::optional vlan, + folly::MacAddress srcMac, + folly::MacAddress dstMac, + const folly::IPAddress& srcIp, + const folly::IPAddress& dstIp, + uint16_t srcPort, + uint16_t dstPort, + uint8_t trafficClass, + uint8_t hopLimit, + uint32_t ingressInterface, + uint32_t egressInterface, + uint32_t samplingRate, + bool computeChecksum, + std::optional> payload) { + CHECK_EQ(srcIp.isV6(), dstIp.isV6()); + if (srcIp.isV6()) { + return makeSflowV5Packet( + allocator, + vlan, + srcMac, + dstMac, + srcIp.asV6(), + dstIp.asV6(), + srcPort, + dstPort, + trafficClass, + hopLimit, + ingressInterface, + egressInterface, + samplingRate, + computeChecksum, + payload); + } + return makeSflowV5Packet( + allocator, + vlan, + srcMac, + dstMac, + srcIp.asV4(), + dstIp.asV4(), + srcPort, + dstPort, + trafficClass, + hopLimit, + ingressInterface, + egressInterface, + samplingRate, + computeChecksum, + payload); +} + } // namespace facebook::fboss::utility diff --git a/fboss/agent/packet/PktFactory.h b/fboss/agent/packet/PktFactory.h index 67358c7f3a819..abb73b8ce92cd 100644 --- a/fboss/agent/packet/PktFactory.h +++ b/fboss/agent/packet/PktFactory.h @@ -8,6 +8,7 @@ #include "fboss/agent/packet/ArpHdr.h" #include "fboss/agent/packet/EthHdr.h" #include "fboss/agent/packet/PTPHeader.h" +#include "fboss/agent/packet/SflowStructs.h" #include @@ -433,6 +434,58 @@ std::unique_ptr makeTCPTxPacket( payload); } -} // namespace utility +std::unique_ptr makeSflowV5Packet( + const AllocatePktFn& allocator, + std::optional vlan, + folly::MacAddress srcMac, + folly::MacAddress dstMac, + const folly::IPAddress& srcIp, + const folly::IPAddress& dstIp, + uint16_t srcPort, + uint16_t dstPort, + uint8_t trafficClass, + uint8_t hopLimit, + uint32_t ingressInterface, + uint32_t egressInterface, + uint32_t samplingRate, + bool computeChecksum, + std::optional> payload); + +template +std::unique_ptr makeSflowV5Packet( + const SwitchT* switchT, + std::optional vlan, + folly::MacAddress srcMac, + folly::MacAddress dstMac, + const folly::IPAddress& srcIp, + const folly::IPAddress& dstIp, + uint16_t srcPort, + uint16_t dstPort, + uint8_t trafficClass, + uint8_t hopLimit, + uint32_t ingressInterface, + uint32_t egressInterface, + uint32_t samplingRate, + bool computeChecksum, + std::optional> payload = + std::optional>()) { + return makeSflowV5Packet( + makeAllocator(switchT), + vlan, + srcMac, + dstMac, + srcIp, + dstIp, + srcPort, + dstPort, + trafficClass, + hopLimit, + ingressInterface, + egressInterface, + samplingRate, + computeChecksum, + payload); +} +} // namespace utility } // namespace facebook::fboss From 4bdbcb1bdb9b23b02423d6711a62ec755bfa53c5 Mon Sep 17 00:00:00 2001 From: Siva Muthusamy Date: Sun, 1 Dec 2024 22:10:58 -0800 Subject: [PATCH 02/12] Reduce the number of test/traffic ports to 1 for dramBlockedTime test on J3AI Summary: As line rate (which is a prerequisite for the dramBlockedTime test) is not hitting if more than 3 ports are used, reducing the number of test/traffic ports to just 1 for this test. Reviewed By: zechengh09 Differential Revision: D66640066 fbshipit-source-id: c5969fabc9d885350bc6d6a28e08c49bc74b1ac9 --- fboss/agent/test/agent_hw_tests/AgentVoqSwitchTests.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fboss/agent/test/agent_hw_tests/AgentVoqSwitchTests.cpp b/fboss/agent/test/agent_hw_tests/AgentVoqSwitchTests.cpp index 50e24ea9bb421..20ffc759d5507 100644 --- a/fboss/agent/test/agent_hw_tests/AgentVoqSwitchTests.cpp +++ b/fboss/agent/test/agent_hw_tests/AgentVoqSwitchTests.cpp @@ -2405,7 +2405,10 @@ TEST_F(AgentVoqSwitchFullScaleDsfNodesTest, stressProgramEcmpRoutes) { TEST_F(AgentVoqSwitchLineRateTest, dramBlockedTime) { auto setup = [=, this]() { - constexpr int kNumberOfPortsForDramBlock{6}; + // Use just one port for the dramBlockedTime test + // Note: If more than 3 ports are used, then traffic wouldn't + // reach line rate which is a prerequisite for this test + constexpr int kNumberOfPortsForDramBlock{1}; setupEcmpDataplaneLoopOnAllPorts(); createTrafficOnMultiplePorts(kNumberOfPortsForDramBlock); }; From d8efb9982ca0354957119bd6e60a494b744bfed6 Mon Sep 17 00:00:00 2001 From: Nivin Lawrence Date: Sun, 1 Dec 2024 23:17:29 -0800 Subject: [PATCH 03/12] Add new class for link level pause traffic test Summary: Add a new test class for 802.3x PAUSE traffic test. Reviewed By: jasmeetbagga Differential Revision: D66528690 fbshipit-source-id: 2e0c1c75183217a4eb976153457ed4675de4007d --- cmake/AgentTestAgentHwTests.cmake | 1 + .../agent_hw_tests/AgentTrafficPauseTests.cpp | 100 ++++++++++++++++++ fboss/agent/test/agent_hw_tests/BUCK | 1 + 3 files changed, 102 insertions(+) create mode 100644 fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp diff --git a/cmake/AgentTestAgentHwTests.cmake b/cmake/AgentTestAgentHwTests.cmake index f5c870f78efa6..565c62773bdda 100644 --- a/cmake/AgentTestAgentHwTests.cmake +++ b/cmake/AgentTestAgentHwTests.cmake @@ -49,6 +49,7 @@ add_library(agent_hw_test_src fboss/agent/test/agent_hw_tests/AgentMmuTuningTests.cpp fboss/agent/test/agent_hw_tests/AgentSflowMirrorTest.cpp fboss/agent/test/agent_hw_tests/AgentAclPriorityTests.cpp + fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp fboss/agent/test/agent_hw_tests/AgentTrunkLoadBalancerTests.cpp fboss/agent/test/agent_hw_tests/AgentTrunkTests.cpp fboss/agent/test/agent_hw_tests/AgentRxReasonTests.cpp diff --git a/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp b/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp new file mode 100644 index 0000000000000..265ff7b4d8ae5 --- /dev/null +++ b/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp @@ -0,0 +1,100 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include "fboss/agent/TxPacket.h" +#include "fboss/agent/packet/PktFactory.h" +#include "fboss/agent/test/AgentHwTest.h" +#include "fboss/agent/test/EcmpSetupHelper.h" +#include "fboss/agent/test/utils/ConfigUtils.h" +#include "fboss/agent/test/utils/CoppTestUtils.h" +#include "fboss/agent/test/utils/OlympicTestUtils.h" +#include "fboss/agent/test/utils/QosTestUtils.h" + +namespace facebook::fboss { + +class AgentTrafficPauseTest : public AgentHwTest { + public: + const folly::IPAddressV6 kDestIp{ + folly::IPAddressV6("2620:0:1cfe:face:b00c::4")}; + + cfg::SwitchConfig initialConfig( + const AgentEnsemble& ensemble) const override { + auto config = utility::onePortPerInterfaceConfig( + ensemble.getSw(), + ensemble.masterLogicalPortIds(), + true /*interfaceHasSubnet*/); + utility::setTTLZeroCpuConfig(ensemble.getL3Asics(), config); + return config; + } + + void setupEcmpTraffic(const PortID& portId) { + utility::EcmpSetupTargetedPorts6 ecmpHelper{ + getProgrammedState(), + utility::getFirstInterfaceMac(getProgrammedState())}; + + const PortDescriptor port(portId); + RoutePrefixV6 route{kDestIp, 128}; + + applyNewState([&](const std::shared_ptr& state) { + return ecmpHelper.resolveNextHops(state, {port}); + }); + + auto routeUpdater = getSw()->getRouteUpdater(); + ecmpHelper.programRoutes(&routeUpdater, {port}, {route}); + + utility::ttlDecrementHandlingForLoopbackTraffic( + getAgentEnsemble(), ecmpHelper.getRouterId(), ecmpHelper.nhop(port)); + } + + void sendPauseFrames(const PortID& portId, const int count) { + // PAUSE frame to have the highest quanta of 0xffff + std::vector payload{0x00, 0x01, 0xff, 0xff}; + std::vector padding(42, 0); + payload.insert(payload.end(), padding.begin(), padding.end()); + auto intfMac = utility::getFirstInterfaceMac(getProgrammedState()); + for (int idx = 0; idx < count; idx++) { + auto pkt = utility::makeEthTxPacket( + getSw(), + utility::firstVlanID(getProgrammedState()), + utility::MacAddressGenerator().get(intfMac.u64NBO() + 1), + folly::MacAddress("01:80:C2:00:00:01"), + ETHERTYPE::ETHERTYPE_EPON, + payload); + // Inject pause frames on highest priority queue to avoid drops + getSw()->sendPacketOutOfPortAsync( + std::move(pkt), + portId, + utility::getOlympicQueueId(utility::OlympicQueueType::NC)); + } + } + + void pumpTraffic(const PortID& portId) { + auto vlanId = utility::firstVlanID(getProgrammedState()); + auto intfMac = utility::getFirstInterfaceMac(getProgrammedState()); + auto dscp = utility::kOlympicQueueToDscp().at(0).front(); + auto srcMac = utility::MacAddressGenerator().get(intfMac.u64NBO() + 1); + for (int i = 0; i < getAgentEnsemble()->getMinPktsForLineRate(portId); + i++) { + auto txPacket = utility::makeUDPTxPacket( + getSw(), + vlanId, + srcMac, + intfMac, + folly::IPAddressV6("2620:0:1cfe:face:b00c::3"), + kDestIp, + 8000, + 8001, + dscp << 2, + 255, + std::vector(2000, 0xff)); + getAgentEnsemble()->sendPacketAsync( + std::move(txPacket), PortDescriptor(portId), std::nullopt); + } + } + + std::vector + getProductionFeaturesVerified() const override { + return {production_features::ProductionFeature::PAUSE}; + } +}; + +} // namespace facebook::fboss diff --git a/fboss/agent/test/agent_hw_tests/BUCK b/fboss/agent/test/agent_hw_tests/BUCK index 26744ba75d3e5..1e0432034fc21 100644 --- a/fboss/agent/test/agent_hw_tests/BUCK +++ b/fboss/agent/test/agent_hw_tests/BUCK @@ -65,6 +65,7 @@ cpp_library( "AgentStateReconstructionTests.cpp", "AgentSwitchStateReplayTest.cpp", "AgentSwitchStatsTxCounterTests.cpp", + "AgentTrafficPauseTests.cpp", "AgentTrafficPfcTests.cpp", "AgentTrunkLoadBalancerTests.cpp", "AgentTrunkTests.cpp", From 298e3fdf0012872d24902df20bd23b4f0ce18314 Mon Sep 17 00:00:00 2001 From: Nivin Lawrence Date: Sun, 1 Dec 2024 23:17:29 -0800 Subject: [PATCH 04/12] Add new function to send pause and check for traffic rates Summary: As titled Reviewed By: jasmeetbagga Differential Revision: D66528688 fbshipit-source-id: d616000867c6d39cf883bda2040e1394e7cdbc50 --- .../agent_hw_tests/AgentTrafficPauseTests.cpp | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp b/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp index 265ff7b4d8ae5..3f012359061fb 100644 --- a/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp +++ b/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp @@ -95,6 +95,55 @@ class AgentTrafficPauseTest : public AgentHwTest { getProductionFeaturesVerified() const override { return {production_features::ProductionFeature::PAUSE}; } -}; + void validateTrafficWithPause( + cfg::PortPause& pauseCfg, + std::function rateChecker) { + const PortID kPortId{masterLogicalInterfacePortIds()[0]}; + auto setup = [&]() { + auto cfg = getAgentEnsemble()->getCurrentConfig(); + auto portCfg = std::find_if( + cfg.ports()->begin(), cfg.ports()->end(), [&kPortId](auto& port) { + return PortID(*port.logicalID()) == kPortId; + }); + portCfg->pause() = std::move(pauseCfg); + applyNewConfig(cfg); + setupEcmpTraffic(kPortId); + }; + auto verify = [&]() { + pumpTraffic(kPortId); + getAgentEnsemble()->waitForLineRateOnPort(kPortId); + auto curPortStats = getLatestPortStats(kPortId); + // Now that we have line rate traffic, send pause + // which should break the traffic loop + XLOG(DBG0) + << "Traffic on port reached line rate, now send back to back PAUSE!"; + std::atomic keepTxingPauseFrames{true}; + std::unique_ptr pauseTxThread = + std::make_unique( + [this, &keepTxingPauseFrames, &kPortId]() { + initThread("PauseFramesTransmitThread"); + while (keepTxingPauseFrames) { + this->sendPauseFrames(kPortId, 1000); + } + }); + HwPortStats prevPortStats{}; + WITH_RETRIES({ + curPortStats = getLatestPortStats(kPortId); + auto rate = + getAgentEnsemble()->getTrafficRate(prevPortStats, curPortStats, 1); + // Update prev stats for the next iteration + prevPortStats = curPortStats; + XLOG(DBG0) << "Current rate is : " << rate + << " bps, pause frames received: " + << curPortStats.inPause_().value(); + EXPECT_EVENTUALLY_TRUE(rateChecker(rate, kPortId)); + }); + keepTxingPauseFrames = false; + pauseTxThread->join(); + pauseTxThread.reset(); + }; + verifyAcrossWarmBoots(setup, verify); + } +}; } // namespace facebook::fboss From 6969f940668578c56df35edc1b31cb502c719cc2 Mon Sep 17 00:00:00 2001 From: Nivin Lawrence Date: Sun, 1 Dec 2024 23:17:29 -0800 Subject: [PATCH 05/12] Add new Pause traffic test to validate Pause with RX/TX/both enabled Summary: As titled Reviewed By: jasmeetbagga Differential Revision: D66528689 fbshipit-source-id: eab7164ce06b6d5812607ea82c13b82676d991e9 --- .../agent_hw_tests/AgentTrafficPauseTests.cpp | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp b/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp index 3f012359061fb..1ac50cd276265 100644 --- a/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp +++ b/fboss/agent/test/agent_hw_tests/AgentTrafficPauseTests.cpp @@ -146,4 +146,51 @@ class AgentTrafficPauseTest : public AgentHwTest { verifyAcrossWarmBoots(setup, verify); } }; +TEST_F(AgentTrafficPauseTest, verifyPauseRxOnly) { + // Enable pause RX alone + cfg::PortPause pauseCfg; + pauseCfg.tx() = false; + pauseCfg.rx() = true; + // Pause should slow down traffic significantly, lets say eventual + // rate should be less than 80% line rate! + auto rateChecker = [this](uint64_t rate, const PortID& portId) { + auto eightyPctLineRate = + static_cast( + getProgrammedState()->getPorts()->getNodeIf(portId)->getSpeed()) * + 1000 * 1000 * 0.8; + return rate && rate < eightyPctLineRate; + }; + validateTrafficWithPause(pauseCfg, rateChecker); +} +TEST_F(AgentTrafficPauseTest, verifyPauseTxOnly) { + // Enable pause TX alone + cfg::PortPause pauseCfg; + pauseCfg.tx() = true; + pauseCfg.rx() = false; + // Pause should have no impact on traffic given only TX is enabled + auto rateChecker = [this](uint64_t rate, const PortID& portId) { + auto lineRate = + static_cast( + getProgrammedState()->getPorts()->getNodeIf(portId)->getSpeed()) * + 1000 * 1000; + return rate >= lineRate; + }; + validateTrafficWithPause(pauseCfg, rateChecker); +} +TEST_F(AgentTrafficPauseTest, verifyPauseRxTx) { + // Enable both RX and TX pause + cfg::PortPause pauseCfg; + pauseCfg.tx() = true; + pauseCfg.rx() = true; + // Pause should slow down traffic significantly, lets say eventual + // rate should be less than 80% line rate! + auto rateChecker = [this](uint64_t rate, const PortID& portId) { + auto eightyPctLineRate = + static_cast( + getProgrammedState()->getPorts()->getNodeIf(portId)->getSpeed()) * + 1000 * 1000 * 0.8; + return rate && rate < eightyPctLineRate; + }; + validateTrafficWithPause(pauseCfg, rateChecker); +} } // namespace facebook::fboss From ba49c680e3c58d19036049726a6d89d985aebac1 Mon Sep 17 00:00:00 2001 From: Alex Hornby Date: Mon, 2 Dec 2024 01:42:44 -0800 Subject: [PATCH 06/12] make openssl install less confusing, align openssl version Summary: X-link: https://github.com/facebookincubator/fizz/pull/152 X-link: https://github.com/facebookincubator/zstrong/pull/1073 On linux getdeps uses system openssl, on macOS we mostly use the homebrew one on github CI. Both of these are openssl3.x, however the fallback build from source version is still set as openssl1.1. This can be confusing, giving the impression getdeps based builds need openssl1.1 * Update the openssl manifest source url to openssl-3.0.15, this version picked to match the ubuntu 22.04 LTS system packages. The other potentially confusing part was that the openssl source tarball was downloaded even when on on a platform like Linux where openssl is always taken from the system packages. * Make the download configurable so that does nothing if satisfied from system packages, and no need to check the cache. Reviewed By: ckwalsh Differential Revision: D66495352 fbshipit-source-id: 4d24bb82bfabe44c7764b819de7f4a05f80daed1 --- build/fbcode_builder/getdeps.py | 7 ++++++- build/fbcode_builder/getdeps/manifest.py | 21 +++++++++++++-------- build/fbcode_builder/manifests/openssl | 12 +++++++----- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/build/fbcode_builder/getdeps.py b/build/fbcode_builder/getdeps.py index 01c6c1f68a828..5f66374f7d982 100755 --- a/build/fbcode_builder/getdeps.py +++ b/build/fbcode_builder/getdeps.py @@ -333,6 +333,12 @@ def run_project_cmd(self, args, loader, manifest): cache = cache_module.create_cache() for m in projects: + fetcher = loader.create_fetcher(m) + if isinstance(fetcher, SystemPackageFetcher): + # We are guaranteed that if the fetcher is set to + # SystemPackageFetcher then this item is completely + # satisfied by the appropriate system packages + continue cached_project = CachedProject(cache, loader, m) if cached_project.download(): continue @@ -348,7 +354,6 @@ def run_project_cmd(self, args, loader, manifest): continue # We need to fetch the sources - fetcher = loader.create_fetcher(m) fetcher.update() diff --git a/build/fbcode_builder/getdeps/manifest.py b/build/fbcode_builder/getdeps/manifest.py index e329da1ee69ce..5cec33aabba72 100644 --- a/build/fbcode_builder/getdeps/manifest.py +++ b/build/fbcode_builder/getdeps/manifest.py @@ -430,23 +430,27 @@ def _create_fetcher(self, build_options, ctx): # We can use the code from fbsource return ShipitTransformerFetcher(build_options, self.shipit_project) + # If both of these are None, the package can only be coming from + # preinstalled toolchain or system packages + repo_url = self.get_repo_url(ctx) + url = self.get("download", "url", ctx=ctx) + # Can we satisfy this dep with system packages? - if build_options.allow_system_packages: + if (repo_url is None and url is None) or build_options.allow_system_packages: if self._is_satisfied_by_preinstalled_environment(ctx): return PreinstalledNopFetcher() - packages = self.get_required_system_packages(ctx) - package_fetcher = SystemPackageFetcher(build_options, packages) - if package_fetcher.packages_are_installed(): - return package_fetcher + if build_options.host_type.get_package_manager(): + packages = self.get_required_system_packages(ctx) + package_fetcher = SystemPackageFetcher(build_options, packages) + if package_fetcher.packages_are_installed(): + return package_fetcher - repo_url = self.get_repo_url(ctx) if repo_url: rev = self.get("git", "rev") depth = self.get("git", "depth") return GitFetcher(build_options, self, repo_url, rev, depth) - url = self.get("download", "url", ctx=ctx) if url: # We need to defer this import until now to avoid triggering # a cycle when the facebook/__init__.py is loaded. @@ -464,7 +468,8 @@ def _create_fetcher(self, build_options, ctx): ) raise KeyError( - "project %s has no fetcher configuration matching %s" % (self.name, ctx) + "project %s has no fetcher configuration or system packages matching %s" + % (self.name, ctx) ) def create_fetcher(self, build_options, loader, ctx): diff --git a/build/fbcode_builder/manifests/openssl b/build/fbcode_builder/manifests/openssl index beef31c9e2e04..7dd40727cc2e8 100644 --- a/build/fbcode_builder/manifests/openssl +++ b/build/fbcode_builder/manifests/openssl @@ -5,7 +5,7 @@ name = openssl libssl-dev [homebrew] -openssl@1.1 +openssl # on homebrew need the matching curl and ca- [rpms] @@ -16,9 +16,11 @@ openssl-libs [pps] openssl -[download] -url = https://www.openssl.org/source/openssl-1.1.1l.tar.gz -sha256 = 0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1 +# no need to download on the systems where we always use the system libs +[download.not(any(os=linux, os=freebsd))] +# match the openssl version packages in ubuntu LTS folly current supports +url = https://www.openssl.org/source/openssl-3.0.15.tar.gz +sha256 = 23c666d0edf20f14249b3d8f0368acaee9ab585b09e1de82107c66e1f3ec9533 # We use the system openssl on these platforms even without --allow-system-packages [build.any(os=linux, os=freebsd)] @@ -26,7 +28,7 @@ builder = nop [build.not(any(os=linux, os=freebsd))] builder = openssl -subdir = openssl-1.1.1l +subdir = openssl-3.0.15 [dependencies.os=windows] perl From 1ea5864742184b638465b6c0a9ea7eff05c7a010 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Mon, 2 Dec 2024 09:36:05 -0800 Subject: [PATCH 07/12] Updating hashes Summary: GitHub releases: https://github.com/facebook/buck2/releases/tag/2024-12-02 https://github.com/facebookincubator/reindeer/releases/tag/v2024.12.02.00 Reviewed By: ckwalsh fbshipit-source-id: 9d88341c768c286f9c2d1ae4d719fcbdc1e8e2c7 --- buck2 | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/buck2 b/buck2 index 5c84145371963..2d7262c04327f 100755 --- a/buck2 +++ b/buck2 @@ -4,62 +4,62 @@ "name": "buck2", "platforms": { "macos-aarch64": { - "size": 24793637, + "size": 24804372, "hash": "blake3", - "digest": "bb0035bb305bf3b6bb381b2c98063ab0912f77fcb3603a891cac4c59d17b2795", + "digest": "09468dd3a7114a853b84bd6befa2ab2dc101ca612435a3f6104a3206ad8ae4be", "format": "zst", "path": "buck2-aarch64-apple-darwin", "providers": [ { - "url": "https://github.com/facebook/buck2/releases/download/2024-11-15/buck2-aarch64-apple-darwin.zst" + "url": "https://github.com/facebook/buck2/releases/download/2024-12-02/buck2-aarch64-apple-darwin.zst" } ] }, "linux-aarch64": { - "size": 27097669, + "size": 27118699, "hash": "blake3", - "digest": "70c796a8e7470a497d6251963c1d9da1679266f4ba1fdbf44a252aeac1687d8c", + "digest": "de2c4c710767206a3441d54ea5b99c35cd18c49a5e13e280f9f0e14d2130d1f0", "format": "zst", "path": "buck2-aarch64-unknown-linux-musl", "providers": [ { - "url": "https://github.com/facebook/buck2/releases/download/2024-11-15/buck2-aarch64-unknown-linux-musl.zst" + "url": "https://github.com/facebook/buck2/releases/download/2024-12-02/buck2-aarch64-unknown-linux-musl.zst" } ] }, "macos-x86_64": { - "size": 26566564, + "size": 26609760, "hash": "blake3", - "digest": "f2d32397d72a0f3d96dd3265a525a9264ecc5aacc01c9f53ef1be7864f792c6c", + "digest": "e0f19c1ad37b9a00e9f5cc4143bec852fdbcdb063dc410fbcb3e99b4b3f383b6", "format": "zst", "path": "buck2-x86_64-apple-darwin", "providers": [ { - "url": "https://github.com/facebook/buck2/releases/download/2024-11-15/buck2-x86_64-apple-darwin.zst" + "url": "https://github.com/facebook/buck2/releases/download/2024-12-02/buck2-x86_64-apple-darwin.zst" } ] }, "windows-x86_64": { - "size": 21945285, + "size": 22070302, "hash": "blake3", - "digest": "e0ebb882535cc24439025b39a023ae2148fc9f4733ab3552dbce396f964dd549", + "digest": "be0abcf7746d803da8fd02e011db156dbda100dda281b8445faf6415827c8fe3", "format": "zst", "path": "buck2-x86_64-pc-windows-msvc.exe", "providers": [ { - "url": "https://github.com/facebook/buck2/releases/download/2024-11-15/buck2-x86_64-pc-windows-msvc.exe.zst" + "url": "https://github.com/facebook/buck2/releases/download/2024-12-02/buck2-x86_64-pc-windows-msvc.exe.zst" } ] }, "linux-x86_64": { - "size": 28049273, + "size": 28064232, "hash": "blake3", - "digest": "4ce1ccad2e051ac169d165905de2e3de68558a74e90756c71ab04fa78e38d23b", + "digest": "698197b24d042e2c38a253c92fe6b59ed09145200234dffe27cc5011913dd815", "format": "zst", "path": "buck2-x86_64-unknown-linux-musl", "providers": [ { - "url": "https://github.com/facebook/buck2/releases/download/2024-11-15/buck2-x86_64-unknown-linux-musl.zst" + "url": "https://github.com/facebook/buck2/releases/download/2024-12-02/buck2-x86_64-unknown-linux-musl.zst" } ] } From acc9c278822305b11d22a54d413fbd8322d2abc1 Mon Sep 17 00:00:00 2001 From: Ron He Date: Mon, 2 Dec 2024 09:39:27 -0800 Subject: [PATCH 08/12] Process Port config for SHEL enable Summary: As titled. Also ensure that we have corresponding ShelConfig on switch level Reviewed By: jasmeetbagga Differential Revision: D66113178 fbshipit-source-id: 468fa60b0f228544b2b59c5e7f20c810e5bc072f --- fboss/agent/ApplyThriftConfig.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fboss/agent/ApplyThriftConfig.cpp b/fboss/agent/ApplyThriftConfig.cpp index 34ad9a53e24d7..b0cfcf909037f 100644 --- a/fboss/agent/ApplyThriftConfig.cpp +++ b/fboss/agent/ApplyThriftConfig.cpp @@ -2505,7 +2505,9 @@ shared_ptr ThriftConfigApplier::updatePort( portFlowletConfigUnchanged && newFlowletConfigName == orig->getFlowletConfigName() && *portConf->conditionalEntropyRehash() == - orig->getConditionalEntropyRehash()) { + orig->getConditionalEntropyRehash() && + portConf->selfHealingECMPLagEnable().value_or(false) == + orig->getSelfHealingECMPLagEnable()) { return nullptr; } @@ -2549,6 +2551,16 @@ shared_ptr ThriftConfigApplier::updatePort( newPort->setPortFlowletConfig(portFlowletCfg); newPort->setScope(*portConf->scope()); newPort->setConditionalEntropyRehash(*portConf->conditionalEntropyRehash()); + if (auto selfHealingECMPLagEnable = portConf->selfHealingECMPLagEnable()) { + if (*selfHealingECMPLagEnable && + !cfg_->switchSettings()->selfHealingEcmpLagConfig().has_value()) { + throw FbossError( + "Switch selfHealingEcmpLagConfig needs to be enabled for port ", + newPort->getName(), + " to have selfHealingEcmpLag enable"); + } + newPort->setSelfHealingECMPLagEnable(*selfHealingECMPLagEnable); + } return newPort; } From 30e626044564e5f44aea166a6dc4c376adade5da Mon Sep 17 00:00:00 2001 From: Ron He Date: Mon, 2 Dec 2024 09:39:27 -0800 Subject: [PATCH 09/12] Process Shel config change for switch settings Summary: As titled. Update switch state accordingly Reviewed By: jasmeetbagga Differential Revision: D66124055 fbshipit-source-id: d5f0faff7e38f1444257913d5d048210397a7212 --- fboss/agent/ApplyThriftConfig.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fboss/agent/ApplyThriftConfig.cpp b/fboss/agent/ApplyThriftConfig.cpp index b0cfcf909037f..ddbe445173d32 100644 --- a/fboss/agent/ApplyThriftConfig.cpp +++ b/fboss/agent/ApplyThriftConfig.cpp @@ -4850,6 +4850,19 @@ shared_ptr ThriftConfigApplier::updateSwitchSettings( switchSettingsChange = true; } + { + // SelfHealingEcmpLag switch configurations + std::optional newSwitchShelConfig; + if (cfg_->switchSettings()->selfHealingEcmpLagConfig()) { + newSwitchShelConfig = *cfg_->switchSettings()->selfHealingEcmpLagConfig(); + } + if (newSwitchShelConfig != + origSwitchSettings->getSelfHealingEcmpLagConfig()) { + newSwitchSettings->setSelfHealingEcmpLagConfig(newSwitchShelConfig); + switchSettingsChange = true; + } + } + if (switchSettingsChange) { return newSwitchSettings; } From 10db0038decfae55ad8450ab2ded1762233aea8a Mon Sep 17 00:00:00 2001 From: Ron He Date: Mon, 2 Dec 2024 09:39:27 -0800 Subject: [PATCH 10/12] Remove duplicate handling for reachability group Summary: As titled. This is already handled on line 1524 Reviewed By: jasmeetbagga Differential Revision: D66133822 fbshipit-source-id: c2dbd4d0f9137c7acda05493dc2e6c4a16d7e0ad --- fboss/agent/hw/sai/switch/SaiPortManager.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fboss/agent/hw/sai/switch/SaiPortManager.cpp b/fboss/agent/hw/sai/switch/SaiPortManager.cpp index a10319c429bcf..f07a5d9d4aaf5 100644 --- a/fboss/agent/hw/sai/switch/SaiPortManager.cpp +++ b/fboss/agent/hw/sai/switch/SaiPortManager.cpp @@ -1526,11 +1526,6 @@ std::shared_ptr SaiPortManager::swPortFromAttributes( #endif port->setScope(platform_->getPlatformMapping()->getPortScope(port->getID())); -// TODO(zecheng): Update flag when new 12.0 release has the attribute -#if defined(BRCM_SAI_SDK_DNX_GTE_11_0) && !defined(BRCM_SAI_SDK_DNX_GTE_12_0) - port->setReachabilityGroupId( - GET_OPT_ATTR(Port, CondEntropyRehashEnable, attributes)); -#endif return port; } From b2a3e80debea2d4e4572525247aab6a539451d00 Mon Sep 17 00:00:00 2001 From: Ron He Date: Mon, 2 Dec 2024 09:39:27 -0800 Subject: [PATCH 11/12] Set Port shel enable based on switch state Summary: As titled. Reviewed By: jasmeetbagga Differential Revision: D66133836 fbshipit-source-id: 15088b9e4a69a3797c7b86794bc2f8608bf4a951 --- fboss/agent/hw/sai/switch/SaiPortManager.cpp | 5 +++++ fboss/agent/hw/sai/switch/npu/SaiPortManager.cpp | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fboss/agent/hw/sai/switch/SaiPortManager.cpp b/fboss/agent/hw/sai/switch/SaiPortManager.cpp index f07a5d9d4aaf5..303458e70a528 100644 --- a/fboss/agent/hw/sai/switch/SaiPortManager.cpp +++ b/fboss/agent/hw/sai/switch/SaiPortManager.cpp @@ -1526,6 +1526,11 @@ std::shared_ptr SaiPortManager::swPortFromAttributes( #endif port->setScope(platform_->getPlatformMapping()->getPortScope(port->getID())); +#if defined(SAI_VERSION_11_7_0_0_DNX_ODP) + auto shelEnable = GET_OPT_ATTR(Port, ShelEnable, attributes); + port->setSelfHealingECMPLagEnable(shelEnable); +#endif + return port; } diff --git a/fboss/agent/hw/sai/switch/npu/SaiPortManager.cpp b/fboss/agent/hw/sai/switch/npu/SaiPortManager.cpp index d31874efcbc72..25c77be775879 100644 --- a/fboss/agent/hw/sai/switch/npu/SaiPortManager.cpp +++ b/fboss/agent/hw/sai/switch/npu/SaiPortManager.cpp @@ -661,6 +661,11 @@ SaiPortTraits::CreateAttributes SaiPortManager::attributesFromSwPort( #if defined(BRCM_SAI_SDK_DNX_GTE_11_0) && !defined(BRCM_SAI_SDK_DNX_GTE_12_0) condEntropyRehashEnable = swPort->getConditionalEntropyRehash(); #endif + std::optional shelEnable{}; +#if defined(SAI_VERSION_11_7_0_0_DNX_ODP) + shelEnable = SaiPortTraits::Attributes::ShelEnable{ + swPort->getSelfHealingECMPLagEnable()}; +#endif if (basicAttributeOnly) { return SaiPortTraits::CreateAttributes{ @@ -799,10 +804,10 @@ SaiPortTraits::CreateAttributes SaiPortManager::attributesFromSwPort( arsPortLoadFutureWeight, // ARS port load future weight #endif reachabilityGroup, - condEntropyRehashEnable, // CondEntropyRehashEnable + condEntropyRehashEnable, std::nullopt, // CondEntropyRehashPeriodUS std::nullopt, // CondEntropyRehashSeed - std::nullopt, // ShelEnable + shelEnable, }; } From e8d02f51addd6a4df03eb4c63a6b55d53dd3dcd9 Mon Sep 17 00:00:00 2001 From: Scott J Paulsen Date: Sun, 1 Dec 2024 20:25:22 -0800 Subject: [PATCH 12/12] PSU Presence detection in platform manager for morgan800cc --- .../configs/morgan800cc/platform_manager.json | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/fboss/platform/configs/morgan800cc/platform_manager.json b/fboss/platform/configs/morgan800cc/platform_manager.json index 993eafe9118bc..6d31d6b45f45a 100644 --- a/fboss/platform/configs/morgan800cc/platform_manager.json +++ b/fboss/platform/configs/morgan800cc/platform_manager.json @@ -434,13 +434,27 @@ "slotType": "PSU_SLOT", "outgoingI2cBusNames": [ "MCB_IOB_I2C_MASTER_1" - ] + ], + "presenceDetection": { + "gpioLineHandle": { + "devicePath": "/[MCB_MCB_GPIO]", + "ineIndex": 48, + "desiredValue": 1 + } + } }, "PSU_SLOT@1": { "slotType": "PSU_SLOT", "outgoingI2cBusNames": [ "MCB_IOB_I2C_MASTER_2" - ] + ], + "presenceDetection": { + "gpioLineHandle": { + "devicePath": "/[MCB_MCB_GPIO]", + "lineIndex": 52, + "desiredValue": 1 + } + } }, "FCB_SLOT@0": { "slotType": "FCB_SLOT",