Skip to content

Commit 75a9757

Browse files
Yikai Linmeta-codesync[bot]
authored andcommitted
Expose policy backup address in fboss2
Summary: # Context The BGP FRR stack associates protected routes with a locally configured backup address, but operators need to verify both the BGP association and the backup nexthop received by FBOSS Agent. Design: https://docs.google.com/document/d/1wRTKEsbN4NAxEmF4PRrj-6UabvE4X_hTnrgdChgWh34/edit # This Diff Add optional `backup_addr` fields to the legacy and canonical BGP route API models, populate them from `BgpPath`, and preserve the field in both Python canonical-RIB decoders when they reconstruct `TBgpPath`. `fboss2 show bgp` renders the configured address as `Backup`; `fboss2 show route` marks backup nexthops as `(BACKUP)` while leaving ordinary primary output unchanged. This is observability only and does not affect path selection, FIB programming, or switchover enablement. # This Stack 1. **D114950612** applies and caches the ingress policy action. 2. **D114950610** carries the backup address from Adj-RIB-In into Loc-RIB. 3. **D114950611** programs the backup address to FBOSS. 4. **This diff** exposes the resulting state in BGP and FBOSS CLI output. Reviewed By: jaiharil Differential Revision: D115002980 fbshipit-source-id: abe1ab4bb526cdda9ead8224223b73a00e7c5f61
1 parent 14ec47e commit 75a9757

5 files changed

Lines changed: 27 additions & 2 deletions

File tree

