Skip to content

Commit

Permalink
fboss2 cli: Canonicalize hostname
Browse files Browse the repository at this point in the history
Summary:
Some commands work with short hostnames (e.g. `rsw026.p045.f01.frc1`)
and some only with the FQDN (e.g. `rsw026.p045.f01.frc1.tfbnw.net`). Even the
same command can work on some short hosts and not on others if it connects to
the host using different clients, some of which support it and some don't.

Specifically, `BmcClient` seems to require the FQDN (canonical name).

Reviewed By: somasun

Differential Revision: D63148545

fbshipit-source-id: 574815e8a15ad24ae33e741c7f3df3d6efe56054
  • Loading branch information
Alex Landau authored and facebook-github-bot committed Sep 25, 2024
1 parent f85ade3 commit 7f85d58
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 22 deletions.
46 changes: 29 additions & 17 deletions fboss/cli/fboss2/utils/CmdUtilsCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,50 @@ using folly::IPAddressV6;

namespace facebook::fboss::utils {

const folly::IPAddress getIPFromHost(const std::string& hostname) {
std::pair<std::string, folly::IPAddress> getCanonicalNameAndIPFromHost(
const std::string& hostname) {
std::string canonicalHostname = hostname;

if (IPAddress::validate(hostname)) {
return IPAddress(hostname);
return std::make_pair(canonicalHostname, IPAddress(hostname));
}
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo* result = nullptr;
auto rv = getaddrinfo(hostname.c_str(), nullptr, &hints, &result);
hints.ai_flags = AI_CANONNAME;
struct addrinfo* info_orig = nullptr;
auto rv = getaddrinfo(hostname.c_str(), nullptr, &hints, &info_orig);

SCOPE_EXIT {
freeaddrinfo(result);
freeaddrinfo(info_orig);
};
if (rv < 0) {
XLOG(ERR) << "Could not get an IP for: " << hostname;
return IPAddress();
return std::make_pair(canonicalHostname, IPAddress());
}

struct addrinfo* info = info_orig;
if (info != nullptr) {
canonicalHostname = info->ai_canonname;
}
struct addrinfo* res;
for (res = result; res != nullptr; res = res->ai_next) {
if (res->ai_addr->sa_family == AF_INET) { // IPV4
struct sockaddr_in* sp = (struct sockaddr_in*)res->ai_addr;
return IPAddress::fromLong(sp->sin_addr.s_addr);
} else if (res->ai_addr->sa_family == AF_INET6) { // IPV6
struct sockaddr_in6* sp = (struct sockaddr_in6*)res->ai_addr;
return IPAddress::fromBinary(ByteRange(
static_cast<unsigned char*>(&(sp->sin6_addr.s6_addr[0])),
IPAddressV6::byteCount()));

for (; info != nullptr; info = info->ai_next) {
if (info->ai_addr->sa_family == AF_INET) { // IPV4
struct sockaddr_in* sp = (struct sockaddr_in*)info->ai_addr;
return std::make_pair(
canonicalHostname, IPAddress::fromLong(sp->sin_addr.s_addr));
} else if (info->ai_addr->sa_family == AF_INET6) { // IPV6
struct sockaddr_in6* sp = (struct sockaddr_in6*)info->ai_addr;
return std::make_pair(
canonicalHostname,
IPAddress::fromBinary(ByteRange(
static_cast<unsigned char*>(&(sp->sin6_addr.s6_addr[0])),
IPAddressV6::byteCount())));
}
}
XLOG(ERR) << "Could not get an IP for: " << hostname;
return IPAddress();
return std::make_pair(canonicalHostname, IPAddress());
}

std::vector<std::string> getHostsFromFile(const std::string& filename) {
Expand Down
3 changes: 2 additions & 1 deletion fboss/cli/fboss2/utils/CmdUtilsCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ auto filterTupleMonostates(Tuple tup) {
void postAppInit(int argc, char* argv[], CLI::App& app);

// API to retrieve host related information
const folly::IPAddress getIPFromHost(const std::string& hostname);
std::pair<std::string, folly::IPAddress> getCanonicalNameAndIPFromHost(
const std::string& hostname);
const std::string getOobNameFromHost(const std::string& host);
std::vector<std::string> getHostsInSmcTier(const std::string& parentTierName);
std::vector<std::string> getHostsFromFile(const std::string& filename);
Expand Down
11 changes: 7 additions & 4 deletions fboss/cli/fboss2/utils/HostInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ namespace facebook::fboss {
class HostInfo {
public:
explicit HostInfo(const std::string& hostName)
: HostInfo(
hostName,
utils::getOobNameFromHost(hostName),
utils::getIPFromHost(hostName)) {}
: HostInfo(utils::getCanonicalNameAndIPFromHost(hostName)) {}

HostInfo(
const std::string& hostName,
Expand Down Expand Up @@ -42,6 +39,12 @@ class HostInfo {
}

private:
explicit HostInfo(const std::pair<std::string, folly::IPAddress>& hostAndIp)
: HostInfo(
hostAndIp.first,
utils::getOobNameFromHost(hostAndIp.first),
hostAndIp.second) {}

const std::string name_;
const std::string oob_;
const folly::IPAddress ip_;
Expand Down

0 comments on commit 7f85d58

Please sign in to comment.