Skip to content

Commit 34859c2

Browse files
Add fboss2-dev delete switch admin-distance and icmpv4-unavailable-src-addr
delete switch admin-distance <client-id> removes a routing client's entry from sw.clientIdToAdminDistance. Once the entry is gone, getAdminDistanceForClientId() finds no mapping and returns AdminDistance::MAX_ADMIN_DISTANCE (255) for that client; the per-client default in switch_config.thrift only applies when the whole map is absent from the config. Saved at coldboot level because the map is consulted only at route-program time and existing routes are not re-stamped. Client-ids 1-4 (STATIC_ROUTE, INTERFACE_ROUTE, LINKLOCAL_ROUTE, REMOTE_INTERFACE_ROUTE) are refused: their distances are hardcoded in the agent, mirroring the refusal in config switch admin-distance. The client-id parsing and forbidden-client check are shared with the config command via parseAdminDistanceClientId(). delete switch icmpv4-unavailable-src-addr clears the optional sw.icmpV4UnavailableSrcAddress field, returning it to its unset default. Hitless.
1 parent 855a784 commit 34859c2

17 files changed

Lines changed: 635 additions & 25 deletions

cmake/CliFboss2.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,12 @@ add_library(fboss2_config_lib
10921092
fboss/cli/fboss2/commands/delete/protocol/static/route/CmdDeleteProtocolStaticRoute.h
10931093
fboss/cli/fboss2/commands/delete/arp/CmdDeleteArp.cpp
10941094
fboss/cli/fboss2/commands/delete/arp/CmdDeleteArp.h
1095+
fboss/cli/fboss2/commands/delete/switch/CmdDeleteSwitch.cpp
1096+
fboss/cli/fboss2/commands/delete/switch/CmdDeleteSwitch.h
1097+
fboss/cli/fboss2/commands/delete/switch/admin_distance/CmdDeleteAdminDistance.cpp
1098+
fboss/cli/fboss2/commands/delete/switch/admin_distance/CmdDeleteAdminDistance.h
1099+
fboss/cli/fboss2/commands/delete/switch/icmpv4_unavailable_src_addr/CmdDeleteIcmpV4UnavailableSrcAddr.cpp
1100+
fboss/cli/fboss2/commands/delete/switch/icmpv4_unavailable_src_addr/CmdDeleteIcmpV4UnavailableSrcAddr.h
10951101
fboss/cli/fboss2/commands/delete/tunnel/CmdDeleteTunnel.cpp
10961102
fboss/cli/fboss2/commands/delete/tunnel/CmdDeleteTunnel.h
10971103
fboss/cli/fboss2/commands/delete/tunnel/ip_in_ip/CmdDeleteTunnelIpInIp.cpp

cmake/CliFboss2TestConfig.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ add_executable(fboss2_cmd_config_test
3838
fboss/cli/fboss2/test/config/CmdConfigVlanPortTaggingModeTest.cpp
3939
fboss/cli/fboss2/test/config/CmdConfigVlanStaticMacTest.cpp
4040
fboss/cli/fboss2/test/config/CmdDeleteAclRuleTest.cpp
41+
fboss/cli/fboss2/test/config/CmdDeleteAdminDistanceTest.cpp
42+
fboss/cli/fboss2/test/config/CmdDeleteIcmpV4UnavailableSrcAddrTest.cpp
4143
fboss/cli/fboss2/test/config/CmdDeleteArpTest.cpp
4244
fboss/cli/fboss2/test/config/CmdDeleteConfigInterfaceTest.cpp
4345
fboss/cli/fboss2/test/config/CmdDeleteDhcpTest.cpp

fboss/cli/fboss2/BUCK

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,9 @@ cpp_library(
12171217
"commands/delete/qos/default_policy/CmdDeleteQosDefaultPolicy.cpp",
12181218
"commands/delete/qos/queue_config/CmdDeleteQosQueueConfig.cpp",
12191219
"commands/delete/qos/queue_config/CmdDeleteQosQueueConfigQueueId.cpp",
1220+
"commands/delete/switch/CmdDeleteSwitch.cpp",
1221+
"commands/delete/switch/admin_distance/CmdDeleteAdminDistance.cpp",
1222+
"commands/delete/switch/icmpv4_unavailable_src_addr/CmdDeleteIcmpV4UnavailableSrcAddr.cpp",
12201223
"commands/delete/tunnel/CmdDeleteTunnel.cpp",
12211224
"commands/delete/tunnel/ip_in_ip/CmdDeleteTunnelIpInIp.cpp",
12221225
"commands/delete/tunnel/ip_in_ip/TunnelIpInIpDeleteUtils.cpp",
@@ -1359,6 +1362,9 @@ cpp_library(
13591362
"commands/delete/qos/default_policy/CmdDeleteQosDefaultPolicy.h",
13601363
"commands/delete/qos/queue_config/CmdDeleteQosQueueConfig.h",
13611364
"commands/delete/qos/queue_config/CmdDeleteQosQueueConfigQueueId.h",
1365+
"commands/delete/switch/CmdDeleteSwitch.h",
1366+
"commands/delete/switch/admin_distance/CmdDeleteAdminDistance.h",
1367+
"commands/delete/switch/icmpv4_unavailable_src_addr/CmdDeleteIcmpV4UnavailableSrcAddr.h",
13621368
"commands/delete/tunnel/CmdDeleteTunnel.h",
13631369
"commands/delete/tunnel/ip_in_ip/CmdDeleteTunnelIpInIp.h",
13641370
"commands/delete/tunnel/ip_in_ip/TunnelIpInIpDeleteUtils.h",

fboss/cli/fboss2/CmdListConfig.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@
146146
#include "fboss/cli/fboss2/commands/delete/qos/default_policy/CmdDeleteQosDefaultPolicy.h"
147147
#include "fboss/cli/fboss2/commands/delete/qos/queue_config/CmdDeleteQosQueueConfig.h"
148148
#include "fboss/cli/fboss2/commands/delete/qos/queue_config/CmdDeleteQosQueueConfigQueueId.h"
149+
#include "fboss/cli/fboss2/commands/delete/switch/CmdDeleteSwitch.h"
150+
#include "fboss/cli/fboss2/commands/delete/switch/admin_distance/CmdDeleteAdminDistance.h"
151+
#include "fboss/cli/fboss2/commands/delete/switch/icmpv4_unavailable_src_addr/CmdDeleteIcmpV4UnavailableSrcAddr.h"
149152
#include "fboss/cli/fboss2/commands/delete/tunnel/CmdDeleteTunnel.h"
150153
#include "fboss/cli/fboss2/commands/delete/tunnel/ip_in_ip/CmdDeleteTunnelIpInIp.h"
151154
#include "fboss/cli/fboss2/commands/delete/tunnel/ip_in_ip/decap/CmdDeleteTunnelIpInIpDecap.h"
@@ -1230,6 +1233,19 @@ const CommandTree& kConfigCommandTree() {
12301233
commandHandler<CmdDeleteVlan>,
12311234
argRegistrar<CmdDeleteVlanTraits>},
12321235

1236+
{"delete",
1237+
"switch",
1238+
"Delete switch-level settings",
1239+
commandHandler<CmdDeleteSwitch>,
1240+
argTypeHandler<CmdDeleteSwitchTraits>,
1241+
{{"admin-distance",
1242+
"Remove the admin distance entry for a routing client: <client-id>",
1243+
commandHandler<CmdDeleteAdminDistance>,
1244+
argRegistrar<CmdDeleteAdminDistanceTraits>},
1245+
{"icmpv4-unavailable-src-addr",
1246+
"Remove the ICMPv4 unavailable source address (agent falls back to the RFC 7600 default)",
1247+
commandHandler<CmdDeleteIcmpV4UnavailableSrcAddr>,
1248+
argRegistrar<CmdDeleteIcmpV4UnavailableSrcAddrTraits>}}},
12331249
};
12341250
stable_sort(root.begin(), root.end());
12351251
return root;

fboss/cli/fboss2/commands/config/switch/admin_distance/CmdConfigAdminDistance.cpp

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,10 @@ namespace facebook::fboss {
2121

2222
namespace {
2323
constexpr int32_t kMaxAdminDistance = 255;
24+
} // namespace
2425

25-
// ClientIDs whose admin distance is hardcoded in the agent and cannot be
26-
// overridden via clientIdToAdminDistance config:
27-
// STATIC_ROUTE (1) -> AdminDistance::STATIC_ROUTE
28-
// INTERFACE_ROUTE (2) -> AdminDistance::DIRECTLY_CONNECTED
29-
// LINKLOCAL_ROUTE (3) -> AdminDistance::DIRECTLY_CONNECTED
30-
// REMOTE_INTERFACE_ROUTE (4) -> AdminDistance::DIRECTLY_CONNECTED
31-
const std::unordered_map<int32_t, std::string>& forbiddenClients() {
26+
const std::unordered_map<int32_t, std::string>&
27+
forbiddenAdminDistanceClients() {
3228
static const std::unordered_map<int32_t, std::string> kForbidden = {
3329
{1,
3430
"STATIC_ROUTE is hardcoded to AdminDistance::STATIC_ROUTE in the agent"},
@@ -41,36 +37,43 @@ const std::unordered_map<int32_t, std::string>& forbiddenClients() {
4137
};
4238
return kForbidden;
4339
}
44-
} // namespace
45-
46-
AdminDistanceArg::AdminDistanceArg(std::vector<std::string> v) {
47-
if (v.size() != 2) {
48-
throw std::invalid_argument(
49-
fmt::format(
50-
"Expected exactly two arguments: <client-id> <distance>, got {}",
51-
v.size()));
52-
}
5340

41+
int32_t parseAdminDistanceClientId(
42+
const std::string& token,
43+
std::string_view action) {
44+
int32_t clientId = 0;
5445
try {
55-
clientId_ = folly::to<int32_t>(v[0]);
46+
clientId = folly::to<int32_t>(token);
5647
} catch (const folly::ConversionError&) {
5748
throw std::invalid_argument(
58-
fmt::format("Invalid client-id '{}': must be an integer", v[0]));
49+
fmt::format("Invalid client-id '{}': must be an integer", token));
5950
}
60-
if (clientId_ < 0) {
51+
if (clientId < 0) {
6152
throw std::invalid_argument(
62-
fmt::format("client-id must be a non-negative integer, got {}", v[0]));
53+
fmt::format("client-id must be a non-negative integer, got {}", token));
6354
}
64-
65-
const auto& forbidden = forbiddenClients();
66-
auto it = forbidden.find(clientId_);
55+
const auto& forbidden = forbiddenAdminDistanceClients();
56+
auto it = forbidden.find(clientId);
6757
if (it != forbidden.end()) {
6858
throw std::invalid_argument(
6959
fmt::format(
70-
"FBOSS does not allow changing admin distance for client-id {}: {}",
71-
clientId_,
60+
"FBOSS does not allow {} for client-id {}: {}",
61+
action,
62+
clientId,
7263
it->second));
7364
}
65+
return clientId;
66+
}
67+
68+
AdminDistanceArg::AdminDistanceArg(std::vector<std::string> v) {
69+
if (v.size() != 2) {
70+
throw std::invalid_argument(
71+
fmt::format(
72+
"Expected exactly two arguments: <client-id> <distance>, got {}",
73+
v.size()));
74+
}
75+
76+
clientId_ = parseAdminDistanceClientId(v[0], "changing admin distance");
7477

7578
try {
7679
distance_ = folly::to<int32_t>(v[1]);

fboss/cli/fboss2/commands/config/switch/admin_distance/CmdConfigAdminDistance.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,33 @@
1010

1111
#pragma once
1212

13+
#include <cstdint>
14+
#include <string>
15+
#include <string_view>
16+
#include <unordered_map>
1317
#include "fboss/cli/fboss2/CmdHandler.h"
1418
#include "fboss/cli/fboss2/commands/config/switch/CmdConfigSwitch.h"
1519

1620
namespace facebook::fboss {
1721

22+
// ClientIDs whose admin distance is hardcoded in the agent, so a
23+
// clientIdToAdminDistance entry for them is never consulted:
24+
// STATIC_ROUTE (1) -> AdminDistance::STATIC_ROUTE
25+
// INTERFACE_ROUTE (2) -> AdminDistance::DIRECTLY_CONNECTED
26+
// LINKLOCAL_ROUTE (3) -> AdminDistance::DIRECTLY_CONNECTED
27+
// REMOTE_INTERFACE_ROUTE (4) -> AdminDistance::DIRECTLY_CONNECTED
28+
// Maps client-id to the reason it is rejected. Both `config switch
29+
// admin-distance` and `delete switch admin-distance` refuse these ids.
30+
const std::unordered_map<int32_t, std::string>& forbiddenAdminDistanceClients();
31+
32+
// Parses and validates the <client-id> token shared by `config switch
33+
// admin-distance` and `delete switch admin-distance`: must be a non-negative
34+
// integer and not a forbidden client. `action` names the operation for the
35+
// refusal message (e.g. "changing admin distance").
36+
int32_t parseAdminDistanceClientId(
37+
const std::string& token,
38+
std::string_view action);
39+
1840
// Parses the two positional arguments of
1941
// config switch admin-distance <client-id> <distance>
2042
// where <client-id> is a routing ClientID (e.g. 0=BGP, 786=OpenR)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*
9+
*/
10+
11+
#include "fboss/cli/fboss2/commands/delete/switch/CmdDeleteSwitch.h"
12+
#include "fboss/cli/fboss2/CmdHandler.cpp"
13+
14+
namespace facebook::fboss {
15+
16+
// Explicit template instantiation
17+
template void CmdHandler<CmdDeleteSwitch, CmdDeleteSwitchTraits>::run();
18+
19+
} // namespace facebook::fboss
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*
9+
*/
10+
11+
#pragma once
12+
13+
#include <string>
14+
#include "fboss/cli/fboss2/CmdHandler.h"
15+
16+
namespace facebook::fboss {
17+
18+
struct CmdDeleteSwitchTraits : public WriteCommandTraits {
19+
static constexpr utils::ObjectArgTypeId ObjectArgTypeId =
20+
utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_NONE;
21+
using ObjectArgType = std::monostate;
22+
using RetType = std::string;
23+
};
24+
25+
class CmdDeleteSwitch
26+
: public CmdHandler<CmdDeleteSwitch, CmdDeleteSwitchTraits> {
27+
public:
28+
RetType queryClient(const HostInfo& /* hostInfo */) {
29+
throw std::runtime_error(
30+
"Incomplete command, please use one of the subcommands (e.g. admin-distance)");
31+
}
32+
33+
void printOutput(const RetType& /* model */) {}
34+
};
35+
36+
} // namespace facebook::fboss
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*
9+
*/
10+
11+
#include "fboss/cli/fboss2/commands/delete/switch/admin_distance/CmdDeleteAdminDistance.h"
12+
13+
#include "fboss/cli/fboss2/CmdHandler.cpp"
14+
15+
#include <fmt/format.h>
16+
#include <iostream>
17+
#include "fboss/agent/FbossError.h"
18+
#include "fboss/cli/fboss2/commands/config/switch/admin_distance/CmdConfigAdminDistance.h"
19+
#include "fboss/cli/fboss2/session/ConfigSession.h"
20+
21+
namespace facebook::fboss {
22+
23+
AdminDistanceDeleteArg::AdminDistanceDeleteArg(std::vector<std::string> v) {
24+
if (v.size() != 1) {
25+
throw std::invalid_argument(
26+
fmt::format(
27+
"Expected exactly one argument: <client-id>, got {}", v.size()));
28+
}
29+
30+
// Shared with `config switch admin-distance`: an entry for the forbidden
31+
// clients is never consulted by the agent, so neither setting nor removing
32+
// one is meaningful.
33+
clientId_ =
34+
parseAdminDistanceClientId(v[0], "removing the admin distance entry");
35+
36+
data_ = std::move(v);
37+
}
38+
39+
CmdDeleteAdminDistanceTraits::RetType CmdDeleteAdminDistance::queryClient(
40+
const HostInfo& /* hostInfo */,
41+
const ObjectArgType& arg) {
42+
auto& session = ConfigSession::getInstance();
43+
auto& swConfig = *session.getAgentConfig().sw();
44+
45+
int32_t clientId = arg.getClientId();
46+
47+
// Once the entry is gone, getAdminDistanceForClientId() (Utils.cpp, reached
48+
// via SwSwitch::clientIdToAdminDistance) finds no mapping and returns
49+
// AdminDistance::MAX_ADMIN_DISTANCE (255) for this client -- it does not fall
50+
// back to the per-client default in switch_config.thrift, since that default
51+
// only applies when the whole clientIdToAdminDistance field is absent from
52+
// the config.
53+
auto& adminDistanceMap = *swConfig.clientIdToAdminDistance();
54+
auto it = adminDistanceMap.find(clientId);
55+
if (it == adminDistanceMap.end()) {
56+
throw FbossError("No admin distance configured for client-id ", clientId);
57+
}
58+
adminDistanceMap.erase(it);
59+
60+
// clientIdToAdminDistance is only consulted at route-program time; existing
61+
// routes are not re-stamped when the map changes. A coldboot is required to
62+
// flush and re-program all routes with the restored default distance.
63+
session.saveConfig(
64+
cli::ServiceType::AGENT, cli::ConfigActionLevel::AGENT_COLDBOOT);
65+
66+
return fmt::format(
67+
"Successfully removed admin distance entry for client-id {}. Routes from "
68+
"this client will use MAX_ADMIN_DISTANCE (255). A coldboot is required to "
69+
"apply the change to existing routes.",
70+
clientId);
71+
}
72+
73+
void CmdDeleteAdminDistance::printOutput(const RetType& output) {
74+
std::cout << output << std::endl;
75+
}
76+
77+
// Explicit template instantiation
78+
template void
79+
CmdHandler<CmdDeleteAdminDistance, CmdDeleteAdminDistanceTraits>::run();
80+
81+
} // namespace facebook::fboss
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*
9+
*/
10+
11+
#pragma once
12+
13+
#include <string>
14+
#include <vector>
15+
#include "fboss/cli/fboss2/CmdHandler.h"
16+
#include "fboss/cli/fboss2/commands/delete/switch/CmdDeleteSwitch.h"
17+
18+
namespace facebook::fboss {
19+
20+
// Parses the single positional argument of
21+
// delete admin-distance <client-id>
22+
// where <client-id> is a routing ClientID (e.g. 0=BGPD, 700=STATIC_INTERNAL,
23+
// 786=OPENR) whose admin-distance override should be removed from the config.
24+
// ClientIDs 1 (STATIC_ROUTE), 2 (INTERFACE_ROUTE), 3 (LINKLOCAL_ROUTE), and
25+
// 4 (REMOTE_INTERFACE_ROUTE) are forbidden here for the same reason they are
26+
// forbidden in `config switch admin-distance`: the agent hardcodes their
27+
// distances, so their map entries are inert. See
28+
// forbiddenAdminDistanceClients() in CmdConfigAdminDistance.h.
29+
class AdminDistanceDeleteArg : public utils::BaseObjectArgType<std::string> {
30+
public:
31+
/* implicit */ AdminDistanceDeleteArg( // NOLINT(google-explicit-constructor)
32+
std::vector<std::string> v);
33+
34+
int32_t getClientId() const {
35+
return clientId_;
36+
}
37+
38+
private:
39+
int32_t clientId_{0};
40+
};
41+
42+
struct CmdDeleteAdminDistanceTraits : public WriteCommandTraits {
43+
using ParentCmd = CmdDeleteSwitch;
44+
static void addCliArg(CLI::App& cmd, std::vector<std::string>& args) {
45+
cmd.add_option(
46+
"client_id",
47+
args,
48+
"<client-id> - routing client whose admin distance entry to remove "
49+
"(e.g. 0=BGP, 786=OpenR). "
50+
"Client-ids 1/2/3/4 are hardcoded and cannot be removed.");
51+
}
52+
using ObjectArgType = AdminDistanceDeleteArg;
53+
using RetType = std::string;
54+
};
55+
56+
class CmdDeleteAdminDistance
57+
: public CmdHandler<CmdDeleteAdminDistance, CmdDeleteAdminDistanceTraits> {
58+
public:
59+
using ObjectArgType = CmdDeleteAdminDistanceTraits::ObjectArgType;
60+
using RetType = CmdDeleteAdminDistanceTraits::RetType;
61+
62+
RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& arg);
63+
64+
void printOutput(const RetType& output);
65+
};
66+
67+
} // namespace facebook::fboss

0 commit comments

Comments
 (0)