diff --git a/fboss/agent/AclNexthopHandler.cpp b/fboss/agent/AclNexthopHandler.cpp index 6f2266bf0965c..51790c5dbcb6e 100644 --- a/fboss/agent/AclNexthopHandler.cpp +++ b/fboss/agent/AclNexthopHandler.cpp @@ -124,23 +124,27 @@ AclEntry* FOLLY_NULLABLE AclNexthopHandler::updateAcl( const auto& origAclAction = origAclEntry->getAclAction(); if (origAclAction && origAclAction->cref()) { - // Tunnel encap nexthops are resolved by the HW pipeline via a second - // routing lookup on the outer header, so they don't need RIB resolution. + // Tunnel encap and SRv6 encap nexthops are resolved by the HW pipeline; + // they do not need RIB resolution. auto redirectAction = origAclAction->cref() ->cref(); auto redirectNhops = redirectAction->cref(); - bool allTunnelEncap = !redirectNhops->empty(); + bool allTunnelRedirect = !redirectNhops->empty(); for (const auto& nh : std::as_const(*redirectNhops)) { const auto& tunnelType = nh->cref(); - if (!tunnelType.has_value() || - tunnelType->toThrift() != TunnelType::IP_IN_IP_ENCAP) { - allTunnelEncap = false; + if (!tunnelType.has_value()) { + allTunnelRedirect = false; + break; + } + auto tt = tunnelType->toThrift(); + if (tt != TunnelType::IP_IN_IP_ENCAP && tt != TunnelType::SRV6_ENCAP) { + allTunnelRedirect = false; break; } } - if (allTunnelEncap) { + if (allTunnelRedirect) { return nullptr; } diff --git a/fboss/agent/ApplyThriftConfig.cpp b/fboss/agent/ApplyThriftConfig.cpp index 1c487a6e428ca..14e9141378a47 100644 --- a/fboss/agent/ApplyThriftConfig.cpp +++ b/fboss/agent/ApplyThriftConfig.cpp @@ -4133,7 +4133,8 @@ std::shared_ptr ThriftConfigApplier::updateAclsImpl( bool hasTunnelRedirect = false; for (const auto& nh : *redirectToNextHop->redirectNextHops()) { if (nh.tunnelType().has_value() && - nh.tunnelType().value() == TunnelType::IP_IN_IP_ENCAP) { + (nh.tunnelType().value() == TunnelType::IP_IN_IP_ENCAP || + nh.tunnelType().value() == TunnelType::SRV6_ENCAP)) { hasTunnelRedirect = true; break; } @@ -4406,6 +4407,12 @@ shared_ptr ThriftConfigApplier::createAcl( if (auto dscp = config->dscp()) { newAcl->setDscp(*dscp); } + if (auto tc = config->tc()) { + newAcl->setTrafficClass(*tc); + } + if (auto routeDst = config->routeDst()) { + newAcl->setRouteDst(*routeDst); + } if (auto dstMac = config->dstMac()) { newAcl->setDstMac(MacAddress(*dstMac)); } diff --git a/fboss/agent/ThriftHandler.cpp b/fboss/agent/ThriftHandler.cpp index 5593357b82e2d..ed9336dd4160f 100644 --- a/fboss/agent/ThriftHandler.cpp +++ b/fboss/agent/ThriftHandler.cpp @@ -548,6 +548,9 @@ AclEntryThrift populateAclEntryThrift(const AclEntry& aclEntry) { if (aclEntry.getDscp()) { aclEntryThrift.dscp() = aclEntry.getDscp().value(); } + if (aclEntry.getTrafficClass()) { + aclEntryThrift.tc() = aclEntry.getTrafficClass().value(); + } if (aclEntry.getTtl()) { aclEntryThrift.ttl() = aclEntry.getTtl().value().getValue(); } @@ -3113,6 +3116,32 @@ void ThriftHandler::setSdkRegDumpEnabled(bool enabled) { } } +void ThriftHandler::setSdkRegDumpEnabled(bool enabled) { + auto log = LOG_THRIFT_CALL_WITH_STATS(DBG1, sw_->stats()); + ensureConfigured(__func__); + if (sw_->isRunModeMonolithic()) { + sw_->getMonolithicHwSwitchHandler()->setSdkRegDumpEnabled(enabled); + return; + } + // Multi-switch: apply to every switch best-effort so that one unsupported or + // unreachable switch does not prevent updating the others. Collect failures + // and surface them together. + std::string failures; + for (const auto& switchId : sw_->getSwitchInfoTable().getSwitchIDs()) { + try { + sw_->getHwSwitchThriftClientTable()->setSdkRegDumpEnabled( + switchId, enabled); + } catch (const std::exception& ex) { + failures += folly::to( + failures.empty() ? "" : "; ", switchId, ": ", ex.what()); + } + } + if (!failures.empty()) { + throw FbossError( + "Failed to set SDK register dump on switch(es): ", failures); + } +} + void ThriftHandler::getPlatformMapping(cfg::PlatformMapping& ret) { ret = sw_->getPlatformMapping()->toThrift(); } diff --git a/fboss/agent/hw/benchmarks/HwSrv6PbrCounterScaleBenchmark.cpp b/fboss/agent/hw/benchmarks/HwSrv6PbrCounterScaleBenchmark.cpp new file mode 100644 index 0000000000000..2fa68245d8c30 --- /dev/null +++ b/fboss/agent/hw/benchmarks/HwSrv6PbrCounterScaleBenchmark.cpp @@ -0,0 +1,523 @@ +// +// HwSrv6PbrCounterScaleBenchmark.cpp +// +// SRv6 PBR per-ACE packet+byte counter scale benchmarks on Cisco Silicon One. +// Programs 448 copies of one ACE shape (RedirectToSrv6BumpsPacketAndByteCounter +// gold tier): TC + ROUTE_DST match, shared gold routeDst per bucket, gold SRv6 +// redirect, per-ACE counter. TC cycles 0-7; routeDst bucket every 8 ACEs (56 +// NHGs for 448 unique keys). GR2 ingress RTF TCAM is split IPv4/IPv6; IPv6 half +// is 448 lines (896 total). +// +// HwSrv6PbrCounterScaleBenchmark_Configure -- times applyNewConfig() for 448 +// ACEs. HwSrv6PbrCounterScaleBenchmark_Read -- times ACL-only stat poll +// (448 SAI byte counter reads) + +// reading byte counters from the +// ACL stats cache (install is +// untimed). + +#include + +#include +#include +#include +#include +#include + +#include "fboss/agent/AddressUtil.h" +#include "fboss/agent/AgentFeatures.h" +#include "fboss/agent/SwSwitch.h" +#include "fboss/agent/SwSwitchRouteUpdateWrapper.h" +#include "fboss/agent/gen-cpp2/switch_config_types.h" +#include "fboss/agent/hw/sai/switch/SaiSwitch.h" +#include "fboss/agent/if/gen-cpp2/ctrl_types.h" +#include "fboss/agent/rib/RoutingInformationBase.h" +#include "fboss/agent/single/MonolithicHwSwitchHandler.h" +#include "fboss/agent/state/RouteNextHop.h" +#include "fboss/agent/test/AgentEnsemble.h" +#include "fboss/agent/test/EcmpSetupHelper.h" +#include "fboss/agent/test/TestUtils.h" +#include "fboss/agent/test/utils/AclTestUtils.h" +#include "fboss/agent/test/utils/ConfigUtils.h" + +DECLARE_bool(enable_acl_table_group); + +namespace facebook::fboss { + +namespace { + +constexpr int kAcePrefixLen = 128; +// Ingress IPv6 ACL table capacity on Yuba / GR2 (448 entries; 896 total TCAM +// split evenly between IPv4 and IPv6 RTF tables). +constexpr int kMaxIngressIpv6AclEntries = 448; +// SAI FIELD_TC is 4-bit (values 0-7); see sai_acl_key.cpp. +constexpr int kMaxPbrTc = 8; +constexpr int kMaxRouteDstNhGroups = + (kMaxIngressIpv6AclEntries + kMaxPbrTc - 1) / kMaxPbrTc; + +constexpr char kTunnelId[] = "srv6PbrScaleTunnel0"; +constexpr char kEncapSrcIp[] = "2401:db00::1"; +constexpr char kQosPolicyName[] = "srv6_pbr_scale_qos"; +constexpr char kPbrAclTableName[] = "Srv6PbrAclTable"; +constexpr char kScaleRouteDstNhgName[] = "scaleRouteDstNhg"; +constexpr char kScaleRedirectNhgName[] = "scaleRedirectNhg"; +// AgentSrv6PbrCounterTest gold tier (RedirectToSrv6BumpsPacketAndByteCounter). +constexpr char kGoldRouteSid[] = "bbbb:b1b1:51:52:53:54:55:56"; +constexpr uint8_t kGoldTierTc = 1; +constexpr uint8_t kGoldTierDscp = 10; +constexpr char kScaleRouteV6Dst[] = "2001:db8:ca5e::1"; +constexpr uint8_t kScaleRouteV6PrefixLen = 128; + +#if defined(TAJO_SDK) +constexpr bool kUseSrv6PbrTcRouteDstPath = true; +#else +constexpr bool kUseSrv6PbrTcRouteDstPath = false; +#endif + +folly::IPAddressV6 makePbrAceMatchDip(int aceIdx) { + return folly::IPAddressV6(fmt::format("2001:db8:{:x}::1", aceIdx + 1)); +} + +// Bucket 0 uses agent gold uSID; higher buckets uniquify routeDst for scale. +std::string makeScaleRouteDstSid(int routeDstBucket) { + if (routeDstBucket == 0) { + return kGoldRouteSid; + } + return fmt::format( + "bbbb:b1b1:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", + 0x50 + (routeDstBucket & 0xff), + (routeDstBucket >> 8) & 0xff, + (routeDstBucket + 1) & 0xff, + (routeDstBucket + 2) & 0xff, + (routeDstBucket + 3) & 0xff, + (routeDstBucket + 4) & 0xff); +} + +std::string scaleRouteDstNhgName(int routeDstBucket) { + if (routeDstBucket == 0) { + return kScaleRouteDstNhgName; + } + return fmt::format("scaleRouteDstNhg_{}", routeDstBucket); +} + +void enableSrv6PbrBenchmarkFlags() { + FLAGS_enable_acl_table_group = true; +#if defined(TAJO_SDK) + FLAGS_enable_nexthop_id_manager = true; + FLAGS_resolve_nexthops_from_id = true; +#endif +} + +void addSrv6EncapTunnelConfig(cfg::SwitchConfig& cfg) { + cfg::Srv6Tunnel tunnel; + tunnel.srv6TunnelId() = kTunnelId; + tunnel.underlayIntfID() = *cfg.interfaces()[0].intfID(); + tunnel.tunnelType() = TunnelType::SRV6_ENCAP; + tunnel.srcIp() = kEncapSrcIp; + tunnel.ttlMode() = cfg::TunnelMode::UNIFORM; + tunnel.dscpMode() = cfg::TunnelMode::UNIFORM; + tunnel.ecnMode() = cfg::TunnelMode::UNIFORM; + cfg.srv6Tunnels() = {tunnel}; +} + +void addScaleDscpToTcQosMap(cfg::SwitchConfig& cfg) { + cfg::QosMap qosMap; + qosMap.dscpMaps()->resize(1); + qosMap.dscpMaps()[0].internalTrafficClass() = kGoldTierTc; + qosMap.dscpMaps()[0].fromDscpToTrafficClass()->push_back(kGoldTierDscp); + qosMap.trafficClassToQueueId()->emplace(kGoldTierTc, 0); + + cfg.qosPolicies()->resize(1); + cfg.qosPolicies()[0].name() = kQosPolicyName; + cfg.qosPolicies()[0].qosMap() = qosMap; + + if (!cfg.dataPlaneTrafficPolicy().has_value()) { + cfg.dataPlaneTrafficPolicy() = cfg::TrafficPolicyConfig(); + } + cfg.dataPlaneTrafficPolicy()->defaultQosPolicy() = kQosPolicyName; +} + +void addSrv6PbrAclTable(cfg::SwitchConfig& cfg) { + if (!FLAGS_enable_acl_table_group) { + return; + } + if (utility::getAclTable(cfg, cfg::AclStage::INGRESS, kPbrAclTableName)) { + return; + } + utility::addAclTable( + &cfg, + cfg::AclStage::INGRESS, + kPbrAclTableName, + 1 /* priority */, + { + cfg::AclTableActionType::COUNTER, + cfg::AclTableActionType::REDIRECT, + }, + { + cfg::AclTableQualifier::TC, + cfg::AclTableQualifier::ROUTE_DST, + }, + {}); +} + +cfg::RedirectNextHop makeSrv6RedirectNh( + const cfg::SwitchConfig& cfg, + const folly::IPAddress& underlayNhIp, + const std::string& sid) { + cfg::RedirectNextHop nh; + nh.ip() = underlayNhIp.str(); + nh.intfID() = *cfg.interfaces()[0].intfID(); + nh.tunnelType() = TunnelType::SRV6_ENCAP; + nh.tunnelId() = kTunnelId; + nh.srv6SegmentList() = {sid}; + return nh; +} + +AgentEnsembleSwitchConfigFn makePbrConfigFn() { + return [](const AgentEnsemble& ensemble) { + auto cfg = utility::onePortPerInterfaceConfig( + ensemble.getSw(), + ensemble.masterLogicalPortIds(), + true /*interfaceHasSubnet*/); + if (kUseSrv6PbrTcRouteDstPath) { + addSrv6EncapTunnelConfig(cfg); + addScaleDscpToTcQosMap(cfg); + } + return cfg; + }; +} + +struct PbrAceNames { + std::string ace; + std::string counter; +}; + +PbrAceNames makeAceNames(int aceIdx) { + return { + fmt::format("srv6_pbr_ace_{}", aceIdx), + fmt::format("srv6_pbr_ctr_{}", aceIdx), + }; +} + +void appendPbrAceDscpDstIpFallback( + cfg::SwitchConfig& cfg, + int aceIdx, + const folly::IPAddressV6& redirectNh, + const std::vector& counterTypes) { + const auto names = makeAceNames(aceIdx); + + cfg::AclEntry ace; + ace.name() = names.ace; + ace.dscp() = static_cast(aceIdx % 64); + ace.dstIp() = + fmt::format("{}/{}", makePbrAceMatchDip(aceIdx).str(), kAcePrefixLen); + utility::addAcl(&cfg, ace, cfg::AclStage::INGRESS); + + utility::addTrafficCounter(&cfg, names.counter, counterTypes); + + cfg::RedirectToNextHopAction redirect; + cfg::RedirectNextHop rnh; + rnh.ip() = redirectNh.str(); + + cfg::MatchAction matchAction; + matchAction.redirectToNextHop() = redirect; + matchAction.counter() = names.counter; + + utility::addMatcher(&cfg, names.ace, matchAction); +} + +// One ACE template (agent gold tier): TC + routeDst + gold SRv6 redirect + +// counter. aceIdx only varies TC (0-7) and routeDst bucket for unique keys. +void appendPbrAceTcRouteDstSrv6( + cfg::SwitchConfig& cfg, + int aceIdx, + const folly::IPAddress& underlayNhIp, + const cfg::RedirectNextHop& goldRedirectNh, + const std::vector& counterTypes) { + const auto names = makeAceNames(aceIdx); + const int routeDstBucket = aceIdx / kMaxPbrTc; + + cfg::AclEntry ace; + ace.name() = names.ace; + ace.tc() = static_cast(aceIdx % kMaxPbrTc); + ace.routeDst() = makeSrv6RedirectNh( + cfg, underlayNhIp, makeScaleRouteDstSid(routeDstBucket)); + utility::addAclEntry(&cfg, ace, kPbrAclTableName, cfg::AclStage::INGRESS); + + utility::addTrafficCounter(&cfg, names.counter, counterTypes); + + cfg::RedirectToNextHopAction redirect; + redirect.redirectNextHops() = {goldRedirectNh}; + + cfg::MatchAction matchAction; + matchAction.redirectToNextHop() = redirect; + matchAction.counter() = names.counter; + + cfg::MatchToAction mta; + mta.matcher() = names.ace; + mta.action() = matchAction; + if (!cfg.dataPlaneTrafficPolicy().has_value()) { + cfg.dataPlaneTrafficPolicy() = cfg::TrafficPolicyConfig(); + } + cfg.dataPlaneTrafficPolicy()->matchToAction()->push_back(mta); +} + +struct PbrScaleEnsemble { + std::unique_ptr ensemble; + SwSwitch* sw{nullptr}; + folly::IPAddress underlayNhIp; + cfg::RedirectNextHop goldRedirectNh; +}; + +RouteNextHopSet makeSrv6NhopSet( + const utility::EcmpSetupAnyNPorts6& ecmpHelper, + const folly::IPAddress& underlayNhIp, + const std::string& sid) { + const auto nhop = ecmpHelper.nhop(0); + CHECK(nhop.linkLocalNhopIp.has_value()); + const folly::IPAddressV6 srv6Sid(sid); + + RouteNextHopSet nhops; + nhops.insert(ResolvedNextHop( + underlayNhIp, + nhop.intf, + ECMP_WEIGHT, + std::nullopt, + std::nullopt, + std::nullopt, + std::nullopt, + std::vector{srv6Sid}, + TunnelType::SRV6_ENCAP, + kTunnelId)); + return nhops; +} + +void programScaleSrv6NhgsAndRoute( + PbrScaleEnsemble& ctx, + const utility::EcmpSetupAnyNPorts6& ecmpHelper) { + std::vector> groups; + groups.reserve(kMaxRouteDstNhGroups + 1); + for (int i = 0; i < kMaxRouteDstNhGroups; ++i) { + groups.emplace_back( + scaleRouteDstNhgName(i), + makeSrv6NhopSet(ecmpHelper, ctx.underlayNhIp, makeScaleRouteDstSid(i))); + } + groups.emplace_back( + kScaleRedirectNhgName, + makeSrv6NhopSet(ecmpHelper, ctx.underlayNhIp, kGoldRouteSid)); + + auto rib = ctx.sw->getRib(); + rib->addOrUpdateNamedNextHopGroups( + ctx.sw->getScopeResolver(), + groups, + createRibToSwitchStateFunction(), + ctx.sw); + + UnicastRoute route; + route.dest()->ip() = + facebook::network::toBinaryAddress(folly::IPAddress(kScaleRouteV6Dst)); + route.dest()->prefixLength() = kScaleRouteV6PrefixLen; + NamedRouteDestination namedDest; + namedDest.nextHopGroup_ref() = kScaleRouteDstNhgName; + route.namedRouteDestination() = namedDest; + route.counterID() = kScaleRouteDstNhgName; + + auto routeUpdater = ctx.sw->getRouteUpdater(); + routeUpdater.addRoute(RouterID(0), ClientID::TE_AGENT, route); + routeUpdater.program(); + waitForStateUpdates(ctx.sw); +} + +PbrScaleEnsemble setupPbrScaleEnsemble() { + enableSrv6PbrBenchmarkFlags(); + + PbrScaleEnsemble ctx; + ctx.ensemble = + createAgentEnsemble(makePbrConfigFn(), false /*disableLinkStateToggler*/); + ctx.sw = ctx.ensemble->getSw(); + + utility::EcmpSetupAnyNPorts6 ecmpHelper( + ctx.sw->getState(), ctx.sw->needL2EntryForNeighbor()); + + ctx.ensemble->applyNewState([&](const std::shared_ptr& in) { + return ecmpHelper.resolveNextHops(in, 1, true /*useLinkLocal*/); + }); + + auto routeUpdater = ctx.sw->getRouteUpdater(); + ecmpHelper.programRoutes(&routeUpdater, 1); + + const auto& nhop = ecmpHelper.nhop(0); + CHECK(nhop.linkLocalNhopIp.has_value()); + ctx.underlayNhIp = folly::IPAddress(*nhop.linkLocalNhopIp); + + if (kUseSrv6PbrTcRouteDstPath) { + programScaleSrv6NhgsAndRoute(ctx, ecmpHelper); + auto cfg = ctx.sw->getConfig(); + ctx.goldRedirectNh = + makeSrv6RedirectNh(cfg, ctx.underlayNhIp, kGoldRouteSid); + } + + return ctx; +} + +const std::vector kPacketAndByteCounterTypes{ + cfg::CounterType::PACKETS, + cfg::CounterType::BYTES}; +const std::vector kBytesOnlyCounterTypes{ + cfg::CounterType::BYTES}; + +cfg::SwitchConfig buildPbrAceConfig( + const PbrScaleEnsemble& ctx, + int numEntries, + const std::vector& counterTypes = + kPacketAndByteCounterTypes) { + auto cfg = ctx.sw->getConfig(); + if (kUseSrv6PbrTcRouteDstPath) { + addSrv6PbrAclTable(cfg); + for (int i = 0; i < numEntries; ++i) { + appendPbrAceTcRouteDstSrv6( + cfg, i, ctx.underlayNhIp, ctx.goldRedirectNh, counterTypes); + } + } else { + utility::EcmpSetupAnyNPorts6 ecmpHelper( + ctx.sw->getState(), ctx.sw->needL2EntryForNeighbor()); + for (int i = 0; i < numEntries; ++i) { + appendPbrAceDscpDstIpFallback( + cfg, i, ecmpHelper.nhop(0).ip, counterTypes); + } + } + return cfg; +} + +void cleanupPbrAces(PbrScaleEnsemble& ctx, int numEntries) { + auto cleanCfg = ctx.sw->getConfig(); + const std::optional tableName = kUseSrv6PbrTcRouteDstPath + ? std::optional(kPbrAclTableName) + : std::nullopt; + + for (int i = 0; i < numEntries; ++i) { + const auto names = makeAceNames(i); + utility::delAclStat(&cleanCfg, names.ace, names.counter); + if (kUseSrv6PbrTcRouteDstPath) { + auto& mta = *cleanCfg.dataPlaneTrafficPolicy()->matchToAction(); + mta.erase( + std::remove_if( + mta.begin(), + mta.end(), + [&](const cfg::MatchToAction& entry) { + return *entry.matcher() == names.ace; + }), + mta.end()); + } else { + utility::delMatcher(&cleanCfg, names.ace); + } + utility::delAcl(&cleanCfg, names.ace, tableName); + } + ctx.ensemble->applyNewConfig(cleanCfg); + waitForStateUpdates(ctx.sw); +} + +struct PbrScalePreparedRun { + PbrScaleEnsemble ctx; + cfg::SwitchConfig aceCfg; + std::vector counterNames; +}; + +PbrScalePreparedRun preparePbrScaleRun(int numEntries) { + PbrScalePreparedRun run; + run.ctx = setupPbrScaleEnsemble(); + run.aceCfg = buildPbrAceConfig(run.ctx, numEntries); + run.counterNames.reserve(numEntries); + for (int i = 0; i < numEntries; ++i) { + run.counterNames.push_back(makeAceNames(i).counter); + } + return run; +} + +void logPbrAceProgramming(int numEntries) { + XLOG(INFO) << "HwSrv6PbrCounterScaleBenchmark: programming " << numEntries + << " ACEs (path=" + << (kUseSrv6PbrTcRouteDstPath ? "TC+ROUTE_DST+SRV6" : "DSCP+dstIp") + << ")"; +} + +void programPbrAcesUntimed(PbrScalePreparedRun& run) { + logPbrAceProgramming(static_cast(run.counterNames.size())); + run.ctx.ensemble->applyNewConfig(run.aceCfg); + waitForStateUpdates(run.ctx.sw); +} + +void updatePbrAclStatsOnly(SwSwitch* sw) { + auto* monoHandler = sw->getMonolithicHwSwitchHandler(); + auto* saiSwitch = static_cast(monoHandler->getHwSwitch()); + saiSwitch->updateAclStats(); +} + +uint64_t sumAclByteCounters( + const AclStats& aclStats, + const std::vector& counterNames) { + uint64_t totalBytes = 0; + const auto& counterMap = *aclStats.statNameToCounterMap(); + for (const auto& counterName : counterNames) { + const auto statStr = counterName + ".bytes"; + const auto entry = counterMap.find(statStr); + if (entry != counterMap.end()) { + totalBytes += entry->second; + } + } + return totalBytes; +} + +void srv6PbrCounterConfigureScaleBenchmark(int numEntries) { + folly::BenchmarkSuspender suspender; + + auto run = preparePbrScaleRun(numEntries); + + suspender.dismiss(); + programPbrAcesUntimed(run); + suspender.rehire(); + + cleanupPbrAces(run.ctx, numEntries); +} + +void srv6PbrCounterReadScaleBenchmark(int numEntries) { + folly::BenchmarkSuspender suspender; + + // Untimed: ensemble, NHGs, route, ACE config build, and hardware programming. + // Byte-only counters so ACL stat poll issues one SAI read per ACE. + auto ctx = setupPbrScaleEnsemble(); + auto aceCfg = buildPbrAceConfig(ctx, numEntries, kBytesOnlyCounterTypes); + logPbrAceProgramming(numEntries); + ctx.ensemble->applyNewConfig(aceCfg); + waitForStateUpdates(ctx.sw); + + std::vector counterNames; + counterNames.reserve(numEntries); + for (int i = 0; i < numEntries; ++i) { + counterNames.push_back(makeAceNames(i).counter); + } + + // Timed: ACL-only SAI/SDK poll + byte counter reads from ACL stats cache. + suspender.dismiss(); + updatePbrAclStatsOnly(ctx.sw); + const auto aclStats = ctx.sw->getMonolithicHwSwitchHandler()->getAclStats(); + const uint64_t totalBytes = sumAclByteCounters(aclStats, counterNames); + folly::doNotOptimizeAway(totalBytes); + suspender.rehire(); + + XLOG(INFO) << "HwSrv6PbrCounterScaleBenchmark Read: polled " << numEntries + << " byte counters"; + + cleanupPbrAces(ctx, numEntries); +} + +BENCHMARK(HwSrv6PbrCounterScaleBenchmark_Configure) { + srv6PbrCounterConfigureScaleBenchmark(kMaxIngressIpv6AclEntries); +} + +BENCHMARK(HwSrv6PbrCounterScaleBenchmark_Read) { + srv6PbrCounterReadScaleBenchmark(kMaxIngressIpv6AclEntries); +} + +} // namespace + +} // namespace facebook::fboss diff --git a/fboss/agent/hw/sai/api/AclApi.h b/fboss/agent/hw/sai/api/AclApi.h index b6ebf386080b3..d4327f163977c 100644 --- a/fboss/agent/hw/sai/api/AclApi.h +++ b/fboss/agent/hw/sai/api/AclApi.h @@ -21,6 +21,13 @@ extern "C" { #include +#if defined(TAJO_SDK) +#include +#endif + +#if defined(TAJO_SDK) && defined(SAI_HAVE_ACL_FIELD_ROUTE_DST) +#define FBOSS_SAI_ACL_FIELD_ROUTE_DST 1 +#endif } inline bool operator==(const sai_u32_range_t& a, const sai_u32_range_t& b) { @@ -179,6 +186,7 @@ struct SaiAclTableTraits { SaiAttribute; using FieldDscp = SaiAttribute; + using FieldTc = SaiAttribute; using FieldDstMac = SaiAttribute; using FieldIpType = @@ -192,6 +200,12 @@ struct SaiAclTableTraits { EnumType, SAI_ACL_TABLE_ATTR_FIELD_ROUTE_DST_USER_META, bool>; +#if defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) + using FieldRouteDst = SaiAttribute< + EnumType, + static_cast(SAI_ACL_TABLE_ATTR_FIELD_ROUTE_DST), + bool>; +#endif using FieldNeighborDstUserMeta = SaiAttribute< EnumType, SAI_ACL_TABLE_ATTR_FIELD_NEIGHBOR_DST_USER_META, @@ -269,11 +283,15 @@ struct SaiAclTableTraits { std::optional, std::optional, std::optional, + std::optional, std::optional, std::optional, std::optional, std::optional, std::optional, +#if defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) + std::optional, +#endif std::optional, std::optional, std::optional, @@ -322,11 +340,15 @@ SAI_ATTRIBUTE_NAME(AclTable, FieldIcmpV4Code); SAI_ATTRIBUTE_NAME(AclTable, FieldIcmpV6Type); SAI_ATTRIBUTE_NAME(AclTable, FieldIcmpV6Code); SAI_ATTRIBUTE_NAME(AclTable, FieldDscp); +SAI_ATTRIBUTE_NAME(AclTable, FieldTc); SAI_ATTRIBUTE_NAME(AclTable, FieldDstMac); SAI_ATTRIBUTE_NAME(AclTable, FieldIpType); SAI_ATTRIBUTE_NAME(AclTable, FieldTtl); SAI_ATTRIBUTE_NAME(AclTable, FieldFdbDstUserMeta); SAI_ATTRIBUTE_NAME(AclTable, FieldRouteDstUserMeta); +#if defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) +SAI_ATTRIBUTE_NAME(AclTable, FieldRouteDst); +#endif SAI_ATTRIBUTE_NAME(AclTable, FieldNeighborDstUserMeta); SAI_ATTRIBUTE_NAME(AclTable, AvailableEntry); SAI_ATTRIBUTE_NAME(AclTable, AvailableCounter); @@ -443,6 +465,8 @@ struct SaiAclEntryTraits { AclEntryFieldU8>; using FieldDscp = SaiAttribute; + using FieldTc = + SaiAttribute; using FieldDstMac = SaiAttribute< EnumType, SAI_ACL_ENTRY_ATTR_FIELD_DST_MAC, @@ -461,6 +485,12 @@ struct SaiAclEntryTraits { EnumType, SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_DST_USER_META, AclEntryFieldU32>; +#if defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) + using FieldRouteDst = SaiAttribute< + EnumType, + static_cast(SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_DST), + AclEntryFieldSaiObjectIdT>; +#endif using FieldNeighborDstUserMeta = SaiAttribute< EnumType, SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_DST_USER_META, @@ -612,11 +642,15 @@ struct SaiAclEntryTraits { std::optional, std::optional, std::optional, + std::optional, std::optional, std::optional, std::optional, std::optional, std::optional, +#if defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) + std::optional, +#endif std::optional, std::optional, std::optional, @@ -685,11 +719,15 @@ SAI_ATTRIBUTE_NAME(AclEntry, FieldIcmpV4Code); SAI_ATTRIBUTE_NAME(AclEntry, FieldIcmpV6Type); SAI_ATTRIBUTE_NAME(AclEntry, FieldIcmpV6Code); SAI_ATTRIBUTE_NAME(AclEntry, FieldDscp); +SAI_ATTRIBUTE_NAME(AclEntry, FieldTc); SAI_ATTRIBUTE_NAME(AclEntry, FieldDstMac); SAI_ATTRIBUTE_NAME(AclEntry, FieldIpType); SAI_ATTRIBUTE_NAME(AclEntry, FieldTtl); SAI_ATTRIBUTE_NAME(AclEntry, FieldFdbDstUserMeta); SAI_ATTRIBUTE_NAME(AclEntry, FieldRouteDstUserMeta); +#if defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) +SAI_ATTRIBUTE_NAME(AclEntry, FieldRouteDst); +#endif SAI_ATTRIBUTE_NAME(AclEntry, FieldNeighborDstUserMeta); SAI_ATTRIBUTE_NAME(AclEntry, FieldEthertype); SAI_ATTRIBUTE_NAME(AclEntry, FieldOuterVlanId); diff --git a/fboss/agent/hw/sai/api/tests/AclApiTest.cpp b/fboss/agent/hw/sai/api/tests/AclApiTest.cpp index 1259fd29ab971..09a37205b0a43 100644 --- a/fboss/agent/hw/sai/api/tests/AclApiTest.cpp +++ b/fboss/agent/hw/sai/api/tests/AclApiTest.cpp @@ -179,6 +179,10 @@ class AclApiTest : public ::testing::Test { return std::make_pair(10, 0x3F); } + std::pair kTc() const { + return std::make_pair(1, 0xFF); + } + std::pair kDscp2() const { return std::make_pair(20, 0x3F); } @@ -402,6 +406,7 @@ class AclApiTest : public ::testing::Test { true, // icmpV6Type true, // icmpV6Code true, // dscp + true, // tc true, // dstMac true, // ipType true, // ttl @@ -480,6 +485,8 @@ class AclApiTest : public ::testing::Test { AclEntryFieldU8(kIcmpV6Code())}; SaiAclEntryTraits::Attributes::FieldDscp aclFieldDscpAttribute{ AclEntryFieldU8(kDscp())}; + SaiAclEntryTraits::Attributes::FieldTc aclFieldTcAttribute{ + AclEntryFieldU8(kTc())}; SaiAclEntryTraits::Attributes::FieldDstMac aclFieldDstMacAttribute{ AclEntryFieldMac(kDstMac())}; SaiAclEntryTraits::Attributes::FieldIpType aclFieldIpTypeAttribute{ @@ -560,6 +567,7 @@ class AclApiTest : public ::testing::Test { aclFieldIcmpV6TypeAttribute, aclFieldIcmpV6CodeAttribute, aclFieldDscpAttribute, + aclFieldTcAttribute, aclFieldDstMacAttribute, aclFieldIpTypeAttribute, aclFieldTtlAttribute, @@ -1093,6 +1101,7 @@ TEST_F(AclApiTest, getAclEntryAttribute) { kIcmpV6Type(), kIcmpV6Code(), kDscp(), + kTc(), kDstMac(), kIpType(), kTtl(), diff --git a/fboss/agent/hw/sai/store/tests/AclTableGroupStoreTest.cpp b/fboss/agent/hw/sai/store/tests/AclTableGroupStoreTest.cpp index 2fe44537cf02d..be08f8282a1b1 100644 --- a/fboss/agent/hw/sai/store/tests/AclTableGroupStoreTest.cpp +++ b/fboss/agent/hw/sai/store/tests/AclTableGroupStoreTest.cpp @@ -62,6 +62,7 @@ class AclTableGroupStoreTest : public SaiStoreTest { true, // icmpv6Type true, // icmpv6Code true, // dscp + true, // tc true, // dstMac true, // ipType true, // ttl diff --git a/fboss/agent/hw/sai/store/tests/AclTableStoreTest.cpp b/fboss/agent/hw/sai/store/tests/AclTableStoreTest.cpp index fd7f6ddfa1614..7b7869066d203 100644 --- a/fboss/agent/hw/sai/store/tests/AclTableStoreTest.cpp +++ b/fboss/agent/hw/sai/store/tests/AclTableStoreTest.cpp @@ -107,6 +107,10 @@ class AclTableStoreTest : public SaiStoreTest { return std::make_pair(10, 0x3F); } + std::pair kTc() const { + return std::make_pair(1, 0xFF); + } + std::pair kDstMac() const { return std::make_pair( folly::MacAddress{"00:11:22:33:44:55"}, @@ -253,6 +257,7 @@ class AclTableStoreTest : public SaiStoreTest { true, // icmpv6Type true, // icmpv6Code true, // dscp + true, // tc true, // dstMac true, // ipType true, // ttl @@ -296,6 +301,7 @@ class AclTableStoreTest : public SaiStoreTest { AclEntryFieldU8(this->kIcmpV6Type()), AclEntryFieldU8(this->kIcmpV6Code()), AclEntryFieldU8(this->kDscp()), + AclEntryFieldU8(this->kTc()), AclEntryFieldMac(this->kDstMac()), AclEntryFieldU32(this->kIpType()), AclEntryFieldU8(this->kTtl()), @@ -449,6 +455,7 @@ TEST_P(AclTableStoreParamTest, aclTableCtorCreate) { true, // icmpv6Type true, // icmpv6Code true, // dscp + true, // tc true, // dstMac true, // ipType true, // ttl @@ -499,6 +506,7 @@ TEST_P(AclTableStoreParamTest, AclEntryCreateCtor) { this->kIcmpV6Type(), this->kIcmpV6Code(), this->kDscp(), + this->kTc(), this->kDstMac(), this->kIpType(), this->kTtl(), diff --git a/fboss/agent/hw/sai/switch/SaiAclTableManager.cpp b/fboss/agent/hw/sai/switch/SaiAclTableManager.cpp index 931a9e46c410a..09d56b2a2f3a9 100644 --- a/fboss/agent/hw/sai/switch/SaiAclTableManager.cpp +++ b/fboss/agent/hw/sai/switch/SaiAclTableManager.cpp @@ -21,18 +21,23 @@ #include "fboss/agent/hw/sai/switch/SaiHostifManager.h" #include "fboss/agent/hw/sai/switch/SaiManagerTable.h" #include "fboss/agent/hw/sai/switch/SaiMirrorManager.h" +#include "fboss/agent/hw/sai/switch/SaiNextHopGroupManager.h" #include "fboss/agent/hw/sai/switch/SaiPortManager.h" +#include "fboss/agent/hw/sai/switch/SaiSrv6TunnelManager.h" #include "fboss/agent/hw/sai/switch/SaiSwitch.h" #include "fboss/agent/hw/sai/switch/SaiSwitchManager.h" #include "fboss/agent/hw/sai/switch/SaiTunnelManager.h" #include "fboss/agent/hw/sai/switch/SaiUdfManager.h" #include "fboss/agent/hw/switch_asics/HwAsic.h" #include "fboss/agent/platforms/sai/SaiPlatform.h" +#include "fboss/agent/state/RouteNextHop.h" +#include "fboss/agent/state/RouteNextHopEntry.h" #include #include #include #include +#include extern "C" { #if defined(BRCM_SAI_SDK_GTE_13_0) && defined(BRCM_SAI_SDK_XGS) @@ -44,6 +49,82 @@ using namespace std::chrono; namespace facebook::fboss { +namespace { + +constexpr auto kSrv6AclNhgMemberWaitTimeout = milliseconds(2000); +constexpr auto kSrv6AclNhgMemberPollInterval = milliseconds(10); + +void waitForSrv6NextHopGroupMembers( + const std::shared_ptr& nhgHandle, + const char* context) { + if (!nhgHandle || !nhgHandle->nextHopGroup) { + throw FbossError(context, ": missing SRv6 next-hop group handle"); + } + const auto deadline = steady_clock::now() + kSrv6AclNhgMemberWaitTimeout; + while (nhgHandle->nextHopGroupSize() == 0) { + if (steady_clock::now() >= deadline) { + throw FbossError( + context, + ": SRv6 next-hop group ", + nhgHandle->nextHopGroup->adapterKey(), + " has no members; resolve the underlay neighbor and install the " + "route/NHG before programming FIELD_ROUTE_DST or REDIRECT ACE"); + } + std::this_thread::sleep_for(kSrv6AclNhgMemberPollInterval); + } +} + +// Build the same normalized NHG key SaiRouteManager uses for SRv6 routes so +// FIELD_ROUTE_DST matches post-LPM destination (test_srv6_svi_pbr.py uses one +// nhg_gold object for route + ACL match + redirect). +RouteNextHopEntry::NextHopSet buildNormalizedSrv6RedirectNhSet( + const cfg::RedirectNextHop& nhStruct) { + if (!nhStruct.srv6SegmentList().has_value() || + nhStruct.srv6SegmentList()->empty()) { + throw FbossError( + "SRV6_ENCAP next-hop group requires non-empty srv6SegmentList"); + } + if (!nhStruct.intfID().has_value()) { + throw FbossError("SRV6_ENCAP next-hop group requires intfID"); + } + if (!nhStruct.tunnelId().has_value()) { + throw FbossError("SRV6_ENCAP next-hop group requires tunnelId"); + } + std::vector segList; + segList.reserve(nhStruct.srv6SegmentList()->size()); + for (const auto& seg : *nhStruct.srv6SegmentList()) { + segList.push_back(folly::IPAddress(seg).asV6()); + } + RouteNextHopEntry::NextHopSet rawNhSet; + rawNhSet.insert(ResolvedNextHop( + folly::IPAddress(*nhStruct.ip()), + InterfaceID(nhStruct.intfID().value()), + ECMP_WEIGHT, + std::nullopt, + std::nullopt, + std::nullopt, + std::nullopt, + std::move(segList), + TunnelType::SRV6_ENCAP, + nhStruct.tunnelId().value())); + return RouteNextHopEntry::normalizeNextHops(rawNhSet); +} + +std::shared_ptr incRefOrAddSrv6RedirectNextHopGroup( + SaiManagerTable* managerTable, + const RouteNextHopEntry::NextHopSet& nhSet, + const char* context) { + auto nhgHandle = managerTable->nextHopGroupManager().incRefOrAddNextHopGroup( + SaiNextHopGroupKey(nhSet, std::nullopt)); + if (!nhgHandle || !nhgHandle->nextHopGroup) { + throw FbossError("Failed to create SRv6 next-hop group for ", context); + } + waitForSrv6NextHopGroupMembers(nhgHandle, context); + return nhgHandle; +} + +} // namespace + sai_u32_range_t SaiAclTableManager::getFdbDstUserMetaDataRange() const { std::optional range = SaiSwitchTraits::Attributes::FdbDstUserMetaDataRange(); @@ -953,6 +1034,12 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( std::make_pair(addedAclEntry->getDscp().value(), kDscpMask))}; } + std::optional fieldTc{std::nullopt}; + if (addedAclEntry->getTrafficClass()) { + fieldTc = SaiAclEntryTraits::Attributes::FieldTc{AclEntryFieldU8( + std::make_pair(addedAclEntry->getTrafficClass().value(), kTcMask))}; + } + std::optional fieldDstMac{ std::nullopt}; if (addedAclEntry->getDstMac()) { @@ -985,6 +1072,12 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( addedAclEntry->getLookupClassRoute().value()))}; } +#if defined(TAJO_SDK) && defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) && \ + SAI_API_VERSION >= SAI_VERSION(1, 12, 0) + std::optional fieldRouteDst{ + std::nullopt}; +#endif + std::optional fieldNeighborDstUserMeta{std::nullopt}; if (addedAclEntry->getLookupClassNeighbor()) { @@ -1067,6 +1160,38 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( aclActionRedirect{std::nullopt}; std::shared_ptr> tunnelEncapNextHop{ nullptr}; + std::shared_ptr srv6PbrNextHopGroup{nullptr}; + std::shared_ptr routeDstNextHopGroup{nullptr}; + +#if defined(TAJO_SDK) && defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) && \ + SAI_API_VERSION >= SAI_VERSION(1, 12, 0) + if (addedAclEntry->getRouteDst()) { + const auto nhStruct = addedAclEntry->getRouteDst().value(); + if (nhStruct.tunnelType().has_value() && + nhStruct.tunnelType().value() == TunnelType::SRV6_ENCAP && + nhStruct.tunnelId().has_value()) { + auto tunnelHandle = + managerTable_->srv6TunnelManager().getSrv6TunnelHandle( + nhStruct.tunnelId().value()); + if (!tunnelHandle || !tunnelHandle->tunnel) { + throw FbossError( + "Missing SRv6 tunnel for FIELD_ROUTE_DST match: ", + nhStruct.tunnelId().value()); + } + const auto nhSet = buildNormalizedSrv6RedirectNhSet(nhStruct); + routeDstNextHopGroup = incRefOrAddSrv6RedirectNextHopGroup( + managerTable_, nhSet, "FIELD_ROUTE_DST match"); + fieldRouteDst = SaiAclEntryTraits::Attributes::FieldRouteDst{ + AclEntryFieldSaiObjectIdT( + std::make_pair( + routeDstNextHopGroup->nextHopGroup->adapterKey(), + kMaskDontCare))}; + } else { + throw FbossError( + "FIELD_ROUTE_DST match currently requires SRV6_ENCAP RedirectNextHop"); + } + } +#endif std::shared_ptr saiAclCounter{nullptr}; std::vector> aclCounterTypeAndName; @@ -1383,11 +1508,47 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( AclEntryActionSaiObjectIdT( NextHopSaiId{tunnelEncapNextHop->adapterKey()})}; break; +#if SAI_API_VERSION >= SAI_VERSION(1, 12, 0) + } else if ( + nhStruct.tunnelType().has_value() && + nhStruct.tunnelType().value() == TunnelType::SRV6_ENCAP && + nhStruct.tunnelId().has_value()) { + auto tunnelHandle = + managerTable_->srv6TunnelManager().getSrv6TunnelHandle( + nhStruct.tunnelId().value()); + if (!tunnelHandle || !tunnelHandle->tunnel) { + throw FbossError( + "Missing SRv6 tunnel for redirect: ", + nhStruct.tunnelId().value()); + } + const auto nhSet = buildNormalizedSrv6RedirectNhSet(nhStruct); + if (routeDstNextHopGroup && addedAclEntry->getRouteDst() && + nhSet == + buildNormalizedSrv6RedirectNhSet( + addedAclEntry->getRouteDst().value())) { + srv6PbrNextHopGroup = routeDstNextHopGroup; + } else { + srv6PbrNextHopGroup = incRefOrAddSrv6RedirectNextHopGroup( + managerTable_, nhSet, "ACL REDIRECT to SRv6"); + } + aclActionRedirect = SaiAclEntryTraits::Attributes::ActionRedirect{ + AclEntryActionSaiObjectIdT( + NextHopGroupSaiId{ + srv6PbrNextHopGroup->nextHopGroup->adapterKey()})}; + break; +#endif } } } } + // PBR / redirect ACEs (test_srv6_svi_pbr.py) use only COUNTER + REDIRECT; + // tables like Srv6PbrAclTable omit PACKET_ACTION. Do not program packet + // action together with REDIRECT. + if (aclActionRedirect.has_value()) { + aclActionPacketAction = std::nullopt; + } + // TODO(skhare) At least one field and one action must be specified. // Once we add support for all fields and actions, throw error if that is not // honored. @@ -1400,9 +1561,14 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( fieldTcpFlags.has_value() || fieldIpFrag.has_value() || fieldIcmpV4Type.has_value() || fieldIcmpV4Code.has_value() || fieldIcmpV6Type.has_value() || fieldIcmpV6Code.has_value() || - fieldDscp.has_value() || fieldDstMac.has_value() || - fieldIpType.has_value() || fieldTtl.has_value() || - fieldFdbDstUserMeta.has_value() || fieldRouteDstUserMeta.has_value() || + fieldDscp.has_value() || fieldTc.has_value() || + fieldDstMac.has_value() || fieldIpType.has_value() || + fieldTtl.has_value() || fieldFdbDstUserMeta.has_value() || + fieldRouteDstUserMeta.has_value() || +#if defined(TAJO_SDK) && defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) && \ + SAI_API_VERSION >= SAI_VERSION(1, 12, 0) + fieldRouteDst.has_value() || +#endif fieldEtherType.has_value() || fieldNeighborDstUserMeta.has_value() || fieldOuterVlanId.has_value() || #if !defined(TAJO_SDK) || defined(TAJO_SDK_GTE_24_8_3001) @@ -1430,8 +1596,8 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( } auto actionIsValid = (aclActionPacketAction.has_value() || aclActionCounter.has_value() || - aclActionSetTC.has_value() || aclActionSetDSCP.has_value() || - aclActionMirrorIngress.has_value() || + aclActionRedirect.has_value() || aclActionSetTC.has_value() || + aclActionSetDSCP.has_value() || aclActionMirrorIngress.has_value() || aclActionMirrorEgress.has_value() || aclActionMacsecFlow.has_value() #if !defined(TAJO_SDK) || aclActionSetUserTrap.has_value() @@ -1474,11 +1640,16 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( fieldIcmpV6Type, fieldIcmpV6Code, fieldDscp, + fieldTc, fieldDstMac, fieldIpType, fieldTtl, fieldFdbDstUserMeta, fieldRouteDstUserMeta, +#if defined(TAJO_SDK) && defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) && \ + SAI_API_VERSION >= SAI_VERSION(1, 12, 0) + fieldRouteDst, +#endif fieldNeighborDstUserMeta, fieldEtherType, fieldOuterVlanId, @@ -1531,6 +1702,8 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( entryHandle->aclEntry = saiAclEntry; entryHandle->aclCounter = saiAclCounter; entryHandle->tunnelEncapNextHop = tunnelEncapNextHop; + entryHandle->srv6PbrNextHopGroup = srv6PbrNextHopGroup; + entryHandle->routeDstNextHopGroup = routeDstNextHopGroup; entryHandle->aclCounterTypeAndName = aclCounterTypeAndName; entryHandle->ingressMirror = ingressMirror; entryHandle->egressMirror = egressMirror; @@ -1775,6 +1948,7 @@ std::set SaiAclTableManager::getSupportedQualifierSet( cfg::AclTableQualifier::DST_IPV4, cfg::AclTableQualifier::IP_PROTOCOL_NUMBER, cfg::AclTableQualifier::DSCP, + cfg::AclTableQualifier::TC, cfg::AclTableQualifier::IP_TYPE, cfg::AclTableQualifier::TTL, cfg::AclTableQualifier::LOOKUP_CLASS_L2, @@ -1809,6 +1983,7 @@ std::set SaiAclTableManager::getSupportedQualifierSet( cfg::AclTableQualifier::DST_IPV6, cfg::AclTableQualifier::SRC_PORT, cfg::AclTableQualifier::DSCP, + cfg::AclTableQualifier::TC, cfg::AclTableQualifier::IP_PROTOCOL_NUMBER, cfg::AclTableQualifier::IP_TYPE, cfg::AclTableQualifier::TTL, @@ -1823,6 +1998,7 @@ std::set SaiAclTableManager::getSupportedQualifierSet( cfg::AclTableQualifier::DST_IPV4, cfg::AclTableQualifier::SRC_PORT, cfg::AclTableQualifier::DSCP, + cfg::AclTableQualifier::TC, cfg::AclTableQualifier::TTL, cfg::AclTableQualifier::IP_PROTOCOL_NUMBER, cfg::AclTableQualifier::IPV6_NEXT_HEADER, @@ -1853,6 +2029,7 @@ std::set SaiAclTableManager::getSupportedQualifierSet( cfg::AclTableQualifier::IPV6_NEXT_HEADER, cfg::AclTableQualifier::SRC_PORT, cfg::AclTableQualifier::DSCP, + cfg::AclTableQualifier::TC, cfg::AclTableQualifier::TTL, cfg::AclTableQualifier::IP_TYPE, cfg::AclTableQualifier::ETHER_TYPE, @@ -1866,6 +2043,7 @@ std::set SaiAclTableManager::getSupportedQualifierSet( } else { return { cfg::AclTableQualifier::DSCP, + cfg::AclTableQualifier::TC, cfg::AclTableQualifier::OUT_PORT, cfg::AclTableQualifier::LOOKUP_CLASS_L2, cfg::AclTableQualifier::LOOKUP_CLASS_ROUTE, @@ -1889,6 +2067,7 @@ std::set SaiAclTableManager::getSupportedQualifierSet( cfg::AclTableQualifier::ICMPV6_TYPE, cfg::AclTableQualifier::ICMPV6_CODE, cfg::AclTableQualifier::DSCP, + cfg::AclTableQualifier::TC, cfg::AclTableQualifier::DST_MAC, cfg::AclTableQualifier::IP_TYPE, cfg::AclTableQualifier::TTL, @@ -2044,6 +2223,10 @@ bool SaiAclTableManager::isQualifierSupported( return hasField( std::get>( attributes)); + case cfg::AclTableQualifier::TC: + return hasField( + std::get>( + attributes)); case cfg::AclTableQualifier::DST_MAC: return hasField( std::get>( @@ -2070,6 +2253,12 @@ bool SaiAclTableManager::isQualifierSupported( std::get>( attributes)); +#if defined(TAJO_SDK) && defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) + case cfg::AclTableQualifier::ROUTE_DST: + return hasField( + std::get>( + attributes)); +#endif case cfg::AclTableQualifier::ETHER_TYPE: return hasField( std::get< diff --git a/fboss/agent/hw/sai/switch/SaiAclTableManager.h b/fboss/agent/hw/sai/switch/SaiAclTableManager.h index f1f8067a6a22e..12a6a371af302 100644 --- a/fboss/agent/hw/sai/switch/SaiAclTableManager.h +++ b/fboss/agent/hw/sai/switch/SaiAclTableManager.h @@ -33,6 +33,7 @@ namespace facebook::fboss { class SaiManagerTable; class SaiPlatform; class SaiStore; +struct SaiNextHopGroupHandle; struct SaiHostifUserDefinedTrapHandle; using SaiAclTable = SaiObject; @@ -82,6 +83,8 @@ struct SaiAclEntryHandle { std::shared_ptr userDefinedTrap; std::shared_ptr aclCounter; std::shared_ptr> tunnelEncapNextHop; + std::shared_ptr srv6PbrNextHopGroup; + std::shared_ptr routeDstNextHopGroup; std::shared_ptr aclEntry; std::vector> aclCounterTypeAndName; std::optional ingressMirror; @@ -113,6 +116,7 @@ class SaiAclTableManager { * Thus, match all mask is 0b111111 i.e. 0x3F. */ static auto constexpr kDscpMask = 0x3F; + static auto constexpr kTcMask = 0xFF; static auto constexpr kMaxUdfGroups = 5; diff --git a/fboss/agent/hw/sai/switch/SaiManagerTable.cpp b/fboss/agent/hw/sai/switch/SaiManagerTable.cpp index ef0a4bc521d02..0ec8f300ad13b 100644 --- a/fboss/agent/hw/sai/switch/SaiManagerTable.cpp +++ b/fboss/agent/hw/sai/switch/SaiManagerTable.cpp @@ -148,6 +148,15 @@ void SaiManagerTable::reset(bool skipSwitchManager) { // MySid handles reference managed next hops and next hop groups, // so must be reset before those managers srv6MySidManager_.reset(); + // ACL entries with REDIRECT / FIELD_ROUTE_DST hold references to next-hop + // groups (SRv6 PBR). Remove ACL tables before NHG/NH teardown so + // remove_acl_entry still sees valid redirect targets. + if (!skipSwitchManager) { + switchManager_->resetIngressAcl(); + switchManager_->resetEgressAcl(); + } + aclTableGroupManager_.reset(); + aclTableManager_.reset(); // Reset neighbor mgr before reseting rif mgr, since the // neighbor entries refer to rifs. While at it, also reset fdb // and next hop mgrs. Fdb is reset after neighbor mgr since @@ -195,18 +204,6 @@ void SaiManagerTable::reset(bool skipSwitchManager) { switchManager_->resetQosMaps(); samplePacketManager_.reset(); - // ACL Table Group is going away, reset ingressACL pointing to it - if (!skipSwitchManager) { - switchManager_->resetIngressAcl(); - switchManager_->resetEgressAcl(); - } - - // Reset ACL Table group before Acl Table, since ACL Table group members - // refer to ACL Table and those references to ACL Table must be released - // before attempting to reset (remove) ACL Table. - aclTableGroupManager_.reset(); - aclTableManager_.reset(); - if (!skipSwitchManager) { switchManager_->resetArsProfile(); } diff --git a/fboss/agent/hw/sai/switch/SaiRouteManager.cpp b/fboss/agent/hw/sai/switch/SaiRouteManager.cpp index 835820b19242e..9cdd59946e80e 100644 --- a/fboss/agent/hw/sai/switch/SaiRouteManager.cpp +++ b/fboss/agent/hw/sai/switch/SaiRouteManager.cpp @@ -190,6 +190,23 @@ void SaiRouteManager::addOrUpdateRoute( if (fwd.getAction() == RouteForwardAction::NEXTHOPS) { packetAction = SAI_PACKET_ACTION_FORWARD; const auto nhops = getNextHops(state, fwd); + const bool programRouteViaNextHopGroup = [&]() -> bool { + if (nhops.size() > 1) { + return true; + } +#if defined(TAJO_SDK) && SAI_API_VERSION >= SAI_VERSION(1, 12, 0) + // Single-member SRv6 routes must use NHG at SAI so ingress ACL + // FIELD_ROUTE_DST (post-LPM) matches the same object as the route. + // Matches sai/test/python/srv6/test_srv6_svi_pbr.py create_route(..., + // nhg). + if (nhops.size() == 1) { + const auto swNextHop = + folly::poly_cast(*(nhops.begin())); + return !swNextHop.srv6SegmentList().empty(); + } +#endif + return false; + }(); /* * A Route which satisfies isConnected() is an interface subnet route. * It will have one NextHop with the ip configured for the interface @@ -298,12 +315,11 @@ void SaiRouteManager::addOrUpdateRoute( XLOG(DBG3) << "Connected route: " << newRoute->str() << " routerInterfaceId: " << routerInterfaceId; } - } else if (nhops.size() > 1) { + } else if (programRouteViaNextHopGroup) { /* - * A Route which has more than one NextHops will create or reference an - * existing SaiNextHopGroup corresponding to ECMP over those next hops. - * When no route refers to a next hop set, it will be removed in SAI as - * well. + * Routes with ECMP (>1 next hop), or single-member SRv6 sidlist routes on + * Tajo, create or reference a SaiNextHopGroup. When no route refers to a + * next hop set, it will be removed in SAI as well. */ auto nextHopGroupHandle = managerTable_->nextHopGroupManager().incRefOrAddNextHopGroup( diff --git a/fboss/agent/hw/sai/switch/SaiSwitch.cpp b/fboss/agent/hw/sai/switch/SaiSwitch.cpp index db47d33653b34..f3ffde3030c56 100644 --- a/fboss/agent/hw/sai/switch/SaiSwitch.cpp +++ b/fboss/agent/hw/sai/switch/SaiSwitch.cpp @@ -5584,6 +5584,11 @@ AclStats SaiSwitch::getAclStats() const { return managerTable_->aclTableManager().getAclStats(); } +void SaiSwitch::updateAclStats() { + std::lock_guard lock(saiSwitchMutex_); + managerTable_->aclTableManager().updateStats(); +} + cfg::SwitchingMode SaiSwitch::getFwdSwitchingMode( const RouteNextHopEntry& fwd) { std::lock_guard lock(saiSwitchMutex_); diff --git a/fboss/agent/hw/sai/switch/SaiSwitch.h b/fboss/agent/hw/sai/switch/SaiSwitch.h index 544cbdd6ffe09..c552ad5429da0 100644 --- a/fboss/agent/hw/sai/switch/SaiSwitch.h +++ b/fboss/agent/hw/sai/switch/SaiSwitch.h @@ -293,6 +293,9 @@ class SaiSwitch : public HwSwitch { AclStats getAclStats() const override; + // Poll ACL counters from SAI/SDK only (no port/queue/switch stat collection). + void updateAclStats(); + std::shared_ptr reconstructSwitchState() const override; std::shared_ptr constructSwitchStateWithFib() noexcept override; diff --git a/fboss/agent/hw/sai/switch/npu/SaiAclTableManager.cpp b/fboss/agent/hw/sai/switch/npu/SaiAclTableManager.cpp index 6e89eca0e68a3..826abf0320fb4 100644 --- a/fboss/agent/hw/sai/switch/npu/SaiAclTableManager.cpp +++ b/fboss/agent/hw/sai/switch/npu/SaiAclTableManager.cpp @@ -244,11 +244,15 @@ std:: qualifierExistsFn(cfg::AclTableQualifier::ICMPV6_TYPE), qualifierExistsFn(cfg::AclTableQualifier::ICMPV6_CODE), qualifierExistsFn(cfg::AclTableQualifier::DSCP), + qualifierExistsFn(cfg::AclTableQualifier::TC), qualifierExistsFn(cfg::AclTableQualifier::DST_MAC), qualifierExistsFn(cfg::AclTableQualifier::IP_TYPE), qualifierExistsFn(cfg::AclTableQualifier::TTL), qualifierExistsFn(cfg::AclTableQualifier::LOOKUP_CLASS_L2), qualifierExistsFn(cfg::AclTableQualifier::LOOKUP_CLASS_ROUTE), +#if defined(TAJO_SDK) && defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) + qualifierExistsFn(cfg::AclTableQualifier::ROUTE_DST), +#endif qualifierExistsFn(cfg::AclTableQualifier::LOOKUP_CLASS_NEIGHBOR), qualifierExistsFn(cfg::AclTableQualifier::ETHER_TYPE), qualifierExistsFn(cfg::AclTableQualifier::OUTER_VLAN), diff --git a/fboss/agent/hw/sai/switch/phy/SaiAclTableManager.cpp b/fboss/agent/hw/sai/switch/phy/SaiAclTableManager.cpp index 71044684b457a..8879f7649bb9a 100644 --- a/fboss/agent/hw/sai/switch/phy/SaiAclTableManager.cpp +++ b/fboss/agent/hw/sai/switch/phy/SaiAclTableManager.cpp @@ -101,6 +101,7 @@ std:: std::nullopt, // fieldIcmpV6Type std::nullopt, // fieldIcmpV6Code std::nullopt, // dscp + std::nullopt, // tc true, // fieldDstMac std::nullopt, // ipType std::nullopt, // ttl diff --git a/fboss/agent/hw/sai/tracer/AclApiTracer.cpp b/fboss/agent/hw/sai/tracer/AclApiTracer.cpp index e75510020c05f..bc6e1c1949d5b 100644 --- a/fboss/agent/hw/sai/tracer/AclApiTracer.cpp +++ b/fboss/agent/hw/sai/tracer/AclApiTracer.cpp @@ -40,11 +40,15 @@ std::map> _AclTableMap{ SAI_ATTR_MAP(AclTable, FieldIcmpV6Type), SAI_ATTR_MAP(AclTable, FieldIcmpV6Code), SAI_ATTR_MAP(AclTable, FieldDscp), + SAI_ATTR_MAP(AclTable, FieldTc), SAI_ATTR_MAP(AclTable, FieldDstMac), SAI_ATTR_MAP(AclTable, FieldIpType), SAI_ATTR_MAP(AclTable, FieldTtl), SAI_ATTR_MAP(AclTable, FieldFdbDstUserMeta), SAI_ATTR_MAP(AclTable, FieldRouteDstUserMeta), +#if defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) + SAI_ATTR_MAP(AclTable, FieldRouteDst), +#endif SAI_ATTR_MAP(AclTable, FieldNeighborDstUserMeta), SAI_ATTR_MAP(AclTable, AvailableEntry), SAI_ATTR_MAP(AclTable, AvailableCounter), @@ -118,11 +122,15 @@ std::map> _AclEntryMap{ SAI_ATTR_MAP(AclEntry, FieldIcmpV6Type), SAI_ATTR_MAP(AclEntry, FieldIcmpV6Code), SAI_ATTR_MAP(AclEntry, FieldDscp), + SAI_ATTR_MAP(AclEntry, FieldTc), SAI_ATTR_MAP(AclEntry, FieldDstMac), SAI_ATTR_MAP(AclEntry, FieldIpType), SAI_ATTR_MAP(AclEntry, FieldTtl), SAI_ATTR_MAP(AclEntry, FieldFdbDstUserMeta), SAI_ATTR_MAP(AclEntry, FieldRouteDstUserMeta), +#if defined(FBOSS_SAI_ACL_FIELD_ROUTE_DST) + SAI_ATTR_MAP(AclEntry, FieldRouteDst), +#endif SAI_ATTR_MAP(AclEntry, FieldNeighborDstUserMeta), SAI_ATTR_MAP(AclEntry, FieldEthertype), SAI_ATTR_MAP(AclEntry, FieldOuterVlanId), diff --git a/fboss/agent/if/ctrl.thrift b/fboss/agent/if/ctrl.thrift index 3cc7e63fb57f0..058b56964ddd1 100644 --- a/fboss/agent/if/ctrl.thrift +++ b/fboss/agent/if/ctrl.thrift @@ -725,6 +725,10 @@ struct AclEntryThrift { 22: optional byte lookupClassL2; 23: optional bool enabled; 24: optional list udfGroups; + /* + * Match on internal traffic class (post-DSCP-to-TC classification). + */ + 25: optional byte tc; } struct AclTableThrift { diff --git a/fboss/agent/state/AclEntry.cpp b/fboss/agent/state/AclEntry.cpp index e42965143bb0a..d625b4cfbf83d 100644 --- a/fboss/agent/state/AclEntry.cpp +++ b/fboss/agent/state/AclEntry.cpp @@ -84,6 +84,12 @@ std::set AclEntry::getRequiredAclTableQualifiers() if (getDscp()) { qualifiers.insert(cfg::AclTableQualifier::DSCP); } + if (getTrafficClass()) { + qualifiers.insert(cfg::AclTableQualifier::TC); + } + if (getRouteDst()) { + qualifiers.insert(cfg::AclTableQualifier::ROUTE_DST); + } if (getIpType()) { qualifiers.insert(cfg::AclTableQualifier::IP_TYPE); } diff --git a/fboss/agent/state/AclEntry.h b/fboss/agent/state/AclEntry.h index 3dc3c3e6de82a..e237c6a9ae759 100644 --- a/fboss/agent/state/AclEntry.h +++ b/fboss/agent/state/AclEntry.h @@ -251,6 +251,28 @@ class AclEntry : public ThriftStructNode { set(dscp); } + std::optional getTrafficClass() const { + if (auto tc = cref()) { + return tc->cref(); + } + return std::nullopt; + } + + void setTrafficClass(uint8_t tc) { + set(tc); + } + + std::optional getRouteDst() const { + if (auto routeDst = cref()) { + return routeDst->toThrift(); + } + return std::nullopt; + } + + void setRouteDst(const cfg::RedirectNextHop& routeDst) { + set(routeDst); + } + std::optional getIpType() const { if (auto ipType = cref()) { return ipType->cref(); @@ -450,12 +472,13 @@ class AclEntry : public ThriftStructNode { // at least one qualifier must be specified return getSrcIp().first || getDstIp().first || getProto() || getTcpFlagsBitMap() || getSrcPort() || getDstPort() || getIpFrag() || - getIcmpType() || getDscp() || getIpType() || getTtl() || getDstMac() || - getL4SrcPort() || getL4DstPort() || getL4DstPortRange() || - getLookupClassL2() || getLookupClassNeighbor() || - getLookupClassRoute() || getPacketLookupResult() || getEtherType() || - getVlanID() || getUdfGroups() || getRoceOpcode() || getRoceBytes() || - getRoceMask() || getUdfTable(); + getIcmpType() || getDscp() || getTrafficClass() || getRouteDst() || + getIpType() || getTtl() || getDstMac() || getL4SrcPort() || + getL4DstPort() || getL4DstPortRange() || getLookupClassL2() || + getLookupClassNeighbor() || getLookupClassRoute() || + getPacketLookupResult() || getEtherType() || getVlanID() || + getUdfGroups() || getRoceOpcode() || getRoceBytes() || getRoceMask() || + getUdfTable(); } std::set getRequiredAclTableQualifiers() const; diff --git a/fboss/agent/switch_config.thrift b/fboss/agent/switch_config.thrift index cf47a26d6e2a1..eddd1140d41f3 100644 --- a/fboss/agent/switch_config.thrift +++ b/fboss/agent/switch_config.thrift @@ -663,6 +663,16 @@ struct AclEntry { 35: optional list udfTable; 36: optional Range l4DstPortRange; + /* + * Match on internal traffic class (post-DSCP-to-TC classification). + * Requires AclTableQualifier::TC on the ACL table. + */ + 37: optional byte tc; + /* + * Match on route destination NH/NHG (SAI FIELD_ROUTE_DST). For SRv6 PBR, + * use SRV6_ENCAP RedirectNextHop matching the gold route next-hop group. + */ + 38: optional RedirectNextHop routeDst; } enum AclTableActionType { diff --git a/fboss/agent/switch_state.thrift b/fboss/agent/switch_state.thrift index d6ad9a0179147..637cf08134724 100644 --- a/fboss/agent/switch_state.thrift +++ b/fboss/agent/switch_state.thrift @@ -269,6 +269,7 @@ struct AclEntryFields { 33: optional switch_config.Range l4DstPortRange; 34: optional byte trafficClass; 35: optional string namedNextHopGroup; + 36: optional switch_config.RedirectNextHop routeDst; } enum NeighborState { diff --git a/fboss/agent/test/agent_hw_tests/AgentSrv6PbrCounterTest.cpp b/fboss/agent/test/agent_hw_tests/AgentSrv6PbrCounterTest.cpp new file mode 100644 index 0000000000000..874996e5876a4 --- /dev/null +++ b/fboss/agent/test/agent_hw_tests/AgentSrv6PbrCounterTest.cpp @@ -0,0 +1,596 @@ +// +// AgentSrv6PbrCounterTest +// ----------------------- +// Exercises programmable packet+byte counters on SRv6 PBR ACEs that redirect +// to tiered SRv6 next-hop groups (gold / silver / bronze) on Cisco Silicon One. +// +// Mirrors sai/test/python/srv6/test_srv6_svi_pbr.py: +// * L3 route points at the gold NHG only (FIELD_ROUTE_DST always gold). +// * DSCP-to-TC qos map selects the ACE (10->TC1, 20->TC2, 30->TC3). +// * Each ACE redirects to its tier NHG with a distinct uSID path. +// * Per-tier ACL counters must increment independently on CPU and front-panel +// inject (both paths validated before rebase). +// * Egress SRv6 packets are trapped to CPU and verified (outer uSID). +// +// Packet path: +// CPU inject: sendPacketSwitchedAsync -> pipeline lookup -> encap + counter. +// Front-panel: sendPacketOutOfPort on inject port (loopback) -> re-ingress -> +// ingress PBR ACL -> SRv6 encap -> underlay egress -> trap + counter bump. +// + +#include + +#include +#include +#include +#include +#include + +#include "fboss/agent/AddressUtil.h" +#include "fboss/agent/AgentFeatures.h" +#include "fboss/agent/AsicUtils.h" +#include "fboss/agent/SwSwitchRouteUpdateWrapper.h" +#include "fboss/agent/gen-cpp2/switch_config_types.h" +#include "fboss/agent/hw/switch_asics/HwAsic.h" +#include "fboss/agent/hw/test/HwTestPacketUtils.h" +#include "fboss/agent/if/gen-cpp2/ctrl_types.h" +#include "fboss/agent/packet/EthFrame.h" +#include "fboss/agent/packet/Ethertype.h" +#include "fboss/agent/rib/RoutingInformationBase.h" +#include "fboss/agent/state/AggregatePort.h" +#include "fboss/agent/state/RouteNextHop.h" +#include "fboss/agent/test/AgentHwTest.h" +#include "fboss/agent/test/EcmpSetupHelper.h" +#include "fboss/agent/test/TrunkUtils.h" +#include "fboss/agent/test/utils/AclTestUtils.h" +#include "fboss/agent/test/utils/ConfigUtils.h" +#include "fboss/agent/test/utils/LoadBalancerTestUtils.h" +#include "fboss/agent/test/utils/PacketSnooper.h" +#include "fboss/agent/test/utils/TrapPacketUtils.h" + +DECLARE_bool(enable_acl_table_group); + +namespace facebook::fboss { + +namespace { + +struct Srv6PbrTier { + const char* name; + uint8_t dscp; + uint8_t tc; + const char* sid; + const char* nhgName; + const char* aclName; + const char* counterName; +}; + +constexpr Srv6PbrTier kGoldTier{ + "gold", + 10, + 1, + "bbbb:b1b1:51:52:53:54:55:56", + "goldSrv6Nhg", + "acl_srv6_pbr_encap_gold", + "acl_srv6_pbr_encap_stat_gold"}; +constexpr Srv6PbrTier kSilverTier{ + "silver", + 20, + 2, + "bbbb:b1b1:61:62:63:64:65:66", + "silverSrv6Nhg", + "acl_srv6_pbr_encap_silver", + "acl_srv6_pbr_encap_stat_silver"}; +constexpr Srv6PbrTier kBronzeTier{ + "bronze", + 30, + 3, + "bbbb:b1b1:71:72:73:74:75:76", + "bronzeSrv6Nhg", + "acl_srv6_pbr_encap_bronze", + "acl_srv6_pbr_encap_stat_bronze"}; + +constexpr std::array kSrv6PbrTiers{ + &kGoldTier, + &kSilverTier, + &kBronzeTier}; + +} // namespace + +struct PhysicalPortSrv6Pbr { + static constexpr bool isTrunk = false; +}; +struct AggregatePortSrv6Pbr { + static constexpr bool isTrunk = true; +}; +using Srv6PbrPortTypes = + ::testing::Types; + +template +class AgentSrv6PbrCounterTest : public AgentHwTest { + public: + static constexpr bool kIsTrunk = PortType::isTrunk; + + void setCmdLineFlagOverrides() const override { + AgentHwTest::setCmdLineFlagOverrides(); + FLAGS_enable_acl_table_group = true; + FLAGS_enable_nexthop_id_manager = true; + FLAGS_resolve_nexthops_from_id = true; + } + + protected: + const std::string kTunnelId{"srv6PbrTunnel0"}; + const std::string kEncapSrcIp{"2401:db00::1"}; + folly::IPAddress underlayNhIp_{folly::IPAddress("fe80:face:b11c::1")}; + const std::string kGoldRouteV6Dst{"2001:db8:61::11"}; + static constexpr uint8_t kGoldRouteV6PrefixLen{128}; + const std::string kQosPolicyName{"srv6_pbr_qos"}; + const std::string kPbrAclTableName{"Srv6PbrAclTable"}; + + std::vector getProductionFeaturesVerified() + const override { + std::vector features{ + ProductionFeature::SRV6_ENCAP, + ProductionFeature::ACL_COUNTER, + }; + if constexpr (kIsTrunk) { + features.push_back(ProductionFeature::LAG); + } + return features; + } + + cfg::SwitchConfig initialConfig( + // TH6/BCM pass the byte assertion for the wrong reason. + bool isCiscoSiliconOneAsic(cfg::AsicType type) const { + switch (type) { + case cfg::AsicType::ASIC_TYPE_YUBA: // GR2 (Graphene2) + case cfg::AsicType::ASIC_TYPE_G202X: // G204 / G202X family + // NOTE: GR3 / G2LL not yet enumerated in this thrift tree; add + // their AsicType enum values here as soon as they land. See + // switch_config.thrift `enum AsicType`. + ensemble.getSw()->getPlatformSupportsAddRemovePort(), + asic->desiredLoopbackModes()); + addSrv6EncapTunnelConfig(cfg); + addDscpToTcQosMap(cfg); + addSrv6SidTrapAcls(cfg, asic); + if constexpr (kIsTrunk) { + utility::addAggPort( + 1, + {static_cast(ensemble.masterLogicalPortIds()[0])}, + &cfg); + cfg.loadBalancers() = + utility::getEcmpFullWithFlowLabelTrunkFullWithFlowLabelHashConfig( + ensemble.getL3Asics()); + } + return cfg; + } + + void applyConfigAndEnableTrunks(const cfg::SwitchConfig& config) { + this->applyNewConfig(config); + this->applyNewState( + [](const std::shared_ptr state) { + return utility::enableTrunkPorts(state); + }, + "enable trunk ports"); + } + + bool isCiscoSiliconOneAsic(cfg::AsicType type) const { + switch (type) { + case cfg::AsicType::ASIC_TYPE_YUBA: + case cfg::AsicType::ASIC_TYPE_G202X: + return true; + default: + return false; + } + + void setupHelper() { + if constexpr (kIsTrunk) { + applyConfigAndEnableTrunks( + this->initialConfig(*this->getAgentEnsemble())); + } + + auto hwAsic = + checkSameAndGetAsic(this->getAgentEnsemble()->getL3Asics()); + if (!isCiscoSiliconOneAsic(hwAsic->getAsicType())) { + GTEST_SKIP() + << "AgentSrv6PbrCounterTest only validates the Cisco " + << "Silicon One SRv6 PBR byte-counter code path. Current " + << "ASIC type = " + << apache::thrift::util::enumNameSafe(hwAsic->getAsicType()) + << " is not in {YUBA, G202X}; skipping."; + } + + utility::EcmpSetupAnyNPorts6 ecmpHelper( + this->getProgrammedState(), + this->getSw()->needL2EntryForNeighbor(), + getLocalMacAddress()); + const auto& nhop = ecmpHelper.nhop(0); + CHECK(nhop.linkLocalNhopIp.has_value()); + underlayNhIp_ = folly::IPAddress(*nhop.linkLocalNhopIp); + this->resolveNeighbors(ecmpHelper, 1, true /* useLinkLocal */); + auto routeUpdater = this->getSw()->getRouteUpdater(); + ecmpHelper.programRoutes(&routeUpdater, 1); + programTierNhgsAndGoldRoute(); + programSrv6PbrAclWithCounters(); + } + + std::unique_ptr makeMatchingPacket(uint8_t dscp) { + auto vlanId = getVlanIDForTx(); + auto intfMac = getMacForFirstInterfaceWithPorts(getProgrammedState()); + auto dstMac = intfMac; + auto srcMac = folly::MacAddress::fromHBO(dstMac.u64HBO() + 1); + const folly::IPAddressV6 srcIp("1::10"); + const folly::IPAddressV6 dstIp(kGoldRouteV6Dst); + return utility::makeUDPTxPacket( + getSw(), + vlanId, + srcMac, + dstMac, + srcIp, + dstIp, + 10000, + 443, + static_cast(dscp << 2)); + } + + uint64_t readAclCounter(const std::string& statName, bool bytes = false) + const { + getSw()->updateStats(); + return utility::getAclInOutPackets(getSw(), statName, bytes); + } + + std::map> + snapshotAllTierCounters() const { + std::map> snapshot; + for (const auto* t : kSrv6PbrTiers) { + snapshot[t->counterName] = { + readAclCounter(t->counterName), + readAclCounter(t->counterName, true)}; + } + return snapshot; + } + + PortID getEgressPort(const PortDescriptor& portDesc) const { + if (portDesc.isPhysicalPort()) { + return portDesc.phyPortID(); + } + auto aggPort = getProgrammedState()->getAggregatePorts()->getNodeIf( + portDesc.aggPortID()); + return aggPort->sortedSubports().front().portID; + } + + PortID findInjectPort(const std::vector& egressPorts) { + for (const auto& portMap : + std::as_const(*getProgrammedState()->getPorts())) { + for (const auto& [_, port] : std::as_const(*portMap.second)) { + if (port->isPortUp() && + std::find( + egressPorts.begin(), egressPorts.end(), port->getID()) == + egressPorts.end()) { + return port->getID(); + } + } + } + return masterLogicalPortIds()[1]; + } + + void verifyTierSrv6PbrEncapAndCounter( + const Srv6PbrTier& tier, + const std::map>& + countersBefore, + std::optional injectPort = std::nullopt, + bool verifyCounters = true) { + const auto pktCountBefore = countersBefore.at(tier.counterName).first; + const auto bytesCountBefore = + countersBefore.at(tier.counterName).second; + + auto txPacket = makeMatchingPacket(tier.dscp); + const size_t sizeOfPacketSent = txPacket->buf()->length(); + auto origFrame = utility::makeEthFrame(*txPacket); + + utility::SwSwitchPacketSnooper snooper( + getSw(), std::string("srv6PbrSnooper-") + tier.name); + + const bool fromCpu = !injectPort.has_value(); + XLOG(INFO) << "AgentSrv6PbrCounterTest: sending 1 " << tier.name + << " UDP pkt (" << sizeOfPacketSent + << " bytes) dscp=" << static_cast(tier.dscp) + << " tc=" << static_cast(tier.tc) + << " inject=" << (fromCpu ? "cpu" : "front-panel") + << "; expect SRv6 encap uSID=" << tier.sid + << " and counter '" << tier.counterName << "' bump"; + + if (injectPort.has_value()) { + this->getAgentEnsemble()->ensureSendPacketOutOfPort( + std::move(txPacket), injectPort.value()); + } else { + this->sendPacketSwitchedAsync(std::move(txPacket)); + } + + auto hwAsic = checkSameAndGetAsic(getAgentEnsemble()->getL3Asics()); + const uint64_t extraBytes = + (hwAsic->getAsicType() == cfg::AsicType::ASIC_TYPE_TOMAHAWK6) ? 4 + : 0; + const folly::IPAddressV6 expectedSid(tier.sid); + + std::optional> frameRx; + WITH_RETRIES({ + if (!frameRx.has_value()) { + frameRx = snooper.waitForPacket(1); + } + EXPECT_EVENTUALLY_TRUE(frameRx.has_value()) + << tier.name << ": no trapped SRv6 egress packet captured"; + }); + ASSERT_TRUE(frameRx.has_value()); + + folly::io::Cursor cursor(frameRx->get()); + utility::EthFrame frame(cursor); + auto ethHdr = frame.header(); + EXPECT_EQ( + ethHdr.etherType, static_cast(ETHERTYPE::ETHERTYPE_IPV6)); + auto v6Payload = frame.v6PayLoad(); + ASSERT_TRUE(v6Payload.has_value()); + auto v6Hdr = v6Payload->header(); + EXPECT_EQ(v6Hdr.dstAddr, expectedSid) + << tier.name << ": outer SRv6 destination does not match tier uSID"; + EXPECT_NE(v6Hdr.flowLabel, 0) + << tier.name << ": expected non-zero outer IPv6 flow label"; + EXPECT_EQ(v6Hdr.trafficClass >> 2, tier.dscp) + << tier.name + << ": outer IPv6 DSCP should propagate from inner packet"; + + auto origInner = origFrame.v6PayLoad(); + ASSERT_TRUE(origInner.has_value()); + auto capturedInner = v6Payload->v6PayLoad(); + ASSERT_NE(capturedInner, nullptr); + EXPECT_EQ(*capturedInner, *origInner) + << tier.name << ": inner IPv6 payload mismatch after SRv6 encap"; + + if (!verifyCounters) { + return; + } + + WITH_RETRIES({ + const auto pktCountAfter = readAclCounter(tier.counterName); + const auto bytesCountAfter = + readAclCounter(tier.counterName, true /* bytes */); + + XLOG(INFO) << "SRv6 PBR ACE counter '" << tier.counterName << "' (" + << tier.name << "): pkts " << pktCountBefore << " -> " + << pktCountAfter << ", bytes " << bytesCountBefore + << " -> " << bytesCountAfter; + + EXPECT_EVENTUALLY_GE(pktCountAfter, pktCountBefore + 1) + << tier.name << ": PBR ACE packet counter did not increment"; + EXPECT_EVENTUALLY_LE(pktCountAfter, pktCountBefore + 2) + << tier.name << ": PBR ACE packet counter over-counted"; + + EXPECT_EVENTUALLY_GE( + bytesCountAfter + extraBytes, bytesCountBefore + sizeOfPacketSent) + << tier.name << ": PBR ACE byte counter did not increment"; + EXPECT_EVENTUALLY_LE( + bytesCountAfter, bytesCountBefore + (2 * sizeOfPacketSent) + 4) + << tier.name << ": PBR ACE byte counter over-counted"; + + for (const auto* other : kSrv6PbrTiers) { + if (other == &tier) { + continue; + } + const auto otherPktCount = readAclCounter(other->counterName); + const auto otherBytesCount = + readAclCounter(other->counterName, true /* bytes */); + EXPECT_EQ( + otherPktCount, countersBefore.at(other->counterName).first) + << tier.name << " traffic bumped " << other->name + << " packet counter"; + EXPECT_EQ( + otherBytesCount, countersBefore.at(other->counterName).second) + << tier.name << " traffic bumped " << other->name + << " byte counter"; + } + }); + } + + void verifyTierSrv6PbrCpuAndFrontPanel( + const Srv6PbrTier& tier, + const std::map>& + countersBefore) { + utility::EcmpSetupAnyNPorts6 ecmpHelper( + getProgrammedState(), + getSw()->needL2EntryForNeighbor(), + getLocalMacAddress()); + const auto egressPort = getEgressPort(ecmpHelper.nhop(0).portDesc); + const auto injectPort = findInjectPort({egressPort}); + + verifyTierSrv6PbrEncapAndCounter(tier, countersBefore, std::nullopt); + verifyTierSrv6PbrEncapAndCounter( + tier, snapshotAllTierCounters(), injectPort); + } + + private: + void addSrv6EncapTunnelConfig(cfg::SwitchConfig & cfg) const { + cfg::Srv6Tunnel tunnel; + tunnel.srv6TunnelId() = kTunnelId; + tunnel.underlayIntfID() = *cfg.interfaces()[0].intfID(); + tunnel.tunnelType() = TunnelType::SRV6_ENCAP; + tunnel.srcIp() = kEncapSrcIp; + " 4) SDK PR #81423 (PACKET_AND_BYTE_COUNTER API) not in " + "tree.\n" + " 5) SDK PR #81561 (ACE_SRV6 counter bank / " cfg.srv6Tunnels() = { + tunnel}; + } + + void addSrv6SidTrapAcls(cfg::SwitchConfig & cfg, const HwAsic* asic) + const { + std::set sidPrefixes; + for (const auto* tier : kSrv6PbrTiers) { + sidPrefixes.insert({folly::IPAddressV6(tier->sid), 128}); + } + utility::addTrapPacketAcl(asic, &cfg, sidPrefixes); + } + + void addSrv6PbrAclTable(cfg::SwitchConfig & cfg) const { + if (!FLAGS_enable_acl_table_group) { + return; + } + if (utility::getAclTable( + cfg, cfg::AclStage::INGRESS, kPbrAclTableName)) { + return; + } + utility::addAclTable( + &cfg, + cfg::AclStage::INGRESS, + kPbrAclTableName, + 1 /* priority */, + { + cfg::AclTableActionType::COUNTER, + cfg::AclTableActionType::REDIRECT, + }, + { + cfg::AclTableQualifier::TC, + cfg::AclTableQualifier::ROUTE_DST, + }, + {}); + } + + void addDscpToTcQosMap(cfg::SwitchConfig & cfg) const { + cfg::QosMap qosMap; + qosMap.dscpMaps()->resize(3); + for (size_t i = 0; i < kSrv6PbrTiers.size(); ++i) { + const auto* tier = kSrv6PbrTiers[i]; + qosMap.dscpMaps()[i].internalTrafficClass() = tier->tc; + qosMap.dscpMaps()[i].fromDscpToTrafficClass()->push_back(tier->dscp); + qosMap.trafficClassToQueueId()->emplace(tier->tc, 0); + } + + cfg.qosPolicies()->resize(1); + cfg.qosPolicies()[0].name() = kQosPolicyName; + cfg.qosPolicies()[0].qosMap() = qosMap; + + if (!cfg.dataPlaneTrafficPolicy().has_value()) { + cfg.dataPlaneTrafficPolicy() = cfg::TrafficPolicyConfig(); + } + cfg.dataPlaneTrafficPolicy()->defaultQosPolicy() = kQosPolicyName; + } + + void programSrv6PbrAclWithCounters() { + auto cfg = getSw()->getConfig(); + addSrv6PbrAclWithCounters(cfg); + applyNewConfig(cfg); + } + + cfg::RedirectNextHop makeSrv6RedirectNh( + const cfg::SwitchConfig& cfg, const std::string& sid) const { + cfg::RedirectNextHop nh; + nh.ip() = underlayNhIp_.str(); + nh.intfID() = *cfg.interfaces()[0].intfID(); + nh.tunnelType() = TunnelType::SRV6_ENCAP; + nh.tunnelId() = kTunnelId; + nh.srv6SegmentList() = {sid}; + return nh; + } + + void addSrv6PbrAclWithCounters(cfg::SwitchConfig & cfg) const { + addSrv6PbrAclTable(cfg); + + const auto goldRouteDstNh = makeSrv6RedirectNh(cfg, kGoldTier.sid); + + for (const auto* tier : kSrv6PbrTiers) { + cfg::AclEntry acl; + acl.name() = tier->aclName; + acl.tc() = tier->tc; + acl.routeDst() = goldRouteDstNh; + utility::addAclEntry( + &cfg, acl, kPbrAclTableName, cfg::AclStage::INGRESS); + + std::vector counterTypes{ + cfg::CounterType::PACKETS, cfg::CounterType::BYTES}; + utility::addTrafficCounter(&cfg, tier->counterName, counterTypes); + + cfg::RedirectToNextHopAction redirectAction; + redirectAction.redirectNextHops() = { + makeSrv6RedirectNh(cfg, tier->sid)}; + + cfg::MatchAction action; + action.redirectToNextHop() = redirectAction; + action.counter() = tier->counterName; + + cfg::MatchToAction mta; + mta.matcher() = tier->aclName; + mta.action() = action; + if (!cfg.dataPlaneTrafficPolicy().has_value()) { + cfg.dataPlaneTrafficPolicy() = cfg::TrafficPolicyConfig(); + } + cfg.dataPlaneTrafficPolicy()->matchToAction()->push_back(mta); + } + } + + RouteNextHopSet makeSrv6NhopSet(const std::string& sid) const { + utility::EcmpSetupAnyNPorts6 ecmpHelper( + getProgrammedState(), + getSw()->needL2EntryForNeighbor(), + getLocalMacAddress()); + const auto nhop = ecmpHelper.nhop(0); + CHECK(nhop.linkLocalNhopIp.has_value()); + const folly::IPAddressV6 srv6Sid(sid); + + RouteNextHopSet nhops; + nhops.insert(ResolvedNextHop( + folly::IPAddress(*nhop.linkLocalNhopIp), + nhop.intf, + ECMP_WEIGHT, + std::nullopt, + std::nullopt, + std::nullopt, + std::nullopt, + std::vector{srv6Sid}, + TunnelType::SRV6_ENCAP, + kTunnelId)); + return nhops; + } + + void programTierNhgsAndGoldRoute() { + std::vector> groups; + for (const auto* tier : kSrv6PbrTiers) { + groups.emplace_back(tier->nhgName, makeSrv6NhopSet(tier->sid)); + } + + auto rib = getSw()->getRib(); + rib->addOrUpdateNamedNextHopGroups( + getSw()->getScopeResolver(), + groups, + createRibToSwitchStateFunction(), + getSw()); + + UnicastRoute route; + route.dest()->ip() = facebook::network::toBinaryAddress( + folly::IPAddress(kGoldRouteV6Dst)); + route.dest()->prefixLength() = kGoldRouteV6PrefixLen; + NamedRouteDestination namedDest; + namedDest.nextHopGroup_ref() = kGoldTier.nhgName; + route.namedRouteDestination() = namedDest; + route.counterID() = kGoldTier.nhgName; + + auto routeUpdater = getSw()->getRouteUpdater(); + routeUpdater.addRoute(RouterID(0), ClientID::TE_AGENT, route); + routeUpdater.program(); + } + }; + + TYPED_TEST_SUITE(AgentSrv6PbrCounterTest, Srv6PbrPortTypes); + + TYPED_TEST( + AgentSrv6PbrCounterTest, RedirectToSrv6BumpsPacketAndByteCounter) { + auto setup = [this]() { this->setupHelper(); }; + + auto verify = [this]() { + auto counters = this->snapshotAllTierCounters(); + for (const auto* tier : kSrv6PbrTiers) { + this->verifyTierSrv6PbrCpuAndFrontPanel(*tier, counters); + counters = this->snapshotAllTierCounters(); + } + }; + + this->verifyAcrossWarmBoots(setup, verify); + } + +} // namespace facebook::fboss diff --git a/fboss/agent/test/utils/AclTestUtils.cpp b/fboss/agent/test/utils/AclTestUtils.cpp index 19556528b3222..28b559e045715 100644 --- a/fboss/agent/test/utils/AclTestUtils.cpp +++ b/fboss/agent/test/utils/AclTestUtils.cpp @@ -1029,6 +1029,14 @@ std::set getRequiredQualifers( addQualifier(aclEntry.dscp().has_value(), qualifier); break; + case cfg::AclTableQualifier::TC: + addQualifier(aclEntry.tc().has_value(), qualifier); + break; + + case cfg::AclTableQualifier::ROUTE_DST: + addQualifier(aclEntry.routeDst().has_value(), qualifier); + break; + case cfg::AclTableQualifier::DST_MAC: addQualifier(aclEntry.dstMac().has_value(), qualifier); break; diff --git a/fboss/fsdb/if/oss/fsdb_model_thriftpath.h b/fboss/fsdb/if/oss/fsdb_model_thriftpath.h index 84b972c3bb885..278478f798f8e 100755 --- a/fboss/fsdb/if/oss/fsdb_model_thriftpath.h +++ b/fboss/fsdb/if/oss/fsdb_model_thriftpath.h @@ -59,7 +59,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(agent, 1); STRUCT_CHILD_GETTERS(bgp, 2); STRUCT_CHILD_GETTERS(qsfp_service, 4); @@ -172,7 +172,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(present, 1); STRUCT_CHILD_GETTERS(transceiver, 2); STRUCT_CHILD_GETTERS(port, 3); @@ -273,7 +273,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(side, 1); STRUCT_CHILD_GETTERS(pcs, 2); STRUCT_CHILD_GETTERS(pmd, 3); @@ -325,7 +325,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(version, 1); STRUCT_CHILD_GETTERS(crc, 2); STRUCT_CHILD_GETTERS(versionStr, 3); @@ -372,7 +372,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(low, 1); STRUCT_CHILD_GETTERS(high, 2); @@ -413,7 +413,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(alarm, 1); STRUCT_CHILD_GETTERS(warn, 2); @@ -455,7 +455,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(pcsRxStatusLive, 1); STRUCT_CHILD_GETTERS(pcsRxStatusLatched, 2); STRUCT_CHILD_GETTERS(rsFecState, 3); @@ -497,7 +497,7 @@ class ChildThriftPath<::facebook::fboss::phy::RsFecState, ::facebook::fboss::fsd template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lanes, 1); template @@ -580,7 +580,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(phyStates, 1); STRUCT_CHILD_GETTERS(tcvrStates, 2); STRUCT_CHILD_GETTERS(pimStates, 3); @@ -627,7 +627,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(tuningStatus, 1); STRUCT_CHILD_GETTERS(wavelengthLockingStatus, 2); STRUCT_CHILD_GETTERS(laserStatusFlagsByte, 3); @@ -675,7 +675,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(dataNotReady, 1); STRUCT_CHILD_GETTERS(interruptL, 2); STRUCT_CHILD_GETTERS(cmisModuleState, 3); @@ -726,7 +726,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lane, 1); STRUCT_CHILD_GETTERS(dataPathDeInit, 2); STRUCT_CHILD_GETTERS(cmisLaneState, 3); @@ -775,7 +775,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(cabledPortPairs, 1); STRUCT_CHILD_GETTERS(firmwareForUpgradeTest, 2); @@ -816,7 +816,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(fwType, 1); STRUCT_CHILD_GETTERS(version, 2); @@ -878,7 +878,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(frequencyGrid, 1); STRUCT_CHILD_GETTERS(centerFrequencyConfig, 2); @@ -929,7 +929,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(singleModeKm, 1); STRUCT_CHILD_GETTERS(singleMode, 2); STRUCT_CHILD_GETTERS(om3, 3); @@ -1018,7 +1018,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(defaultCommandLineArgs, 1); STRUCT_CHILD_GETTERS(transceiverConfigOverrides, 2); STRUCT_CHILD_GETTERS(sdk_version, 3); @@ -1095,7 +1095,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(transceiverPartNumber, 1); STRUCT_CHILD_GETTERS(applicationCode, 2); STRUCT_CHILD_GETTERS(hostApplicationCode, 3); @@ -1137,7 +1137,7 @@ class ChildThriftPath<::facebook::fboss::cfg::Firmware, ::facebook::fboss::fsdb: template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(versions, 1); template @@ -1176,7 +1176,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(factor, 1); STRUCT_CHILD_GETTERS(config, 2); @@ -1216,7 +1216,7 @@ class ChildThriftPath<::facebook::fboss::cfg::TransceiverFirmware, ::facebook::f template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(versionsMap, 1); template @@ -1294,7 +1294,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(diagnostics, 1); STRUCT_CHILD_GETTERS(vdm, 2); STRUCT_CHILD_GETTERS(cdb, 3); @@ -1371,7 +1371,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(frequencyMhz, 1); STRUCT_CHILD_GETTERS(channelNumber, 2); @@ -1411,7 +1411,7 @@ class ChildThriftPath<::facebook::fboss::phy::RsInfo, ::facebook::fboss::fsdb::F template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(faultStatus, 1); template @@ -1452,7 +1452,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(txLos, 1); STRUCT_CHILD_GETTERS(rxLos, 2); STRUCT_CHILD_GETTERS(txLol, 3); @@ -1504,7 +1504,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(cdrTx, 1); STRUCT_CHILD_GETTERS(cdrRx, 2); STRUCT_CHILD_GETTERS(rateSelect, 3); @@ -1559,7 +1559,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(linkTrainingEnabled, 1); STRUCT_CHILD_GETTERS(rxStatus, 2); @@ -1601,7 +1601,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lane, 1); STRUCT_CHILD_GETTERS(fecAlignmentLockLive, 2); STRUCT_CHILD_GETTERS(fecAlignmentLockChanged, 3); @@ -1651,7 +1651,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lane, 1); STRUCT_CHILD_GETTERS(txInputEqualization, 2); STRUCT_CHILD_GETTERS(rxOutputEmphasis, 3); @@ -1709,7 +1709,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(smfCode, 1); STRUCT_CHILD_GETTERS(extendedSpecificationComplianceCode, 2); STRUCT_CHILD_GETTERS(ethernet10GComplianceCode, 3); @@ -1773,7 +1773,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lane, 1); STRUCT_CHILD_GETTERS(rvga, 2); STRUCT_CHILD_GETTERS(dco, 3); @@ -1912,7 +1912,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rxPreemphasis, 1); STRUCT_CHILD_GETTERS(rxAmplitude, 2); STRUCT_CHILD_GETTERS(txEqualization, 3); @@ -1955,7 +1955,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(applicationFirmwareVersion, 1); STRUCT_CHILD_GETTERS(dspFirmwareVersion, 2); @@ -2021,7 +2021,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(enable_tls, 1); STRUCT_CHILD_GETTERS(x509_ca_path, 2); STRUCT_CHILD_GETTERS(x509_cert_path, 3); @@ -2071,7 +2071,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(aPortName, 1); STRUCT_CHILD_GETTERS(zPortName, 2); STRUCT_CHILD_GETTERS(profileID, 3); @@ -2116,7 +2116,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(type, 1); STRUCT_CHILD_GETTERS(sub_type, 2); STRUCT_CHILD_GETTERS(asn, 3); @@ -2203,7 +2203,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(config, 1); STRUCT_CHILD_GETTERS(state, 2); @@ -2243,7 +2243,7 @@ class ChildThriftPath<::facebook::neteng::fboss::bgp::thrift::TBgpExtCommUnion, template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(two_byte_asn, 1); template @@ -2281,7 +2281,7 @@ class ChildThriftPath<::facebook::bgp::rib_policy::TGoldenPrefixPolicy, ::facebo template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(allowed_prefixes, 1); template @@ -2323,7 +2323,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(version, 1); STRUCT_CHILD_GETTERS(fwFault, 2); STRUCT_CHILD_GETTERS(dspFwVer, 3); @@ -2373,7 +2373,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(criteria_list, 1); STRUCT_CHILD_GETTERS(bgp_native_path_selection_min_nexthop, 2); STRUCT_CHILD_GETTERS(drain_on_min_nexthop_violation, 3); @@ -2420,7 +2420,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(set_lbw, 1); STRUCT_CHILD_GETTERS(set_ucmp_weights, 2); @@ -2461,7 +2461,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(prefixes, 1); STRUCT_CHILD_GETTERS(community_list, 2); @@ -2545,7 +2545,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(asn, 1); STRUCT_CHILD_GETTERS(value, 2); STRUCT_CHILD_GETTERS(community, 3); @@ -2629,7 +2629,7 @@ class ChildThriftPath<::facebook::fboss::cfg::QsfpSdkVersion, ::facebook::fboss: template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(version, 2); template @@ -2672,7 +2672,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(prefix, 1); STRUCT_CHILD_GETTERS(path_count, 2); STRUCT_CHILD_GETTERS(mnh_threshold, 3); @@ -2811,7 +2811,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(type, 1); STRUCT_CHILD_GETTERS(as_path_len_filter, 2); STRUCT_CHILD_GETTERS(as_path_filters, 3); @@ -2910,7 +2910,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(communities, 3); @@ -2958,7 +2958,7 @@ class ChildThriftPath<::facebook::bgp::rib_policy::TRouteAttributePolicy, ::face template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(statements, 1); template @@ -3021,7 +3021,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(neighbors, 3); @@ -3070,7 +3070,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(statements, 1); STRUCT_CHILD_GETTERS(version, 2); STRUCT_CHILD_GETTERS(golden_prefix_policy, 3); @@ -3136,7 +3136,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(set_self, 1); STRUCT_CHILD_GETTERS(next_hop, 2); @@ -3178,7 +3178,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(preCursor, 1); STRUCT_CHILD_GETTERS(postCursor, 2); STRUCT_CHILD_GETTERS(mainAmplitude, 3); @@ -3221,7 +3221,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(community, 1); STRUCT_CHILD_GETTERS(community_name, 2); @@ -3288,7 +3288,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(bgp_policy_statements, 1); STRUCT_CHILD_GETTERS(community_lists, 2); STRUCT_CHILD_GETTERS(aspath_lists, 3); @@ -3340,7 +3340,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(weight_value, 1); STRUCT_CHILD_GETTERS(weight_action_type, 2); STRUCT_CHILD_GETTERS(obj_uuid, 100); @@ -3441,7 +3441,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(type, 1); STRUCT_CHILD_GETTERS(set_as_path_prepend, 2); STRUCT_CHILD_GETTERS(community_action, 3); @@ -3517,7 +3517,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(community_list, 5); STRUCT_CHILD_GETTERS(origin, 2); STRUCT_CHILD_GETTERS(as_path_length, 3); @@ -3577,7 +3577,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(features, 1); STRUCT_CHILD_GETTERS(enable_med_comparison, 2); STRUCT_CHILD_GETTERS(enable_med_missing_as_worst, 3); @@ -3665,7 +3665,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(route_action, 1); STRUCT_CHILD_GETTERS(flow_action, 2); @@ -3709,7 +3709,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ingress_path_limit, 1); STRUCT_CHILD_GETTERS(prefix_limit, 2); STRUCT_CHILD_GETTERS(total_path_limit, 3); @@ -3761,7 +3761,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(as_paths, 3); @@ -3816,7 +3816,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(hold_time_seconds, 1); STRUCT_CHILD_GETTERS(keep_alive_seconds, 2); STRUCT_CHILD_GETTERS(out_delay_seconds, 3); @@ -3917,7 +3917,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(net_service_identity, 1); STRUCT_CHILD_GETTERS(net_static_file_acl, 2); STRUCT_CHILD_GETTERS(net_auth_checker_kill_switch_file, 3); @@ -3978,7 +3978,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(value, 1); STRUCT_CHILD_GETTERS(minimum_supporting_routes, 2); @@ -4019,7 +4019,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(statements, 1); STRUCT_CHILD_GETTERS(version, 2); @@ -4081,7 +4081,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(mnh, 1); STRUCT_CHILD_GETTERS(agg_lbw_bps, 2); @@ -4142,11 +4142,11 @@ class ChildThriftPath<::facebook::bgp::bgp_policy::AsPathToAsSetAction, ::facebo template using TypeFor = typename Children::template type_of; using Self::Self; - + template auto operator()(const std::integral_constant&) { - + } }; @@ -4201,7 +4201,48 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + + STRUCT_CHILD_GETTERS(partial_drain_state, 1); + STRUCT_CHILD_GETTERS(drained_prefixes, 2); + + template + auto operator()(const std::integral_constant&) { + if constexpr (__id == apache::thrift::FieldId{1}) { return partial_drain_state(); } + else if constexpr (__id == apache::thrift::FieldId{2}) { return drained_prefixes(); } + } +}; + + +template +class ChildThriftPath<::facebook::neteng::fboss::bgp::thrift::TPartialDrainState, ::facebook::fboss::fsdb::FsdbOperStateRoot, Parent> : + public Path< + ::facebook::neteng::fboss::bgp::thrift::TPartialDrainState, + ::facebook::fboss::fsdb::FsdbOperStateRoot, + ::apache::thrift::type_class::structure, + ::apache::thrift::type::struct_t<::facebook::neteng::fboss::bgp::thrift::TPartialDrainState>, + Parent> { + public: + using Self = Path< + ::facebook::neteng::fboss::bgp::thrift::TPartialDrainState, + ::facebook::fboss::fsdb::FsdbOperStateRoot, + ::apache::thrift::type_class::structure, + ::apache::thrift::type::struct_t<::facebook::neteng::fboss::bgp::thrift::TPartialDrainState>, + Parent>; + template + using Child = Path< + ChildType, + ::facebook::fboss::fsdb::FsdbOperStateRoot, + ChildTC, + ChildTag, + Self + >; + using Children = thriftpath::TypeMap>, +std::pair, ::facebook::fboss::fsdb::FsdbOperStateRoot, Self>>>; + + template + using TypeFor = typename Children::template type_of; + using Self::Self; + STRUCT_CHILD_GETTERS(partial_drain_state, 1); STRUCT_CHILD_GETTERS(drained_prefixes, 2); @@ -4245,7 +4286,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(tags, 3); @@ -4355,7 +4396,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(enable_memory_profiling, 1); STRUCT_CHILD_GETTERS(heap_dump_interval_s, 2); @@ -4395,7 +4436,7 @@ class ChildThriftPath<::facebook::neteng::fboss::bgp::thrift::TBgpExtCommunity, template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(u, 1); template @@ -4435,7 +4476,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(communities, 3); @@ -4480,7 +4521,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(med_value, 1); STRUCT_CHILD_GETTERS(med_action_type, 2); STRUCT_CHILD_GETTERS(update_pattern, 3); @@ -4526,7 +4567,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(localpref, 1); STRUCT_CHILD_GETTERS(name, 2); STRUCT_CHILD_GETTERS(description, 3); @@ -4594,7 +4635,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(config, 1); STRUCT_CHILD_GETTERS(routeAttributePolicy, 2); STRUCT_CHILD_GETTERS(pathSelectionPolicy, 3); @@ -4643,7 +4684,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(macAddress, 1); STRUCT_CHILD_GETTERS(port, 2); @@ -4688,7 +4729,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(header, 2); STRUCT_CHILD_GETTERS(startOffsetInBytes, 3); @@ -4737,7 +4778,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(enabled, 1); STRUCT_CHILD_GETTERS(polynominal, 2); @@ -4802,7 +4843,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(label, 1); STRUCT_CHILD_GETTERS(nexthopsmulti, 2); STRUCT_CHILD_GETTERS(fwd, 3); @@ -4909,7 +4950,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(mirrorPortId, 2); STRUCT_CHILD_GETTERS(localSrcIp, 3); @@ -4996,7 +5037,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ipaddress, 1); STRUCT_CHILD_GETTERS(mac, 2); STRUCT_CHILD_GETTERS(portId, 3); @@ -5073,7 +5114,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(weight, 2); STRUCT_CHILD_GETTERS(reserved, 3); @@ -5147,7 +5188,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(vrf, 1); STRUCT_CHILD_GETTERS(fibV4, 2); STRUCT_CHILD_GETTERS(fibV6, 3); @@ -5224,7 +5265,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(switchType, 1); STRUCT_CHILD_GETTERS(asicType, 2); STRUCT_CHILD_GETTERS(switchIndex, 3); @@ -5291,7 +5332,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sci, 1); STRUCT_CHILD_GETTERS(associationNum, 2); @@ -5374,7 +5415,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(tagged, 1); STRUCT_CHILD_GETTERS(priorityTagged, 2); @@ -5415,7 +5456,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(logicalID, 2); @@ -5458,7 +5499,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(headroomBytes, 2); STRUCT_CHILD_GETTERS(sharedBytes, 3); @@ -5524,7 +5565,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(systemID, 1); STRUCT_CHILD_GETTERS(systemPriority, 2); @@ -5568,7 +5609,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(mac, 1); STRUCT_CHILD_GETTERS(portId, 2); STRUCT_CHILD_GETTERS(classID, 3); @@ -5621,7 +5662,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sci, 1); STRUCT_CHILD_GETTERS(l2Port, 2); STRUCT_CHILD_GETTERS(assocNum, 3); @@ -5780,7 +5821,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(portId, 1); STRUCT_CHILD_GETTERS(portName, 2); STRUCT_CHILD_GETTERS(portDescription, 3); @@ -6015,7 +6056,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(prefix, 1); STRUCT_CHILD_GETTERS(nexthopsmulti, 2); STRUCT_CHILD_GETTERS(fwd, 3); @@ -6069,7 +6110,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(policy_match_entries, 3); @@ -6152,7 +6193,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(phyChip, 1); STRUCT_CHILD_GETTERS(fwVersion, 2); STRUCT_CHILD_GETTERS(speed, 3); @@ -6417,7 +6458,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(locatorPrefix, 1); STRUCT_CHILD_GETTERS(entries, 2); @@ -6501,7 +6542,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(peer_address, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(peer_as, 3); @@ -6566,7 +6607,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(egressPort, 1); STRUCT_CHILD_GETTERS(ip, 2); STRUCT_CHILD_GETTERS(tunnel, 3); @@ -6634,7 +6675,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(systemPriority, 1); STRUCT_CHILD_GETTERS(systemID, 2); STRUCT_CHILD_GETTERS(key, 3); @@ -6729,7 +6770,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(priority, 2); STRUCT_CHILD_GETTERS(aclMap, 3); @@ -6780,7 +6821,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(fibsMap, 1); STRUCT_CHILD_GETTERS(idToNextHop, 2); STRUCT_CHILD_GETTERS(idToNextHopIdSet, 3); @@ -6827,7 +6868,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(writeLog, 1); STRUCT_CHILD_GETTERS(readLog, 2); STRUCT_CHILD_GETTERS(disableOnFail, 3); @@ -6879,7 +6920,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(srv6TunnelId, 1); STRUCT_CHILD_GETTERS(underlayIntfId, 2); STRUCT_CHILD_GETTERS(srcIp, 3); @@ -6978,7 +7019,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(asn_regexp, 3); @@ -7050,7 +7091,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(communities, 3); @@ -7158,7 +7199,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(streamType, 2); STRUCT_CHILD_GETTERS(weight, 3); @@ -7227,7 +7268,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(nexthop_weight_map, 1); STRUCT_CHILD_GETTERS(nexthop_weight_actions, 2); STRUCT_CHILD_GETTERS(apply_all_actions_or_fallback_to_ecmp, 3); @@ -7273,7 +7314,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(greTunnel, 1); STRUCT_CHILD_GETTERS(sflowTunnel, 2); STRUCT_CHILD_GETTERS(srcIp, 3); @@ -7315,11 +7356,11 @@ class ChildThriftPath<::facebook::fboss::cfg::DecapMySidConfig, ::facebook::fbos template using TypeFor = typename Children::template type_of; using Self::Self; - + template auto operator()(const std::integral_constant&) { - + } }; @@ -7354,7 +7395,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(minimumLength, 1); STRUCT_CHILD_GETTERS(maximumLength, 2); STRUCT_CHILD_GETTERS(probability, 3); @@ -7399,7 +7440,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(localFault, 1); STRUCT_CHILD_GETTERS(remoteFault, 2); STRUCT_CHILD_GETTERS(highCrcErrorRateLive, 3); @@ -7443,7 +7484,7 @@ class ChildThriftPath<::facebook::fboss::cfg::CmisOverrides, ::facebook::fboss:: template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rxEqualizerSettings, 1); template @@ -7482,7 +7523,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(path_matchers, 1); STRUCT_CHILD_GETTERS(min_nexthop, 2); @@ -7523,7 +7564,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ip, 1); STRUCT_CHILD_GETTERS(ttl, 2); @@ -7567,7 +7608,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(allowSlowPeerDetach, 1); STRUCT_CHILD_GETTERS(slowPeerTimeThresholdMs, 2); STRUCT_CHILD_GETTERS(slowPeerBlockCountThreshold, 3); @@ -7629,7 +7670,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(portId, 1); STRUCT_CHILD_GETTERS(switchId, 2); STRUCT_CHILD_GETTERS(portName, 3); @@ -7727,7 +7768,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(dscpMaps, 1); STRUCT_CHILD_GETTERS(expMaps, 2); STRUCT_CHILD_GETTERS(trafficClassToQueueId, 3); @@ -7779,7 +7820,7 @@ class ChildThriftPath<::facebook::fboss::state::Label, ::facebook::fboss::fsdb:: template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(value, 1); template @@ -7861,7 +7902,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(adjacency, 1); STRUCT_CHILD_GETTERS(node, 2); STRUCT_CHILD_GETTERS(decap, 3); @@ -7905,7 +7946,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(portName, 1); STRUCT_CHILD_GETTERS(isV6, 2); STRUCT_CHILD_GETTERS(address, 3); @@ -7948,7 +7989,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(dropReasonAggregations, 1); STRUCT_CHILD_GETTERS(agingGroup, 2); @@ -7989,7 +8030,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(minimum, 1); STRUCT_CHILD_GETTERS(maximum, 2); @@ -8073,7 +8114,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(scalingFactor, 1); STRUCT_CHILD_GETTERS(loadWeight, 2); STRUCT_CHILD_GETTERS(queueWeight, 3); @@ -8158,7 +8199,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(common, 1); STRUCT_CHILD_GETTERS(npuEntries, 2); @@ -8252,7 +8293,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sendToQueue, 1); STRUCT_CHILD_GETTERS(trafficCounter, 2); STRUCT_CHILD_GETTERS(setDscp, 3); @@ -8315,7 +8356,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rxReason, 1); STRUCT_CHILD_GETTERS(queueId, 2); @@ -8368,7 +8409,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(dscp, 3); STRUCT_CHILD_GETTERS(truncate, 4); @@ -8434,7 +8475,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(rules, 2); STRUCT_CHILD_GETTERS(qosMap, 3); @@ -8483,7 +8524,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(routerAdvertisementSeconds, 1); STRUCT_CHILD_GETTERS(curHopLimit, 2); STRUCT_CHILD_GETTERS(routerLifetime, 3); @@ -8619,7 +8660,7 @@ class ChildThriftPath<::facebook::fboss::cfg::NodeMySidConfig, ::facebook::fboss template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(nodeAddress, 1); template @@ -8678,7 +8719,7 @@ class ChildThriftPath<::facebook::fboss::cfg::SetDscpMatchAction, ::facebook::fb template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(dscpValue, 1); template @@ -8720,7 +8761,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(cableLength, 2); STRUCT_CHILD_GETTERS(mediaInterface, 3); @@ -8780,7 +8821,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(mirrorPortId, 2); STRUCT_CHILD_GETTERS(localSrcPort, 3); @@ -8846,7 +8887,7 @@ class ChildThriftPath<::facebook::fboss::cfg::StaticMplsRouteNoNextHops, ::faceb template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ingressLabel, 1); template @@ -8927,7 +8968,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(detection, 1); STRUCT_CHILD_GETTERS(behavior, 2); @@ -8968,7 +9009,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(path_matchers, 1); STRUCT_CHILD_GETTERS(weight, 2); @@ -9045,7 +9086,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(remote_as, 1); STRUCT_CHILD_GETTERS(remote_as_4_byte, 35); STRUCT_CHILD_GETTERS(local_addr, 2); @@ -9159,7 +9200,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(config, 1); STRUCT_CHILD_GETTERS(jsonConfig, 2); STRUCT_CHILD_GETTERS(yamlConfig, 3); @@ -9247,7 +9288,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(l2PktType, 2); STRUCT_CHILD_GETTERS(l3pktType, 3); @@ -9303,7 +9344,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(adminDistance, 1); STRUCT_CHILD_GETTERS(action, 2); STRUCT_CHILD_GETTERS(counterID, 3); @@ -9369,7 +9410,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(key, 1); STRUCT_CHILD_GETTERS(name, 2); STRUCT_CHILD_GETTERS(description, 3); @@ -9490,7 +9531,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ipv4Fields, 1); STRUCT_CHILD_GETTERS(ipv6Fields, 2); STRUCT_CHILD_GETTERS(transportFields, 3); @@ -9579,7 +9620,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(value, 1); STRUCT_CHILD_GETTERS(mask, 2); @@ -9658,7 +9699,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(inactivityIntervalUsecs, 1); STRUCT_CHILD_GETTERS(flowletTableSize, 2); STRUCT_CHILD_GETTERS(dynamicEgressLoadExponent, 3); @@ -9789,7 +9830,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(numFlowSamplesPerView, 1); STRUCT_CHILD_GETTERS(flowLimit, 2); STRUCT_CHILD_GETTERS(numFlowsClear, 3); @@ -9866,7 +9907,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(address, 1); STRUCT_CHILD_GETTERS(weight, 2); STRUCT_CHILD_GETTERS(mplsAction, 3); @@ -9923,7 +9964,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(prefixAddress, 1); STRUCT_CHILD_GETTERS(prefixLength, 2); @@ -9991,7 +10032,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(type, 1); STRUCT_CHILD_GETTERS(mySid, 2); STRUCT_CHILD_GETTERS(unresolveNextHopsId, 3); @@ -10075,7 +10116,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(router_id, 1); STRUCT_CHILD_GETTERS(local_as, 2); STRUCT_CHILD_GETTERS(networks4, 3); @@ -10180,7 +10221,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(fieldSelection, 2); STRUCT_CHILD_GETTERS(algorithm, 3); @@ -10246,7 +10287,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(remoteSystem, 1); STRUCT_CHILD_GETTERS(remotePort, 2); @@ -10308,7 +10349,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sff, 1); STRUCT_CHILD_GETTERS(cmis, 2); @@ -10349,7 +10390,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ingress_filter, 1); STRUCT_CHILD_GETTERS(egress_filter, 2); @@ -10432,7 +10473,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(from, 1); STRUCT_CHILD_GETTERS(to, 2); @@ -10494,7 +10535,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(prefix_list, 1); STRUCT_CHILD_GETTERS(permissive_mode, 2); @@ -10535,7 +10576,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(matcher, 1); STRUCT_CHILD_GETTERS(multi_path_selector, 2); @@ -10576,7 +10617,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(blockNeighborVlanID, 1); STRUCT_CHILD_GETTERS(blockNeighborIP, 2); @@ -10617,7 +10658,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(boolean_operator, 1); STRUCT_CHILD_GETTERS(communities, 2); @@ -10665,7 +10706,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(srv6TunnelId, 1); STRUCT_CHILD_GETTERS(underlayIntfID, 2); STRUCT_CHILD_GETTERS(srcIp, 3); @@ -10733,7 +10774,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(name, 2); STRUCT_CHILD_GETTERS(scalingFactor, 3); @@ -10803,7 +10844,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rack_id, 1); STRUCT_CHILD_GETTERS(plane_id, 2); STRUCT_CHILD_GETTERS(remote_rack_capacity, 3); @@ -10850,7 +10891,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(routerID, 1); STRUCT_CHILD_GETTERS(prefix, 2); @@ -10976,7 +11017,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(vlanID, 1); STRUCT_CHILD_GETTERS(macAddress, 2); STRUCT_CHILD_GETTERS(egressLogicalPortID, 3); @@ -11049,7 +11090,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(pre, 1); STRUCT_CHILD_GETTERS(pre2, 2); STRUCT_CHILD_GETTERS(main, 3); @@ -11150,7 +11191,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(udfGroups, 1); STRUCT_CHILD_GETTERS(udfPacketMatcher, 2); @@ -11215,7 +11256,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(matcher, 1); STRUCT_CHILD_GETTERS(actions, 2); STRUCT_CHILD_GETTERS(ttl_secs, 3); @@ -11266,7 +11307,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(oui, 2); STRUCT_CHILD_GETTERS(partNumber, 3); @@ -11337,7 +11378,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(asicSdk, 1); STRUCT_CHILD_GETTERS(saiSdk, 2); STRUCT_CHILD_GETTERS(firmware, 3); @@ -11381,7 +11422,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(v6, 1); STRUCT_CHILD_GETTERS(prefix, 2); STRUCT_CHILD_GETTERS(mask, 3); @@ -11426,7 +11467,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(queues, 1); STRUCT_CHILD_GETTERS(rxReasonToQueue, 2); STRUCT_CHILD_GETTERS(defaultQosPolicy, 3); @@ -11514,7 +11555,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(aclTables, 2); STRUCT_CHILD_GETTERS(stage, 3); @@ -11558,7 +11599,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(version, 1); STRUCT_CHILD_GETTERS(next_hop_prefix, 2); STRUCT_CHILD_GETTERS(next_hop_interface, 3); @@ -11600,7 +11641,7 @@ class ChildThriftPath<::facebook::bgp::nsf_policy::NsfTeWeightEncoding, ::facebo template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(l2_encoding, 1); template @@ -11683,7 +11724,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(frequencyConfig, 1); STRUCT_CHILD_GETTERS(txPower0P01Dbm, 2); STRUCT_CHILD_GETTERS(appSelCode, 3); @@ -11733,7 +11774,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(local_pref, 3); @@ -11789,7 +11830,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(numLanes, 1); STRUCT_CHILD_GETTERS(modulation, 2); STRUCT_CHILD_GETTERS(fec, 3); @@ -11844,7 +11885,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(as_path, 3); @@ -11935,7 +11976,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(trafficClass, 1); STRUCT_CHILD_GETTERS(attr, 2); @@ -12000,7 +12041,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(tx, 2); STRUCT_CHILD_GETTERS(rx, 3); @@ -12047,7 +12088,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(action, 1); STRUCT_CHILD_GETTERS(sendToCPU, 2); @@ -12091,7 +12132,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(wide_metrics_only, 3); @@ -12138,7 +12179,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(types, 2); @@ -12179,7 +12220,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(next_hop_count, 1); STRUCT_CHILD_GETTERS(agg_lbw_bps, 2); @@ -12192,19 +12233,19 @@ std::pair -class ChildThriftPath<::facebook::fboss::cfg::QosRule, ::facebook::fboss::fsdb::FsdbOperStateRoot, Parent> : +class ChildThriftPath<::facebook::neteng::fboss::bgp::thrift::TCapacity, ::facebook::fboss::fsdb::FsdbOperStateRoot, Parent> : public Path< - ::facebook::fboss::cfg::QosRule, + ::facebook::neteng::fboss::bgp::thrift::TCapacity, ::facebook::fboss::fsdb::FsdbOperStateRoot, - ::apache::thrift::type_class::structure, - ::apache::thrift::type::struct_t<::facebook::fboss::cfg::QosRule>, + ::apache::thrift::type_class::variant, + ::apache::thrift::type::union_t<::facebook::neteng::fboss::bgp::thrift::TCapacity>, Parent> { public: using Self = Path< - ::facebook::fboss::cfg::QosRule, + ::facebook::neteng::fboss::bgp::thrift::TCapacity, ::facebook::fboss::fsdb::FsdbOperStateRoot, - ::apache::thrift::type_class::structure, - ::apache::thrift::type::struct_t<::facebook::fboss::cfg::QosRule>, + ::apache::thrift::type_class::variant, + ::apache::thrift::type::union_t<::facebook::neteng::fboss::bgp::thrift::TCapacity>, Parent>; template using Child = Path< @@ -12214,26 +12255,67 @@ class ChildThriftPath<::facebook::fboss::cfg::QosRule, ::facebook::fboss::fsdb:: ChildTag, Self >; - using Children = thriftpath::TypeMap>, -std::pair, ::facebook::fboss::fsdb::FsdbOperStateRoot, Self>>>; + using Children = thriftpath::TypeMap>, +std::pair>>; template using TypeFor = typename Children::template type_of; using Self::Self; - - STRUCT_CHILD_GETTERS(queueId, 1); - STRUCT_CHILD_GETTERS(dscp, 2); + + STRUCT_CHILD_GETTERS(next_hop_count, 1); + STRUCT_CHILD_GETTERS(agg_lbw_bps, 2); template auto operator()(const std::integral_constant&) { - if constexpr (__id == apache::thrift::FieldId{1}) { return queueId(); } - else if constexpr (__id == apache::thrift::FieldId{2}) { return dscp(); } + if constexpr (__id == apache::thrift::FieldId{1}) { return next_hop_count(); } + else if constexpr (__id == apache::thrift::FieldId{2}) { return agg_lbw_bps(); } } }; template -class ChildThriftPath<::facebook::fboss::AlarmThreshold, ::facebook::fboss::fsdb::FsdbOperStateRoot, Parent> : +class ChildThriftPath<::facebook::fboss::cfg::QosRule, ::facebook::fboss::fsdb::FsdbOperStateRoot, Parent> : + public Path< + ::facebook::fboss::cfg::QosRule, + ::facebook::fboss::fsdb::FsdbOperStateRoot, + ::apache::thrift::type_class::structure, + ::apache::thrift::type::struct_t<::facebook::fboss::cfg::QosRule>, + Parent> { + public: + using Self = Path< + ::facebook::fboss::cfg::QosRule, + ::facebook::fboss::fsdb::FsdbOperStateRoot, + ::apache::thrift::type_class::structure, + ::apache::thrift::type::struct_t<::facebook::fboss::cfg::QosRule>, + Parent>; + template + using Child = Path< + ChildType, + ::facebook::fboss::fsdb::FsdbOperStateRoot, + ChildTC, + ChildTag, + Self + >; + using Children = thriftpath::TypeMap>, +std::pair, ::facebook::fboss::fsdb::FsdbOperStateRoot, Self>>>; + + template + using TypeFor = typename Children::template type_of; + using Self::Self; + + STRUCT_CHILD_GETTERS(queueId, 1); + STRUCT_CHILD_GETTERS(dscp, 2); + + template + auto operator()(const std::integral_constant&) { + if constexpr (__id == apache::thrift::FieldId{1}) { return queueId(); } + else if constexpr (__id == apache::thrift::FieldId{2}) { return dscp(); } + } +}; + + +template +class ChildThriftPath<::facebook::fboss::AlarmThreshold, ::facebook::fboss::fsdb::FsdbOperStateRoot, Parent> : public Path< ::facebook::fboss::AlarmThreshold, ::facebook::fboss::fsdb::FsdbOperStateRoot, @@ -12264,7 +12346,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(temp, 1); STRUCT_CHILD_GETTERS(vcc, 2); STRUCT_CHILD_GETTERS(rxPwr, 3); @@ -12332,7 +12414,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(config, 1); STRUCT_CHILD_GETTERS(yamlConfig, 2); @@ -12397,7 +12479,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(destination, 2); STRUCT_CHILD_GETTERS(dscp, 3); @@ -12470,7 +12552,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lane, 1); STRUCT_CHILD_GETTERS(txLos, 2); STRUCT_CHILD_GETTERS(rxLos, 3); @@ -12564,7 +12646,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(fabricPortGroupMap, 1); STRUCT_CHILD_GETTERS(switchIdToFabricPortGroupMap, 2); STRUCT_CHILD_GETTERS(switchIdToLastUpdatedTimestamp, 3); @@ -12608,7 +12690,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lane, 1); STRUCT_CHILD_GETTERS(media, 2); STRUCT_CHILD_GETTERS(code, 3); @@ -12650,7 +12732,7 @@ class ChildThriftPath<::facebook::fboss::PimState, ::facebook::fboss::fsdb::Fsdb template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(errors, 1); template @@ -12739,7 +12821,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(prefix, 1); STRUCT_CHILD_GETTERS(communities, 2); STRUCT_CHILD_GETTERS(minimum_supporting_routes, 3); @@ -12838,7 +12920,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(macAddrToBlockVlanID, 1); STRUCT_CHILD_GETTERS(macAddrToBlockAddr, 2); @@ -12885,7 +12967,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lane, 1); STRUCT_CHILD_GETTERS(signalDetectLive, 2); STRUCT_CHILD_GETTERS(signalDetectChanged, 3); @@ -12937,7 +13019,7 @@ class ChildThriftPath<::facebook::fboss::asic::AsicConfig, ::facebook::fboss::fs template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(config, 1); template @@ -12997,7 +13079,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(srcPort, 1); STRUCT_CHILD_GETTERS(dstPrefix, 2); @@ -13039,7 +13121,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sharedBytes, 1); STRUCT_CHILD_GETTERS(headroomBytes, 2); STRUCT_CHILD_GETTERS(reservedBytes, 3); @@ -13137,7 +13219,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(l2LearningMode, 1); STRUCT_CHILD_GETTERS(qcmEnable, 2); STRUCT_CHILD_GETTERS(ptpTcEnable, 3); @@ -13246,7 +13328,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(spPriority, 1); STRUCT_CHILD_GETTERS(wrrWeight, 2); @@ -13286,7 +13368,7 @@ class ChildThriftPath<::facebook::fboss::cfg::SetTcAction, ::facebook::fboss::fs template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(tcValue, 1); template @@ -13376,7 +13458,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ipInIpTunnelId, 1); STRUCT_CHILD_GETTERS(underlayIntfID, 2); STRUCT_CHILD_GETTERS(dstIp, 3); @@ -13456,7 +13538,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(compare_numeric_value, 2); @@ -13518,7 +13600,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rx, 1); STRUCT_CHILD_GETTERS(tx, 2); @@ -13581,7 +13663,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(asn, 1); STRUCT_CHILD_GETTERS(repeat_times, 2); STRUCT_CHILD_GETTERS(obj_uuid, 100); @@ -13627,7 +13709,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(config, 1); STRUCT_CHILD_GETTERS(switchState, 2); STRUCT_CHILD_GETTERS(fsdbSubscriptions, 4); @@ -13709,7 +13791,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(agingIntervalInMsecs, 1); STRUCT_CHILD_GETTERS(numFlowSamplesPerView, 2); STRUCT_CHILD_GETTERS(flowLimit, 3); @@ -13823,7 +13905,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rack_id, 1); STRUCT_CHILD_GETTERS(plane_id, 2); STRUCT_CHILD_GETTERS(remote_rack_capacity, 3); @@ -13870,7 +13952,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(chip, 1); STRUCT_CHILD_GETTERS(lane, 2); @@ -13908,16 +13990,18 @@ class ChildThriftPath<::facebook::fboss::cfg::RedirectNextHop, ::facebook::fboss using Children = thriftpath::TypeMap>, std::pair>, std::pair>>, -std::pair>>; +std::pair>, +std::pair, ::facebook::fboss::fsdb::FsdbOperStateRoot, Self>>>; template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ip, 1); STRUCT_CHILD_GETTERS(intfID, 2); STRUCT_CHILD_GETTERS(tunnelType, 3); STRUCT_CHILD_GETTERS(tunnelId, 4); + STRUCT_CHILD_GETTERS(srv6SegmentList, 5); template auto operator()(const std::integral_constant&) { @@ -13925,6 +14009,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(dstPrefixLength, 2); @@ -14098,7 +14183,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(switchId, 2); STRUCT_CHILD_GETTERS(type, 3); @@ -14216,7 +14301,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(portMaps, 100); STRUCT_CHILD_GETTERS(vlanMaps, 101); STRUCT_CHILD_GETTERS(aclMaps, 102); @@ -14330,7 +14415,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(portId, 1); STRUCT_CHILD_GETTERS(portType, 2); @@ -14393,7 +14478,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(seg_type, 1); STRUCT_CHILD_GETTERS(asns, 2); STRUCT_CHILD_GETTERS(asns_4_byte, 3); @@ -14481,7 +14566,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(interfaceId, 1); STRUCT_CHILD_GETTERS(routerId, 2); STRUCT_CHILD_GETTERS(vlanId, 3); @@ -14570,7 +14655,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(host, 1); STRUCT_CHILD_GETTERS(port, 2); @@ -14612,7 +14697,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(nexthops_DEPRECATED, 1); STRUCT_CHILD_GETTERS(redirectNextHops, 2); STRUCT_CHILD_GETTERS(redirectNextHopGroup, 3); @@ -14697,7 +14782,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(action, 1); STRUCT_CHILD_GETTERS(sendToCPU, 2); @@ -14759,7 +14844,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(value, 1); STRUCT_CHILD_GETTERS(mask, 2); @@ -14843,7 +14928,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(mediaInterfaceCode, 1); STRUCT_CHILD_GETTERS(supportedFirmwareVersions, 2); STRUCT_CHILD_GETTERS(supportedPortProfiles, 3); @@ -14885,7 +14970,7 @@ class ChildThriftPath<::facebook::bgp::rib_policy::TRouteAttributeLbwAction, ::f template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lbw, 1); template @@ -14927,7 +15012,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(type, 1); STRUCT_CHILD_GETTERS(name, 2); STRUCT_CHILD_GETTERS(description, 3); @@ -14974,7 +15059,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(matcher, 1); STRUCT_CHILD_GETTERS(action, 2); @@ -15015,7 +15100,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ip, 1); STRUCT_CHILD_GETTERS(prefixLength, 2); @@ -15111,7 +15196,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(name, 2); STRUCT_CHILD_GETTERS(description, 3); @@ -15248,12 +15333,13 @@ std::pair, ::facebook::fboss::fsdb::FsdbOperStateRoot, Self>>, std::pair>, std::pair>, -std::pair>>; +std::pair>, +std::pair>>; template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(priority, 1); STRUCT_CHILD_GETTERS(name, 2); STRUCT_CHILD_GETTERS(srcIp, 3); @@ -15289,6 +15375,7 @@ std::pair auto operator()(const std::integral_constant&) { @@ -15327,6 +15414,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rx, 1); STRUCT_CHILD_GETTERS(tx, 2); @@ -15523,7 +15611,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(l2LearningMode, 1); STRUCT_CHILD_GETTERS(qcmEnable, 2); STRUCT_CHILD_GETTERS(ptpTcEnable, 3); @@ -15703,7 +15791,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(value, 1); STRUCT_CHILD_GETTERS(compare_operator, 2); @@ -15793,7 +15881,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(dscpMap, 2); STRUCT_CHILD_GETTERS(expMap, 3); @@ -15852,7 +15940,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(tx, 1); STRUCT_CHILD_GETTERS(rx, 2); STRUCT_CHILD_GETTERS(portPgConfigName, 3); @@ -15901,7 +15989,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(asn, 1); STRUCT_CHILD_GETTERS(ip, 2); @@ -16040,7 +16128,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(minLimitBytes, 2); STRUCT_CHILD_GETTERS(headroomLimitBytes, 3); @@ -16109,7 +16197,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lowestAdminDistanceClientId, 1); STRUCT_CHILD_GETTERS(client2NextHopEntry, 2); @@ -16151,7 +16239,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(min_step_bps, 1); STRUCT_CHILD_GETTERS(error_pct_threshold, 2); STRUCT_CHILD_GETTERS(fixed_quantized_bps_list, 3); @@ -16217,7 +16305,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ip, 1); STRUCT_CHILD_GETTERS(udpSrcPort, 2); STRUCT_CHILD_GETTERS(udpDstPort, 3); @@ -16316,7 +16404,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(vlanId, 1); STRUCT_CHILD_GETTERS(vlanName, 2); STRUCT_CHILD_GETTERS(intfID, 3); @@ -16449,7 +16537,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(srcIp, 1); STRUCT_CHILD_GETTERS(dstIp, 2); STRUCT_CHILD_GETTERS(srcMac, 3); @@ -16503,7 +16591,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(vlanID, 1); STRUCT_CHILD_GETTERS(logicalPort, 2); STRUCT_CHILD_GETTERS(spanningTreeState, 3); @@ -16551,7 +16639,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(max_routes, 1); STRUCT_CHILD_GETTERS(warning_only, 2); STRUCT_CHILD_GETTERS(warning_limit, 3); @@ -16615,7 +16703,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(vlanID, 1); STRUCT_CHILD_GETTERS(ipAddress, 2); @@ -16699,7 +16787,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(action, 1); STRUCT_CHILD_GETTERS(swapLabel, 2); STRUCT_CHILD_GETTERS(pushLabels, 3); @@ -16742,7 +16830,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ext_communities, 1); STRUCT_CHILD_GETTERS(obj_uuid, 100); @@ -16825,7 +16913,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(community_list, 1); STRUCT_CHILD_GETTERS(community_list_name, 2); @@ -16924,7 +17012,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(version, 1); STRUCT_CHILD_GETTERS(ports, 2); STRUCT_CHILD_GETTERS(vlans, 3); @@ -17084,7 +17172,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(match_logic_type, 3); @@ -17131,7 +17219,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(prefix_list, 1); STRUCT_CHILD_GETTERS(prefix_list_name, 2); @@ -17218,7 +17306,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(next_hop, 1); STRUCT_CHILD_GETTERS(as_path, 2); STRUCT_CHILD_GETTERS(communities, 3); @@ -17332,7 +17420,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(scalingFactor, 2); STRUCT_CHILD_GETTERS(loadWeight, 3); @@ -17398,7 +17486,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(action, 1); STRUCT_CHILD_GETTERS(resolvedNexthops, 2); @@ -17439,7 +17527,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(address, 2); @@ -17501,7 +17589,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(linkCount, 1); STRUCT_CHILD_GETTERS(linkPercentage, 2); @@ -17545,7 +17633,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lane, 1); STRUCT_CHILD_GETTERS(txDisable, 2); STRUCT_CHILD_GETTERS(txSquelch, 3); @@ -17612,7 +17700,7 @@ class ChildThriftPath<::facebook::fboss::cfg::SystemPortRanges, ::facebook::fbos template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(systemPortRanges, 1); template @@ -17673,7 +17761,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(min, 1); STRUCT_CHILD_GETTERS(max, 2); STRUCT_CHILD_GETTERS(invert, 3); @@ -17716,7 +17804,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ingressLabel, 1); STRUCT_CHILD_GETTERS(nexthops, 2); @@ -17758,7 +17846,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(stage, 1); STRUCT_CHILD_GETTERS(name, 2); STRUCT_CHILD_GETTERS(aclTableMap, 3); @@ -17844,7 +17932,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(internalTrafficClass, 1); STRUCT_CHILD_GETTERS(fromPcpToTrafficClass, 2); STRUCT_CHILD_GETTERS(fromTrafficClassToPcp, 3); @@ -17888,7 +17976,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(udfGroup, 1); STRUCT_CHILD_GETTERS(roceBytes, 2); STRUCT_CHILD_GETTERS(roceMask, 3); @@ -17932,7 +18020,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(shelSrcIp, 1); STRUCT_CHILD_GETTERS(shelDstIp, 2); STRUCT_CHILD_GETTERS(shelPeriodicIntervalMS, 3); @@ -17983,7 +18071,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(base_prefix, 1); STRUCT_CHILD_GETTERS(seq_num, 2); STRUCT_CHILD_GETTERS(prefix_len_ranges, 3); @@ -18044,7 +18132,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(priority, 2); STRUCT_CHILD_GETTERS(aclEntries, 3); @@ -18094,7 +18182,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(internalTrafficClass, 1); STRUCT_CHILD_GETTERS(fromExpToTrafficClass, 2); STRUCT_CHILD_GETTERS(fromTrafficClassToExp, 3); @@ -18310,12 +18398,14 @@ std::pair, ::facebook::fboss::fsdb::FsdbOperStateRoot, Self>>, std::pair, ::facebook::fboss::fsdb::FsdbOperStateRoot, Self>>, std::pair, ::facebook::fboss::fsdb::FsdbOperStateRoot, Self>>, -std::pair>>; +std::pair>, +std::pair>, +std::pair>>; template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(srcIp, 3); STRUCT_CHILD_GETTERS(dstIp, 4); STRUCT_CHILD_GETTERS(srcL4PortRange_DEPRECATED, 5); @@ -18349,6 +18439,8 @@ std::pair auto operator()(const std::integral_constant&) { @@ -18385,6 +18477,8 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(matchToAction, 1); STRUCT_CHILD_GETTERS(defaultQosPolicy, 2); STRUCT_CHILD_GETTERS(portIdToQosPolicy, 3); @@ -18527,7 +18621,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(defaultCommandLineArgs, 1); STRUCT_CHILD_GETTERS(sw, 2); STRUCT_CHILD_GETTERS(platform, 3); @@ -18638,7 +18732,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(memberPortID, 1); STRUCT_CHILD_GETTERS(priority, 2); STRUCT_CHILD_GETTERS(rate, 3); @@ -18707,7 +18801,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(type, 1); STRUCT_CHILD_GETTERS(encoding_scheme, 2); STRUCT_CHILD_GETTERS(encoding_id, 3); @@ -18751,7 +18845,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(bcm, 1); STRUCT_CHILD_GETTERS(asic, 2); STRUCT_CHILD_GETTERS(asicConfig, 3); @@ -18793,7 +18887,7 @@ class ChildThriftPath<::facebook::fboss::cfg::QueueCongestionDetection, ::facebo template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(linear, 1); template @@ -18855,7 +18949,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(coreToUse, 1); STRUCT_CHILD_GETTERS(path, 2); STRUCT_CHILD_GETTERS(logPath, 3); @@ -18933,7 +19027,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(remote_as, 3); @@ -19048,7 +19142,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(id, 2); STRUCT_CHILD_GETTERS(recordStats, 3); @@ -19127,7 +19221,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(internalTrafficClass, 1); STRUCT_CHILD_GETTERS(fromDscpToTrafficClass, 2); STRUCT_CHILD_GETTERS(fromTrafficClassToDscp, 3); @@ -19191,7 +19285,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(tcvrProgrammingStartTs, 1); STRUCT_CHILD_GETTERS(tcvrProgrammingCompleteTs, 2); @@ -19232,7 +19326,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(match_type, 1); STRUCT_CHILD_GETTERS(community, 2); @@ -19277,7 +19371,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(flow, 1); STRUCT_CHILD_GETTERS(nexthops, 3); STRUCT_CHILD_GETTERS(resolvedNexthops, 4); @@ -19346,7 +19440,7 @@ class ChildThriftPath<::facebook::fboss::cfg::UserDefinedTrapAction, ::facebook: template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(queueId, 1); template @@ -19406,7 +19500,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lanes, 1); STRUCT_CHILD_GETTERS(linkTrainingStatus, 2); @@ -19469,7 +19563,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(addr, 1); STRUCT_CHILD_GETTERS(port, 2); STRUCT_CHILD_GETTERS(ifName, 3); @@ -19513,7 +19607,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(routerID, 1); STRUCT_CHILD_GETTERS(prefix, 2); STRUCT_CHILD_GETTERS(nexthops, 3); @@ -19579,7 +19673,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(type, 2); STRUCT_CHILD_GETTERS(physicalID, 3); @@ -19655,7 +19749,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ipTunnelId, 1); STRUCT_CHILD_GETTERS(underlayIntfId, 2); STRUCT_CHILD_GETTERS(mode, 3); @@ -19715,7 +19809,7 @@ class ChildThriftPath<::facebook::fboss::cfg::QueueMatchAction, ::facebook::fbos template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(queueId, 1); template @@ -19754,7 +19848,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(vlanID, 1); STRUCT_CHILD_GETTERS(macAddress, 2); @@ -19794,7 +19888,7 @@ class ChildThriftPath<::facebook::fboss::cfg::PacketCounterMatchAction, ::facebo template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(counterName, 1); template @@ -19908,7 +20002,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sendToQueue, 1); STRUCT_CHILD_GETTERS(packetCounter_DEPRECATED, 2); STRUCT_CHILD_GETTERS(setDscp, 3); @@ -19973,7 +20067,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(flowId, 1); STRUCT_CHILD_GETTERS(action, 2); @@ -20014,7 +20108,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(tx, 1); STRUCT_CHILD_GETTERS(rx, 2); @@ -20055,7 +20149,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(startTime, 1); STRUCT_CHILD_GETTERS(fsdbStatsPublishIntervalMsec, 2); @@ -20142,7 +20236,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(type_high, 1); STRUCT_CHILD_GETTERS(type_low, 2); STRUCT_CHILD_GETTERS(value, 3); @@ -20213,7 +20307,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(detectionTimeMsecs, 1); STRUCT_CHILD_GETTERS(recoveryTimeMsecs, 2); STRUCT_CHILD_GETTERS(recoveryAction, 3); @@ -20256,7 +20350,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(as_path, 1); STRUCT_CHILD_GETTERS(as_path_name, 2); @@ -20322,7 +20416,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(policy_version, 3); @@ -20377,7 +20471,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(algorithm, 2); STRUCT_CHILD_GETTERS(seed, 3); @@ -20452,7 +20546,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(min, 1); STRUCT_CHILD_GETTERS(max, 2); STRUCT_CHILD_GETTERS(invert, 3); @@ -20502,7 +20596,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(prefix, 1); STRUCT_CHILD_GETTERS(paths, 2); STRUCT_CHILD_GETTERS(best_group, 3); @@ -20640,7 +20734,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ctlCode, 1); STRUCT_CHILD_GETTERS(dspMode, 2); STRUCT_CHILD_GETTERS(afeTrim, 3); @@ -20787,7 +20881,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(chip, 1); STRUCT_CHILD_GETTERS(platformSettings, 3); STRUCT_CHILD_GETTERS(switchIndexToSwitchId, 4); @@ -20856,7 +20950,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ipAddress, 1); STRUCT_CHILD_GETTERS(mac, 2); STRUCT_CHILD_GETTERS(interfaceId, 3); @@ -20919,7 +21013,7 @@ class ChildThriftPath<::facebook::fboss::cfg::SetEcmpHashAction, ::facebook::fbo template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(switchingMode, 1); template @@ -20958,7 +21052,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(vendorName, 1); STRUCT_CHILD_GETTERS(partNumberToTransceiverAttributes, 2); @@ -21080,7 +21174,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(intfID, 1); STRUCT_CHILD_GETTERS(routerID, 2); STRUCT_CHILD_GETTERS(vlanID, 3); @@ -21200,7 +21294,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(is_partially_drained, 1); STRUCT_CHILD_GETTERS(num_affected_prefixes, 2); STRUCT_CHILD_GETTERS(partial_drain_transition_count, 3); @@ -21280,7 +21374,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(logicalID, 1); STRUCT_CHILD_GETTERS(state, 2); STRUCT_CHILD_GETTERS(minFrameSize, 3); @@ -21417,7 +21511,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(routerID, 1); STRUCT_CHILD_GETTERS(prefix, 2); STRUCT_CHILD_GETTERS(nexthops, 3); @@ -21523,7 +21617,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(pktsPerSec, 1); STRUCT_CHILD_GETTERS(kbitsPerSec, 2); @@ -21585,7 +21679,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ip, 1); STRUCT_CHILD_GETTERS(port, 2); @@ -21647,7 +21741,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(minimum, 1); STRUCT_CHILD_GETTERS(maximum, 2); @@ -21689,7 +21783,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(afi, 1); STRUCT_CHILD_GETTERS(prefix_bin, 2); STRUCT_CHILD_GETTERS(num_bits, 3); @@ -21732,7 +21826,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sakKey, 1); STRUCT_CHILD_GETTERS(sak, 2); @@ -21776,7 +21870,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(id, 1); STRUCT_CHILD_GETTERS(priority, 2); STRUCT_CHILD_GETTERS(lacpPortRate, 3); @@ -21830,7 +21924,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(description, 2); STRUCT_CHILD_GETTERS(version, 3); @@ -21886,7 +21980,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(trafficPolicy, 1); STRUCT_CHILD_GETTERS(rxReasonToCPUQueue, 2); STRUCT_CHILD_GETTERS(rxReasonToQueueOrderedList, 3); @@ -21947,7 +22041,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(agent, 1); STRUCT_CHILD_GETTERS(qsfp_service, 3); STRUCT_CHILD_GETTERS(sensor_service, 4); @@ -21992,7 +22086,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(maxAlarmVal, 3); STRUCT_CHILD_GETTERS(minAlarmVal, 4); STRUCT_CHILD_GETTERS(upperCriticalVal, 5); @@ -22037,7 +22131,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(high, 1); STRUCT_CHILD_GETTERS(low, 2); @@ -22104,7 +22198,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(preFecBerMediaMin, 1); STRUCT_CHILD_GETTERS(preFecBerMediaMax, 2); STRUCT_CHILD_GETTERS(preFecBerMediaAvg, 3); @@ -22212,7 +22306,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sensor, 1); STRUCT_CHILD_GETTERS(channels, 2); STRUCT_CHILD_GETTERS(stats, 3); @@ -22288,7 +22382,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(value, 2); STRUCT_CHILD_GETTERS(timeStamp, 3); @@ -22339,7 +22433,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(value, 1); STRUCT_CHILD_GETTERS(flags, 2); @@ -22382,7 +22476,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(mediaPortVdmStats, 1); STRUCT_CHILD_GETTERS(hostPortVdmStats, 2); STRUCT_CHILD_GETTERS(statsCollectionTme, 3); @@ -22460,7 +22554,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(datapathBER, 1); STRUCT_CHILD_GETTERS(datapathErroredFrames, 2); STRUCT_CHILD_GETTERS(laneSNR, 3); @@ -22592,7 +22686,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(readDownTime, 1); STRUCT_CHILD_GETTERS(writeDownTime, 2); STRUCT_CHILD_GETTERS(numReadAttempted, 3); @@ -22656,7 +22750,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(cd, 1); STRUCT_CHILD_GETTERS(dgd, 2); STRUCT_CHILD_GETTERS(sopmd, 3); @@ -22727,7 +22821,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(temp, 1); STRUCT_CHILD_GETTERS(vcc, 2); @@ -22768,7 +22862,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(alarm, 1); STRUCT_CHILD_GETTERS(warn, 2); @@ -22811,7 +22905,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(min, 1); STRUCT_CHILD_GETTERS(max, 2); STRUCT_CHILD_GETTERS(avg, 3); @@ -22857,7 +22951,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(mediaPortVdmStats, 1); STRUCT_CHILD_GETTERS(hostPortVdmStats, 2); STRUCT_CHILD_GETTERS(statsCollectionTme, 3); @@ -22908,7 +23002,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rxBitsPm, 1); STRUCT_CHILD_GETTERS(rxBitsSubIntPm, 2); STRUCT_CHILD_GETTERS(rxCorrBitsPm, 3); @@ -22965,7 +23059,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(media, 1); STRUCT_CHILD_GETTERS(host, 2); @@ -23027,7 +23121,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(channel, 1); STRUCT_CHILD_GETTERS(sensors, 6); @@ -23073,7 +23167,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rxPwr, 1); STRUCT_CHILD_GETTERS(txBias, 2); STRUCT_CHILD_GETTERS(txPwr, 3); @@ -23132,7 +23226,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(datapathBERMax, 1); STRUCT_CHILD_GETTERS(datapathErroredFramesMax, 2); STRUCT_CHILD_GETTERS(laneSNRMin, 3); @@ -23197,7 +23291,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(fdrRciWatermarkBytes, 1); STRUCT_CHILD_GETTERS(coreRciWatermarkBytes, 2); STRUCT_CHILD_GETTERS(dtlQueueWatermarkBytes, 3); @@ -23316,7 +23410,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(globalDrops, 1); STRUCT_CHILD_GETTERS(globalReachabilityDrops, 2); STRUCT_CHILD_GETTERS(packetIntegrityDrops, 3); @@ -23441,7 +23535,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(queueInPackets_, 1); STRUCT_CHILD_GETTERS(queueDiscardPackets_, 2); STRUCT_CHILD_GETTERS(queueToName_, 3); @@ -23532,7 +23626,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(readDownTime, 1); STRUCT_CHILD_GETTERS(writeDownTime, 2); STRUCT_CHILD_GETTERS(numReadAttempted, 3); @@ -23602,7 +23696,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(bytes, 1); STRUCT_CHILD_GETTERS(packets, 2); @@ -23643,7 +23737,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(macAddress, 1); STRUCT_CHILD_GETTERS(port, 2); @@ -23704,7 +23798,7 @@ class ChildThriftPath<::facebook::fboss::stats::SensorServiceStats, ::facebook:: template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sensorData, 1); template @@ -23811,7 +23905,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(correctedCodewords, 1); STRUCT_CHILD_GETTERS(uncorrectedCodewords, 2); STRUCT_CHILD_GETTERS(correctedBits, 3); @@ -23891,7 +23985,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(modulatorBiasXI, 1); STRUCT_CHILD_GETTERS(modulatorBiasXQ, 2); STRUCT_CHILD_GETTERS(modulatorBiasYI, 3); @@ -23954,7 +24048,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(queueOutDiscardBytes_, 1); STRUCT_CHILD_GETTERS(queueOutBytes_, 2); STRUCT_CHILD_GETTERS(queueWatermarkBytes_, 3); @@ -24019,7 +24113,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(statsEventSyncActive, 1); STRUCT_CHILD_GETTERS(fdbEventSyncActive, 2); STRUCT_CHILD_GETTERS(linkEventSyncActive, 3); @@ -24115,7 +24209,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(hwPortStats, 1); STRUCT_CHILD_GETTERS(hwTrunkStats, 2); STRUCT_CHILD_GETTERS(hwResourceStats, 3); @@ -24239,7 +24333,90 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + + STRUCT_CHILD_GETTERS(width, 1); + STRUCT_CHILD_GETTERS(height, 2); + + template + auto operator()(const std::integral_constant&) { + if constexpr (__id == apache::thrift::FieldId{1}) { return width(); } + else if constexpr (__id == apache::thrift::FieldId{2}) { return height(); } + } +}; + +template +class ChildThriftPath<::std::map<::std::int16_t, ::facebook::fboss::HwSwitchDropStats>, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Parent> : + public Path< + ::std::map<::std::int16_t, ::facebook::fboss::HwSwitchDropStats>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::map<::apache::thrift::type_class::integral, ::apache::thrift::type_class::structure>, + ::apache::thrift::type::map<::apache::thrift::type::i16_t, ::apache::thrift::type::struct_t<::facebook::fboss::HwSwitchDropStats>>, + Parent> { + public: + using Self = Path< + ::std::map<::std::int16_t, ::facebook::fboss::HwSwitchDropStats>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::map<::apache::thrift::type_class::integral, ::apache::thrift::type_class::structure>, + ::apache::thrift::type::map<::apache::thrift::type::i16_t, ::apache::thrift::type::struct_t<::facebook::fboss::HwSwitchDropStats>>, + Parent>; + using Child = ChildThriftPath<::facebook::fboss::HwSwitchDropStats, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Self>; + using Self::Self; + + CONTAINER_CHILD_GETTERS(::std::int16_t); +}; + +template +class ChildThriftPath, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Parent> : + public Path< + folly::F14FastMap<::std::string, ::facebook::fboss::HwPortStats>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::map<::apache::thrift::type_class::string, ::apache::thrift::type_class::structure>, + ::apache::thrift::type::map<::apache::thrift::type::string_t, ::apache::thrift::type::struct_t<::facebook::fboss::HwPortStats>>, + Parent> { + public: + using Self = Path< + folly::F14FastMap<::std::string, ::facebook::fboss::HwPortStats>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::map<::apache::thrift::type_class::string, ::apache::thrift::type_class::structure>, + ::apache::thrift::type::map<::apache::thrift::type::string_t, ::apache::thrift::type::struct_t<::facebook::fboss::HwPortStats>>, + Parent>; + using Child = ChildThriftPath<::facebook::fboss::HwPortStats, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Self>; + using Self::Self; + + CONTAINER_CHILD_GETTERS(::std::string); +}; + + +template +class ChildThriftPath<::facebook::fboss::phy::EyeInfo, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Parent> : + public Path< + ::facebook::fboss::phy::EyeInfo, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::structure, + ::apache::thrift::type::struct_t<::facebook::fboss::phy::EyeInfo>, + Parent> { + public: + using Self = Path< + ::facebook::fboss::phy::EyeInfo, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::structure, + ::apache::thrift::type::struct_t<::facebook::fboss::phy::EyeInfo>, + Parent>; + template + using Child = Path< + ChildType, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ChildTC, + ChildTag, + Self + >; + using Children = thriftpath::TypeMap>, +std::pair>>; + + template + using TypeFor = typename Children::template type_of; + using Self::Self; + STRUCT_CHILD_GETTERS(width, 1); STRUCT_CHILD_GETTERS(height, 2); @@ -24342,7 +24519,7 @@ class ChildThriftPath<::facebook::fboss::phy::PcsStats, ::facebook::fboss::fsdb: template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rsFec, 1); template @@ -24402,7 +24579,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(capacity_, 1); STRUCT_CHILD_GETTERS(inBytes_, 2); STRUCT_CHILD_GETTERS(inUnicastPkts_, 3); @@ -24488,7 +24665,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(mismatchCount, 1); STRUCT_CHILD_GETTERS(missingCount, 2); STRUCT_CHILD_GETTERS(virtualDevicesWithAsymmetricConnectivity, 3); @@ -24536,7 +24713,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(phyStats, 1); STRUCT_CHILD_GETTERS(tcvrStats, 2); STRUCT_CHILD_GETTERS(portStats, 3); @@ -24579,7 +24756,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(hwTeFlowStats, 1); STRUCT_CHILD_GETTERS(timestamp, 2); @@ -24672,7 +24849,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ingressMacDropBitmap, 1); STRUCT_CHILD_GETTERS(egressPipeDropBitmap, 2); STRUCT_CHILD_GETTERS(egressMacDropBitmap, 3); @@ -24797,7 +24974,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(name, 1); STRUCT_CHILD_GETTERS(value, 2); STRUCT_CHILD_GETTERS(timeStamp, 3); @@ -24839,7 +25016,7 @@ class ChildThriftPath<::facebook::fboss::HwTeFlowStats, ::facebook::fboss::fsdb: template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(bytes, 1); template @@ -24937,7 +25114,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(parityErrors, 1); STRUCT_CHILD_GETTERS(correctedParityErrors, 2); STRUCT_CHILD_GETTERS(uncorrectedParityErrors, 3); @@ -25114,7 +25291,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(directionIngress, 1); STRUCT_CHILD_GETTERS(ucastUncontrolledPkts, 2); STRUCT_CHILD_GETTERS(ucastControlledPkts, 3); @@ -25254,7 +25431,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(saId, 1); STRUCT_CHILD_GETTERS(saStats, 2); @@ -25357,7 +25534,108 @@ class ChildThriftPath<::facebook::fboss::HwBufferPoolStats, ::facebook::fboss::f template using TypeFor = typename Children::template type_of; using Self::Self; - + + STRUCT_CHILD_GETTERS(deviceWatermarkBytes, 1); + + template + auto operator()(const std::integral_constant&) { + if constexpr (__id == apache::thrift::FieldId{1}) { return deviceWatermarkBytes(); } + } +}; + +template +class ChildThriftPath<::std::set<::std::string>, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Parent> : + public Path< + ::std::set<::std::string>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::set<::apache::thrift::type_class::string>, + ::apache::thrift::type::set<::apache::thrift::type::string_t>, + Parent> { + public: + using Self = Path< + ::std::set<::std::string>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::set<::apache::thrift::type_class::string>, + ::apache::thrift::type::set<::apache::thrift::type::string_t>, + Parent>; + using Child = Path<::std::string, ::facebook::fboss::fsdb::FsdbOperStatsRoot, ::apache::thrift::type_class::string, ::apache::thrift::type::string_t, Self>; + using Self::Self; + + CONTAINER_CHILD_GETTERS(::std::string); +}; + +template +class ChildThriftPath<::std::map<::std::string, ::facebook::fboss::HwTrunkStats>, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Parent> : + public Path< + ::std::map<::std::string, ::facebook::fboss::HwTrunkStats>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::map<::apache::thrift::type_class::string, ::apache::thrift::type_class::structure>, + ::apache::thrift::type::map<::apache::thrift::type::string_t, ::apache::thrift::type::struct_t<::facebook::fboss::HwTrunkStats>>, + Parent> { + public: + using Self = Path< + ::std::map<::std::string, ::facebook::fboss::HwTrunkStats>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::map<::apache::thrift::type_class::string, ::apache::thrift::type_class::structure>, + ::apache::thrift::type::map<::apache::thrift::type::string_t, ::apache::thrift::type::struct_t<::facebook::fboss::HwTrunkStats>>, + Parent>; + using Child = ChildThriftPath<::facebook::fboss::HwTrunkStats, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Self>; + using Self::Self; + + CONTAINER_CHILD_GETTERS(::std::string); +}; + +template +class ChildThriftPath<::std::map<::std::int32_t, ::std::int64_t>, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Parent> : + public Path< + ::std::map<::std::int32_t, ::std::int64_t>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::map<::apache::thrift::type_class::integral, ::apache::thrift::type_class::integral>, + ::apache::thrift::type::map<::apache::thrift::type::i32_t, ::apache::thrift::type::i64_t>, + Parent> { + public: + using Self = Path< + ::std::map<::std::int32_t, ::std::int64_t>, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::map<::apache::thrift::type_class::integral, ::apache::thrift::type_class::integral>, + ::apache::thrift::type::map<::apache::thrift::type::i32_t, ::apache::thrift::type::i64_t>, + Parent>; + using Child = Path<::std::int64_t, ::facebook::fboss::fsdb::FsdbOperStatsRoot, ::apache::thrift::type_class::integral, ::apache::thrift::type::i64_t, Self>; + using Self::Self; + + CONTAINER_CHILD_GETTERS(::std::int32_t); +}; + + +template +class ChildThriftPath<::facebook::fboss::HwBufferPoolStats, ::facebook::fboss::fsdb::FsdbOperStatsRoot, Parent> : + public Path< + ::facebook::fboss::HwBufferPoolStats, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::structure, + ::apache::thrift::type::struct_t<::facebook::fboss::HwBufferPoolStats>, + Parent> { + public: + using Self = Path< + ::facebook::fboss::HwBufferPoolStats, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ::apache::thrift::type_class::structure, + ::apache::thrift::type::struct_t<::facebook::fboss::HwBufferPoolStats>, + Parent>; + template + using Child = Path< + ChildType, + ::facebook::fboss::fsdb::FsdbOperStatsRoot, + ChildTC, + ChildTag, + Self + >; + using Children = thriftpath::TypeMap>>; + + template + using TypeFor = typename Children::template type_of; + using Self::Self; + STRUCT_CHILD_GETTERS(deviceWatermarkBytes, 1); template @@ -25527,7 +25805,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(inBytes_, 1); STRUCT_CHILD_GETTERS(inUnicastPkts_, 2); STRUCT_CHILD_GETTERS(inMulticastPkts_, 3); @@ -25798,7 +26076,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(hw_table_stats_stale, 1); STRUCT_CHILD_GETTERS(l3_host_max, 2); STRUCT_CHILD_GETTERS(l3_host_used, 3); @@ -25965,7 +26243,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(defaultAclStats, 1); STRUCT_CHILD_GETTERS(controlAclStats, 2); STRUCT_CHILD_GETTERS(flowAclStats, 3); @@ -26008,7 +26286,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(l3EcmpDlbFailPackets, 1); STRUCT_CHILD_GETTERS(l3EcmpDlbPortReassignmentCount, 2); @@ -26070,7 +26348,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sci, 1); STRUCT_CHILD_GETTERS(assocNum, 2); @@ -26110,7 +26388,7 @@ class ChildThriftPath<::facebook::fboss::HwSwitchCounterStats, ::facebook::fboss template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(routeCounters, 1); template @@ -26165,7 +26443,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(preMacsecDropPkts, 1); STRUCT_CHILD_GETTERS(controlPkts, 2); STRUCT_CHILD_GETTERS(dataPkts, 3); @@ -26251,7 +26529,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(directionIngress, 1); STRUCT_CHILD_GETTERS(octetsEncrypted, 2); STRUCT_CHILD_GETTERS(octetsProtected, 3); @@ -26321,7 +26599,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lane, 1); STRUCT_CHILD_GETTERS(eyes, 2); STRUCT_CHILD_GETTERS(snr, 3); @@ -26458,7 +26736,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(inBytes_, 1); STRUCT_CHILD_GETTERS(inPkts_, 2); STRUCT_CHILD_GETTERS(outBytes_, 3); @@ -26511,7 +26789,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(sci, 1); STRUCT_CHILD_GETTERS(flowStats, 2); @@ -26558,7 +26836,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(rxCells, 1); STRUCT_CHILD_GETTERS(txCells, 2); STRUCT_CHILD_GETTERS(rxBytes, 3); @@ -26617,7 +26895,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(ingressPortStats, 1); STRUCT_CHILD_GETTERS(egressPortStats, 2); STRUCT_CHILD_GETTERS(ingressFlowStats, 3); @@ -26671,7 +26949,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(side, 1); STRUCT_CHILD_GETTERS(pcs, 2); STRUCT_CHILD_GETTERS(pmd, 3); @@ -26759,7 +27037,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(system, 1); STRUCT_CHILD_GETTERS(line, 2); STRUCT_CHILD_GETTERS(linkFlapCount, 3); @@ -26828,7 +27106,7 @@ std::pair using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(nbitSymbolErrorMax, 1); STRUCT_CHILD_GETTERS(nbitSymbolErrorAvg, 2); STRUCT_CHILD_GETTERS(nbitSymbolErrorCur, 3); @@ -26870,7 +27148,7 @@ class ChildThriftPath<::facebook::fboss::phy::PmdStats, ::facebook::fboss::fsdb: template using TypeFor = typename Children::template type_of; using Self::Self; - + STRUCT_CHILD_GETTERS(lanes, 1); template