Skip to content

Commit 64ea7d1

Browse files
huruinanmeta-codesync[bot]
authored andcommitted
Add Port.linkScanMode
Summary: Adds the per-port `linkScanMode` config that later diffs use to pick the linkscan mode. This diff is config and state plumbing only -- nothing reads the setting yet, so behavior is unchanged. - `switch_config.thrift`: new `LinkScanMode` enum (`SOFTWARE` / `HARDWARE`) plus `PortConfig.linkScanMode` (field 45). Leaving the field unset means FBOSS never programs the mode and leaves whatever the SDK came up with alone; either value is written down to the SDK. - `switch_state.thrift` / `state/Port.h`: matching `PortFields` field 73 plus getter/setter, so the setting is warmboot-serialized like the rest of the port fields. - `ApplyThriftConfig.cpp`: propagates config to switch state. `fsdb_model_thriftpath.h` is regenerated via `buck2 run fbcode//fboss/fsdb/if/oss:sync_model_thriftpath`, as its CI verify step requires. Reviewed By: jasmeetbagga Differential Revision: D116373299 fbshipit-source-id: bd32ee3006c9227f69dd011e489f0613d4e6328d
1 parent 2c8153f commit 64ea7d1

6 files changed

Lines changed: 87 additions & 0 deletions

File tree

