Dedup netlink utility functions in tests.

PiperOrigin-RevId: 305749697
This commit is contained in:
Ting-Yu Wang
2020-04-09 13:34:31 -07:00
committed by gVisor bot
parent 2b4687a46b
commit 64c2b49067
5 changed files with 24 additions and 84 deletions
+1 -2
View File
@@ -138,7 +138,6 @@ cc_library(
hdrs = ["socket_netlink_route_util.h"],
deps = [
":socket_netlink_util",
"@com_google_absl//absl/types:optional",
],
)
@@ -2804,13 +2803,13 @@ cc_binary(
srcs = ["socket_netlink_route.cc"],
linkstatic = 1,
deps = [
":socket_netlink_route_util",
":socket_netlink_util",
":socket_test_util",
"//test/util:capability_util",
"//test/util:cleanup",
"//test/util:file_descriptor",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/types:optional",
gtest,
"//test/util:test_main",
"//test/util:test_util",
+10 -65
View File
@@ -26,7 +26,7 @@
#include "gtest/gtest.h"
#include "absl/strings/str_format.h"
#include "absl/types/optional.h"
#include "test/syscalls/linux/socket_netlink_route_util.h"
#include "test/syscalls/linux/socket_netlink_util.h"
#include "test/syscalls/linux/socket_test_util.h"
#include "test/util/capability_util.h"
@@ -118,24 +118,6 @@ void CheckGetLinkResponse(const struct nlmsghdr* hdr, int seq, int port) {
// TODO(mpratt): Check ifinfomsg contents and following attrs.
}
PosixError DumpLinks(
const FileDescriptor& fd, uint32_t seq,
const std::function<void(const struct nlmsghdr* hdr)>& fn) {
struct request {
struct nlmsghdr hdr;
struct ifinfomsg ifm;
};
struct request req = {};
req.hdr.nlmsg_len = sizeof(req);
req.hdr.nlmsg_type = RTM_GETLINK;
req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
req.hdr.nlmsg_seq = seq;
req.ifm.ifi_family = AF_UNSPEC;
return NetlinkRequestResponse(fd, &req, sizeof(req), fn, false);
}
TEST(NetlinkRouteTest, GetLinkDump) {
FileDescriptor fd =
ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket(NETLINK_ROUTE));
@@ -161,37 +143,6 @@ TEST(NetlinkRouteTest, GetLinkDump) {
EXPECT_TRUE(loopbackFound);
}
struct Link {
int index;
std::string name;
};
PosixErrorOr<absl::optional<Link>> FindLoopbackLink() {
ASSIGN_OR_RETURN_ERRNO(FileDescriptor fd, NetlinkBoundSocket(NETLINK_ROUTE));
absl::optional<Link> link;
RETURN_IF_ERRNO(DumpLinks(fd, kSeq, [&](const struct nlmsghdr* hdr) {
if (hdr->nlmsg_type != RTM_NEWLINK ||
hdr->nlmsg_len < NLMSG_SPACE(sizeof(struct ifinfomsg))) {
return;
}
const struct ifinfomsg* msg =
reinterpret_cast<const struct ifinfomsg*>(NLMSG_DATA(hdr));
if (msg->ifi_type == ARPHRD_LOOPBACK) {
const auto* rta = FindRtAttr(hdr, msg, IFLA_IFNAME);
if (rta == nullptr) {
// Ignore links that do not have a name.
return;
}
link = Link();
link->index = msg->ifi_index;
link->name = std::string(reinterpret_cast<const char*>(RTA_DATA(rta)));
}
}));
return link;
}
// CheckLinkMsg checks a netlink message against an expected link.
void CheckLinkMsg(const struct nlmsghdr* hdr, const Link& link) {
ASSERT_THAT(hdr->nlmsg_type, Eq(RTM_NEWLINK));
@@ -209,9 +160,7 @@ void CheckLinkMsg(const struct nlmsghdr* hdr, const Link& link) {
}
TEST(NetlinkRouteTest, GetLinkByIndex) {
absl::optional<Link> loopback_link =
ASSERT_NO_ERRNO_AND_VALUE(FindLoopbackLink());
ASSERT_TRUE(loopback_link.has_value());
Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink());
FileDescriptor fd =
ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket(NETLINK_ROUTE));
@@ -227,13 +176,13 @@ TEST(NetlinkRouteTest, GetLinkByIndex) {
req.hdr.nlmsg_flags = NLM_F_REQUEST;
req.hdr.nlmsg_seq = kSeq;
req.ifm.ifi_family = AF_UNSPEC;
req.ifm.ifi_index = loopback_link->index;
req.ifm.ifi_index = loopback_link.index;
bool found = false;
ASSERT_NO_ERRNO(NetlinkRequestResponse(
fd, &req, sizeof(req),
[&](const struct nlmsghdr* hdr) {
CheckLinkMsg(hdr, *loopback_link);
CheckLinkMsg(hdr, loopback_link);
found = true;
},
false));
@@ -241,9 +190,7 @@ TEST(NetlinkRouteTest, GetLinkByIndex) {
}
TEST(NetlinkRouteTest, GetLinkByName) {
absl::optional<Link> loopback_link =
ASSERT_NO_ERRNO_AND_VALUE(FindLoopbackLink());
ASSERT_TRUE(loopback_link.has_value());
Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink());
FileDescriptor fd =
ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket(NETLINK_ROUTE));
@@ -262,8 +209,8 @@ TEST(NetlinkRouteTest, GetLinkByName) {
req.hdr.nlmsg_seq = kSeq;
req.ifm.ifi_family = AF_UNSPEC;
req.rtattr.rta_type = IFLA_IFNAME;
req.rtattr.rta_len = RTA_LENGTH(loopback_link->name.size() + 1);
strncpy(req.ifname, loopback_link->name.c_str(), sizeof(req.ifname));
req.rtattr.rta_len = RTA_LENGTH(loopback_link.name.size() + 1);
strncpy(req.ifname, loopback_link.name.c_str(), sizeof(req.ifname));
req.hdr.nlmsg_len =
NLMSG_LENGTH(sizeof(req.ifm)) + NLMSG_ALIGN(req.rtattr.rta_len);
@@ -271,7 +218,7 @@ TEST(NetlinkRouteTest, GetLinkByName) {
ASSERT_NO_ERRNO(NetlinkRequestResponse(
fd, &req, sizeof(req),
[&](const struct nlmsghdr* hdr) {
CheckLinkMsg(hdr, *loopback_link);
CheckLinkMsg(hdr, loopback_link);
found = true;
},
false));
@@ -523,9 +470,7 @@ TEST(NetlinkRouteTest, LookupAll) {
TEST(NetlinkRouteTest, AddAddr) {
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
absl::optional<Link> loopback_link =
ASSERT_NO_ERRNO_AND_VALUE(FindLoopbackLink());
ASSERT_TRUE(loopback_link.has_value());
Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink());
FileDescriptor fd =
ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket(NETLINK_ROUTE));
@@ -545,7 +490,7 @@ TEST(NetlinkRouteTest, AddAddr) {
req.ifa.ifa_prefixlen = 24;
req.ifa.ifa_flags = 0;
req.ifa.ifa_scope = 0;
req.ifa.ifa_index = loopback_link->index;
req.ifa.ifa_index = loopback_link.index;
req.rtattr.rta_type = IFA_LOCAL;
req.rtattr.rta_len = RTA_LENGTH(sizeof(req.addr));
inet_pton(AF_INET, "10.0.0.1", &req.addr);
@@ -18,7 +18,6 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include "absl/types/optional.h"
#include "test/syscalls/linux/socket_netlink_util.h"
namespace gvisor {
@@ -73,14 +72,14 @@ PosixErrorOr<std::vector<Link>> DumpLinks() {
return links;
}
PosixErrorOr<absl::optional<Link>> FindLoopbackLink() {
PosixErrorOr<Link> LoopbackLink() {
ASSIGN_OR_RETURN_ERRNO(auto links, DumpLinks());
for (const auto& link : links) {
if (link.type == ARPHRD_LOOPBACK) {
return absl::optional<Link>(link);
return link;
}
}
return absl::optional<Link>();
return PosixError(ENOENT, "loopback link not found");
}
PosixError LinkAddLocalAddr(int index, int family, int prefixlen,
@@ -20,7 +20,6 @@
#include <vector>
#include "absl/types/optional.h"
#include "test/syscalls/linux/socket_netlink_util.h"
namespace gvisor {
@@ -37,7 +36,8 @@ PosixError DumpLinks(const FileDescriptor& fd, uint32_t seq,
PosixErrorOr<std::vector<Link>> DumpLinks();
PosixErrorOr<absl::optional<Link>> FindLoopbackLink();
// Returns the loopback link on the system. ENOENT if not found.
PosixErrorOr<Link> LoopbackLink();
// LinkAddLocalAddr sets IFA_LOCAL attribute on the interface.
PosixError LinkAddLocalAddr(int index, int family, int prefixlen,
+8 -11
View File
@@ -56,14 +56,14 @@ PosixErrorOr<std::set<std::string>> DumpLinkNames() {
return names;
}
PosixErrorOr<absl::optional<Link>> GetLinkByName(const std::string& name) {
PosixErrorOr<Link> GetLinkByName(const std::string& name) {
ASSIGN_OR_RETURN_ERRNO(auto links, DumpLinks());
for (const auto& link : links) {
if (link.name == name) {
return absl::optional<Link>(link);
return link;
}
}
return absl::optional<Link>();
return PosixError(ENOENT, "interface not found");
}
struct pihdr {
@@ -268,24 +268,21 @@ PosixErrorOr<FileDescriptor> OpenAndAttachTap(
return PosixError(errno);
}
ASSIGN_OR_RETURN_ERRNO(absl::optional<Link> link, GetLinkByName(dev_name));
if (!link.has_value()) {
return PosixError(ENOENT, "no link");
}
ASSIGN_OR_RETURN_ERRNO(auto link, GetLinkByName(dev_name));
// Interface setup.
struct in_addr addr;
inet_pton(AF_INET, dev_ipv4_addr.c_str(), &addr);
EXPECT_NO_ERRNO(LinkAddLocalAddr(link->index, AF_INET, /*prefixlen=*/24,
&addr, sizeof(addr)));
EXPECT_NO_ERRNO(LinkAddLocalAddr(link.index, AF_INET, /*prefixlen=*/24, &addr,
sizeof(addr)));
if (!IsRunningOnGvisor()) {
// FIXME(b/110961832): gVisor doesn't support setting MAC address on
// interfaces yet.
RETURN_IF_ERRNO(LinkSetMacAddr(link->index, kMacA, sizeof(kMacA)));
RETURN_IF_ERRNO(LinkSetMacAddr(link.index, kMacA, sizeof(kMacA)));
// FIXME(b/110961832): gVisor always creates enabled/up'd interfaces.
RETURN_IF_ERRNO(LinkChangeFlags(link->index, IFF_UP, IFF_UP));
RETURN_IF_ERRNO(LinkChangeFlags(link.index, IFF_UP, IFF_UP));
}
return fd;