fboss/cli/fboss2/commands/show/bgp/CanonicalRibResolver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ std::optional<TBgpPath> resolveCanonicalPath(
121121
assignIfSet(path.aggregator(), dedupPath.aggregator());
122122
assignIfSet(path.topologyInfo(), dedupPath.topology_info());
123123
assignIfSet(path.weight(), dedupPath.weight());
124+
assignIfSet(path.backup_addr(), dedupPath.backup_addr());
124125

125126
// Peer attribution resolves through the shared peers pool by index.
126127
if (canonPath.peer_idx().has_value()) {

fboss/cli/fboss2/oss/CmdShowUtils.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,13 +419,25 @@ void printRIBEntries(
419419
extCommunitiesStr = printExtCommunities(*extCommunities);
420420
}
421421

422+
std::string backupAddrStr;
423+
if (const auto* backupAddr =
424+
apache::thrift::get_pointer(path.backup_addr())) {
425+
backupAddrStr = fmt::format(
426+
" (backup: {})",
427+
IPAddress::fromBinary(
428+
folly::ByteRange(
429+
folly::StringPiece(*backupAddr->prefix_bin())))
430+
.str());
431+
}
432+
422433
std::string pathToPrint = fmt::format(
423-
"{} from {} ({}) via {} | LBW: {} | Origin: {} | "
434+
"{} from {} ({}) via {}{} | LBW: {} | Origin: {} | "
424435
"LP: {} | ASP: {} | LM: {} | NH Weight: {} | MED: {} | ID: {} (rcvd) {} (sent) | Weight: {}{} | IgpCost: {}",
425436
marker,
426437
peerIdStr,
427438
peerDescriptionStr,
428439
nextHopStr,
440+
backupAddrStr,
429441
lbwStr,
430442
(originStr != nettools::bgplib::kNullMessage)
431443
? originStr.substr(11) // Trim BGP_ORIGIN_ from origin string

fboss/cli/fboss2/test/CanonicalRibResolverTest.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace {
3131
// Mirrors facebook::bgp::kBestPathGroup / kDefaultPathGroup -- the group keys
3232
// bgpd uses; the resolver must reconstruct best_group as kBestGroup.
3333
constexpr auto kBestGroup = "best";
34+
constexpr auto kBackupAddr = "2001:db8::1";
3435

3536
// A canonical state with a single prefix and sparse path/peer IDs, optionally
3637
// marked as the selected best.
@@ -40,6 +41,7 @@ TCanonicalRibState makeSingleEntryState(int64_t med, bool markBest) {
4041
TBgpDedupedPath deduped;
4142
deduped.next_hop() = getPrefix(kNextHop);
4243
deduped.med() = med;
44+
deduped.backup_addr() = getPrefix(kBackupAddr);
4345
state.deduped_paths()->emplace(7, deduped);
4446

4547
TCanonicalPeer peer;
@@ -88,6 +90,7 @@ TEST(CanonicalRibResolverTest, ResolvesPathPeerAndBestPath) {
8890
EXPECT_EQ(kPeerDescription, path.peer_description().value());
8991
EXPECT_EQ(1234, path.router_id().value());
9092
EXPECT_EQ(100, path.med().value());
93+
EXPECT_EQ(getPrefix(kBackupAddr), path.backup_addr().value());
9194
EXPECT_TRUE(path.is_best_path().value());
9295
}
9396

fboss/cli/fboss2/test/CmdShowBgpTableDetailTest.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ class CmdShowBgpTableDetailTestFixture : public CmdHandlerTestBase {
4242
entriesIPv4_ = {buildEntry()};
4343
entriesIPv6_ = {
4444
buildEntry("2001::1/64", "2001::2", "2001::3", "two00one::three", 7)};
45+
entriesIPv6_.front()
46+
.paths()
47+
->at(entriesIPv6_.front().best_group().value())
48+
.front()
49+
.backup_addr() = getPrefix("2001:db8::1");
4550
combineEntries();
4651
}
4752

@@ -114,7 +119,7 @@ TEST_F(CmdShowBgpTableDetailTestFixture, printOutput) {
114119
" ExtCommunities: Type(64):SubType(2):AS(3):Value(4)\n"
115120
" BestPath Rejection Reason: Router-Id, Filter Criterion: Choose Lowest Value\n"
116121
"\n> 2001::1/64, Selected 1/1 paths (1 active, 0 inactive)\n"
117-
"*@ from 2001::3 (two00one::three) via 2001::2 | LBW: None | Origin: INCOMPLETE | LP: DEPRIO/25 | ASP: 65301 | LM: # | NH Weight: 7 | MED: 10 | ID: 5 (rcvd) 6 (sent) | Weight: 20 | IgpCost: 100"
122+
"*@ from 2001::3 (two00one::three) via 2001::2 (backup: 2001:db8::1) | LBW: None | Origin: INCOMPLETE | LP: DEPRIO/25 | ASP: 65301 | LM: # | NH Weight: 7 | MED: 10 | ID: 5 (rcvd) 6 (sent) | Weight: 20 | IgpCost: 100"
118123
"\n Router/Originator: 2.2.2.3 | ClusterList: [1.1.1.2]\n"
119124
" Communities: FABRIC_POD_RSW_LOOP/65527:12705\n"
120125
" ExtCommunities: Type(64):SubType(2):AS(3):Value(4)\n"

neteng/fboss/bgp/if/bgp_route_types.thrift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ struct TBgpPath {
137137
// Set by the loc-RIB getters; left unset by shadow-RIB views, which only hold
138138
// selected paths.
139139
28: optional bool is_inactive;
140+
// Locally configured backup address. This is not a BGP wire attribute.
141+
29: optional bgp_attr.TIpPrefix backup_addr;
140142
}
141143

142144
/**
@@ -386,6 +388,8 @@ struct TBgpDedupedPath {
386388
12: optional map<string, i64> topology_info;
387389
/** Cisco-style local BGP weight (path-selection attr). Mirrors TBgpPath.weight. */
388390
13: optional i32 weight;
391+
/** Locally configured backup address. Mirrors TBgpPath.backup_addr. */
392+
14: optional bgp_attr.TIpPrefix backup_addr;
389393
}
390394

391395
/**

0 commit comments

Comments
 (0)