fboss/agent/ApplyThriftConfig.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3241,6 +3241,7 @@ shared_ptr<Port> ThriftConfigApplier::updatePort(
32413241
orig->getRxPrecoding().value_or(false) &&
32423242
portConf->rxPrecoding().has_value() ==
32433243
orig->getRxPrecoding().has_value() &&
3244+
portConf->linkScanMode().to_optional() == orig->getLinkScanMode() &&
32443245
portConf->portDownHoldoffTimeMs().value_or(0) ==
32453246
orig->getPortDownHoldoffTimeMs().value_or(0) &&
32463247
portConf->portDownHoldoffTimeMs().has_value() ==
@@ -3358,6 +3359,7 @@ shared_ptr<Port> ThriftConfigApplier::updatePort(
33583359
} else {
33593360
newPort->setRxPrecoding(std::nullopt);
33603361
}
3362+
newPort->setLinkScanMode(portConf->linkScanMode().to_optional());
33613363
if (portConf->portDownHoldoffTimeMs().has_value()) {
33623364
auto v = portConf->portDownHoldoffTimeMs().value();
33633365
if (v < 0) {

fboss/agent/state/Port.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,23 @@ class Port : public ThriftStructNode<Port, state::PortFields> {
941941
}
942942
}
943943

944+
/** @brief Get who notices link status changes: the SDK or the ASIC */
945+
std::optional<cfg::LinkScanMode> getLinkScanMode() const {
946+
if (auto linkScanMode = cref<switch_state_tags::linkScanMode>()) {
947+
return linkScanMode->toThrift();
948+
}
949+
return std::nullopt;
950+
}
951+
952+
/** @brief Set who notices link status changes: the SDK or the ASIC */
953+
void setLinkScanMode(std::optional<cfg::LinkScanMode> linkScanMode) {
954+
if (!linkScanMode.has_value()) {
955+
ref<switch_state_tags::linkScanMode>().reset();
956+
} else {
957+
set<switch_state_tags::linkScanMode>(linkScanMode.value());
958+
}
959+
}
960+
944961
std::optional<int32_t> getPortSwitchId() const {
945962
if (auto portSwitchId = cref<switch_state_tags::portSwitchId>()) {
946963
return portSwitchId->cref();

fboss/agent/state/tests/PortTests.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,50 @@ TEST(Port, precodingConfig) {
14741474
EXPECT_EQ(serializedPort->getRxPrecoding(), true);
14751475
}
14761476

1477+
TEST(Port, linkScanModeConfig) {
1478+
auto platform = createMockPlatform();
1479+
auto state = make_shared<SwitchState>();
1480+
registerPort(state, PortID(1), "port1", scope());
1481+
1482+
auto applyAndVerify = [&](std::optional<cfg::LinkScanMode> newMode) {
1483+
auto oldMode = state->getPorts()->getNodeIf(PortID(1))->getLinkScanMode();
1484+
cfg::SwitchConfig config;
1485+
config.ports()->resize(1);
1486+
preparedMockPortConfig(
1487+
config.ports()[0], 1, "port1", cfg::PortState::DISABLED);
1488+
if (newMode.has_value()) {
1489+
config.ports()[0].linkScanMode() = newMode.value();
1490+
}
1491+
auto newState = publishAndApplyConfig(state, &config, platform.get());
1492+
1493+
if (oldMode == newMode) {
1494+
EXPECT_EQ(nullptr, newState);
1495+
return;
1496+
}
1497+
ASSERT_NE(nullptr, newState);
1498+
state = newState;
1499+
EXPECT_EQ(
1500+
state->getPorts()->getNodeIf(PortID(1))->getLinkScanMode(), newMode);
1501+
};
1502+
1503+
EXPECT_EQ(
1504+
std::nullopt, state->getPorts()->getNodeIf(PortID(1))->getLinkScanMode());
1505+
1506+
applyAndVerify(cfg::LinkScanMode::HARDWARE);
1507+
applyAndVerify(cfg::LinkScanMode::SOFTWARE);
1508+
applyAndVerify(cfg::LinkScanMode::SOFTWARE);
1509+
// Dropping the field from config clears it from switch state
1510+
applyAndVerify(std::nullopt);
1511+
1512+
auto newPort = state->getPorts()->getNodeIf(PortID(1))->clone();
1513+
newPort->setLinkScanMode(cfg::LinkScanMode::HARDWARE);
1514+
auto serializedPort = std::make_shared<Port>(newPort->toThrift());
1515+
EXPECT_EQ(serializedPort->getLinkScanMode(), cfg::LinkScanMode::HARDWARE);
1516+
1517+
newPort->setLinkScanMode(std::nullopt);
1518+
EXPECT_FALSE(newPort->toThrift().linkScanMode().has_value());
1519+
}
1520+
14771521
// Test holdoff timer fields: default values, applyConfig propagation,
14781522
// getter/setter methods, and serialization/deserialization.
14791523
TEST(Port, holdoffTimerConfig) {

fboss/agent/switch_config.thrift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,18 @@ enum PortDrainState {
11831183
DRAINED = 1,
11841184
}
11851185

1186+
/*
1187+
* Who notices that a port's link status changed: the SDK's software
1188+
* linkscan thread, or the ASIC itself.
1189+
*
1190+
* Unset leaves whatever the SDK came up with alone - FBOSS never
1191+
* programs the mode. Either value is written down to the SDK.
1192+
*/
1193+
enum LinkScanMode {
1194+
SOFTWARE = 1,
1195+
HARDWARE = 2,
1196+
}
1197+
11861198
/**
11871199
* Configuration for a single logical port
11881200
*/
@@ -1415,6 +1427,13 @@ struct Port {
14151427
// Controls whether RX precoding settings from the platform mapping are
14161428
// applied to the port.
14171429
44: optional bool rxPrecoding;
1430+
1431+
/*
1432+
* Whether link status changes on this port are noticed by the SDK's
1433+
* software linkscan thread or by the ASIC.
1434+
* Unset = leave whatever the SDK came up with untouched.
1435+
*/
1436+
45: optional LinkScanMode linkScanMode;
14181437
}
14191438

14201439
enum LacpPortRate {

fboss/agent/switch_state.thrift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ struct PortFields {
190190
71: optional bool txPrecoding;
191191
// Whether platform mapping RX precoding settings are applied to this port
192192
72: optional bool rxPrecoding;
193+
// Whether the SDK's software linkscan thread or the ASIC notices link
194+
// status changes on this port. Unset = leave SDK default untouched.
195+
73: optional switch_config.LinkScanMode linkScanMode;
193196
}
194197

195198
typedef ctrl.SystemPortThrift SystemPortFields

fboss/fsdb/if/oss/fsdb_model_thriftpath.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4272,6 +4272,7 @@ class ChildThriftPath<::facebook::fboss::state::PortFields, ::facebook::fboss::f
42724272
STRUCT_CHILD_GETTERS(llrConfig, 70);
42734273
STRUCT_CHILD_GETTERS(txPrecoding, 71);
42744274
STRUCT_CHILD_GETTERS(rxPrecoding, 72);
4275+
STRUCT_CHILD_GETTERS(linkScanMode, 73);
42754276
};
42764277

42774278

@@ -5069,6 +5070,7 @@ class ChildThriftPath<::facebook::fboss::cfg::Port, ::facebook::fboss::fsdb::Fsd
50695070
STRUCT_CHILD_GETTERS(llrConfigName, 42);
50705071
STRUCT_CHILD_GETTERS(txPrecoding, 43);
50715072
STRUCT_CHILD_GETTERS(rxPrecoding, 44);
5073+
STRUCT_CHILD_GETTERS(linkScanMode, 45);
50725074
};
50735075

50745076

0 commit comments

Comments
 (0)