summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux
diff options
context:
space:
mode:
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r--test/syscalls/linux/socket_netdevice.cc6
-rw-r--r--test/syscalls/linux/socket_netlink_route.cc57
-rw-r--r--test/syscalls/linux/socket_netlink_util.cc9
-rw-r--r--test/syscalls/linux/socket_netlink_util.h3
4 files changed, 62 insertions, 13 deletions
diff --git a/test/syscalls/linux/socket_netdevice.cc b/test/syscalls/linux/socket_netdevice.cc
index 6a5fa8965..765f8e0e4 100644
--- a/test/syscalls/linux/socket_netdevice.cc
+++ b/test/syscalls/linux/socket_netdevice.cc
@@ -89,7 +89,8 @@ TEST(NetdeviceTest, Netmask) {
// (i.e. netmask) for the loopback device.
int prefixlen = -1;
ASSERT_NO_ERRNO(NetlinkRequestResponse(
- fd, &req, sizeof(req), [&](const struct nlmsghdr *hdr) {
+ fd, &req, sizeof(req),
+ [&](const struct nlmsghdr *hdr) {
EXPECT_THAT(hdr->nlmsg_type, AnyOf(Eq(RTM_NEWADDR), Eq(NLMSG_DONE)));
EXPECT_TRUE((hdr->nlmsg_flags & NLM_F_MULTI) == NLM_F_MULTI)
@@ -111,7 +112,8 @@ TEST(NetdeviceTest, Netmask) {
ifaddrmsg->ifa_family == AF_INET) {
prefixlen = ifaddrmsg->ifa_prefixlen;
}
- }));
+ },
+ false));
ASSERT_GE(prefixlen, 0);
diff --git a/test/syscalls/linux/socket_netlink_route.cc b/test/syscalls/linux/socket_netlink_route.cc
index ac7e0bd3e..32fe0d6d1 100644
--- a/test/syscalls/linux/socket_netlink_route.cc
+++ b/test/syscalls/linux/socket_netlink_route.cc
@@ -238,7 +238,8 @@ TEST(NetlinkRouteTest, GetLinkDump) {
// Loopback is common among all tests, check that it's found.
bool loopbackFound = false;
ASSERT_NO_ERRNO(NetlinkRequestResponse(
- fd, &req, sizeof(req), [&](const struct nlmsghdr* hdr) {
+ fd, &req, sizeof(req),
+ [&](const struct nlmsghdr* hdr) {
CheckGetLinkResponse(hdr, kSeq, port);
if (hdr->nlmsg_type != RTM_NEWLINK) {
return;
@@ -252,10 +253,44 @@ TEST(NetlinkRouteTest, GetLinkDump) {
loopbackFound = true;
EXPECT_NE(msg->ifi_flags & IFF_LOOPBACK, 0);
}
- }));
+ },
+ false));
EXPECT_TRUE(loopbackFound);
}
+TEST(NetlinkRouteTest, MsgHdrMsgUnsuppType) {
+ FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket());
+
+ struct request {
+ struct nlmsghdr hdr;
+ struct ifinfomsg ifm;
+ };
+
+ constexpr uint32_t kSeq = 12345;
+
+ struct request req = {};
+ req.hdr.nlmsg_len = sizeof(req);
+ // If type & 0x3 is equal to 0x2, this means a get request
+ // which doesn't require CAP_SYS_ADMIN.
+ req.hdr.nlmsg_type = ((__RTM_MAX + 1024) & (~0x3)) | 0x2;
+ req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ req.hdr.nlmsg_seq = kSeq;
+ req.ifm.ifi_family = AF_UNSPEC;
+
+ ASSERT_NO_ERRNO(NetlinkRequestResponse(
+ fd, &req, sizeof(req),
+ [&](const struct nlmsghdr* hdr) {
+ EXPECT_THAT(hdr->nlmsg_type, Eq(NLMSG_ERROR));
+ EXPECT_EQ(hdr->nlmsg_seq, kSeq);
+ EXPECT_GE(hdr->nlmsg_len, sizeof(*hdr) + sizeof(struct nlmsgerr));
+
+ const struct nlmsgerr* msg =
+ reinterpret_cast<const struct nlmsgerr*>(NLMSG_DATA(hdr));
+ EXPECT_EQ(msg->error, -EOPNOTSUPP);
+ },
+ true));
+}
+
TEST(NetlinkRouteTest, MsgHdrMsgTrunc) {
FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket());
@@ -364,9 +399,11 @@ TEST(NetlinkRouteTest, ControlMessageIgnored) {
req.ifm.ifi_family = AF_UNSPEC;
ASSERT_NO_ERRNO(NetlinkRequestResponse(
- fd, &req, sizeof(req), [&](const struct nlmsghdr* hdr) {
+ fd, &req, sizeof(req),
+ [&](const struct nlmsghdr* hdr) {
CheckGetLinkResponse(hdr, kSeq, port);
- }));
+ },
+ false));
}
TEST(NetlinkRouteTest, GetAddrDump) {
@@ -388,7 +425,8 @@ TEST(NetlinkRouteTest, GetAddrDump) {
req.rgm.rtgen_family = AF_UNSPEC;
ASSERT_NO_ERRNO(NetlinkRequestResponse(
- fd, &req, sizeof(req), [&](const struct nlmsghdr* hdr) {
+ fd, &req, sizeof(req),
+ [&](const struct nlmsghdr* hdr) {
EXPECT_THAT(hdr->nlmsg_type, AnyOf(Eq(RTM_NEWADDR), Eq(NLMSG_DONE)));
EXPECT_TRUE((hdr->nlmsg_flags & NLM_F_MULTI) == NLM_F_MULTI)
@@ -405,7 +443,8 @@ TEST(NetlinkRouteTest, GetAddrDump) {
EXPECT_GE(hdr->nlmsg_len, sizeof(*hdr) + sizeof(struct ifaddrmsg));
// TODO(mpratt): Check ifaddrmsg contents and following attrs.
- }));
+ },
+ false));
}
TEST(NetlinkRouteTest, LookupAll) {
@@ -448,7 +487,8 @@ TEST(NetlinkRouteTest, GetRouteDump) {
bool routeFound = false;
bool dstFound = true;
ASSERT_NO_ERRNO(NetlinkRequestResponse(
- fd, &req, sizeof(req), [&](const struct nlmsghdr* hdr) {
+ fd, &req, sizeof(req),
+ [&](const struct nlmsghdr* hdr) {
// Validate the reponse to RTM_GETROUTE + NLM_F_DUMP.
EXPECT_THAT(hdr->nlmsg_type, AnyOf(Eq(RTM_NEWROUTE), Eq(NLMSG_DONE)));
@@ -491,7 +531,8 @@ TEST(NetlinkRouteTest, GetRouteDump) {
routeFound = true;
dstFound = rtDstFound && dstFound;
}
- }));
+ },
+ false));
// At least one route found in main route table.
EXPECT_TRUE(routeFound);
// Found RTA_DST for each route in main table.
diff --git a/test/syscalls/linux/socket_netlink_util.cc b/test/syscalls/linux/socket_netlink_util.cc
index 728d25434..36b6560c2 100644
--- a/test/syscalls/linux/socket_netlink_util.cc
+++ b/test/syscalls/linux/socket_netlink_util.cc
@@ -54,7 +54,8 @@ PosixErrorOr<uint32_t> NetlinkPortID(int fd) {
PosixError NetlinkRequestResponse(
const FileDescriptor& fd, void* request, size_t len,
- const std::function<void(const struct nlmsghdr* hdr)>& fn) {
+ const std::function<void(const struct nlmsghdr* hdr)>& fn,
+ bool expect_nlmsgerr) {
struct iovec iov = {};
iov.iov_base = request;
iov.iov_len = len;
@@ -93,7 +94,11 @@ PosixError NetlinkRequestResponse(
}
} while (type != NLMSG_DONE && type != NLMSG_ERROR);
- EXPECT_EQ(type, NLMSG_DONE);
+ if (expect_nlmsgerr) {
+ EXPECT_EQ(type, NLMSG_ERROR);
+ } else {
+ EXPECT_EQ(type, NLMSG_DONE);
+ }
return NoError();
}
diff --git a/test/syscalls/linux/socket_netlink_util.h b/test/syscalls/linux/socket_netlink_util.h
index bea449107..db8639a2f 100644
--- a/test/syscalls/linux/socket_netlink_util.h
+++ b/test/syscalls/linux/socket_netlink_util.h
@@ -34,7 +34,8 @@ PosixErrorOr<uint32_t> NetlinkPortID(int fd);
// Send the passed request and call fn will all response netlink messages.
PosixError NetlinkRequestResponse(
const FileDescriptor& fd, void* request, size_t len,
- const std::function<void(const struct nlmsghdr* hdr)>& fn);
+ const std::function<void(const struct nlmsghdr* hdr)>& fn,
+ bool expect_nlmsgerr);
} // namespace testing
} // namespace gvisor