summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2021-09-26 11:22:35 +0000
committerMikael Magnusson <mikma@users.sourceforge.net>2021-09-26 11:22:35 +0000
commitea43d9ffc0fd7bc1f42bada76006dbcf26f752af (patch)
treeb6921fcae6d5154ae292510c16d042abed112774
parent96667cf4a3c30726cb4242f749afcee42ce7cd43 (diff)
-rw-r--r--test/syscalls/linux/socket_netlink_route.cc116
-rw-r--r--test/syscalls/linux/socket_netlink_route_util.cc2
2 files changed, 114 insertions, 4 deletions
diff --git a/test/syscalls/linux/socket_netlink_route.cc b/test/syscalls/linux/socket_netlink_route.cc
index 3708f1fb4..ee3604be6 100644
--- a/test/syscalls/linux/socket_netlink_route.cc
+++ b/test/syscalls/linux/socket_netlink_route.cc
@@ -352,8 +352,119 @@ TEST(NetlinkRouteTest, RemoveLinkByIndexNotFound) {
PosixErrorIs(ENODEV, _));
}
+#define IFI_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+#define IFI_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+
+TEST(NetlinkRouteTest, AddLink) {
+ const std::string name = "dummy1";
+ const std::string kind = "dummy";
+
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
+ FileDescriptor fd =
+ ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket(NETLINK_ROUTE));
+
+ struct request {
+ struct nlmsghdr hdr;
+ struct ifinfomsg ifm;
+ char buf[1024];
+ };
+
+ struct request req = {};
+ size_t rta_len = 0;
+
+ req.ifm.ifi_family = AF_UNSPEC;
+ req.ifm.ifi_type = ARPHRD_ETHER;
+ req.ifm.ifi_flags = IFF_BROADCAST;
+
+ struct rtattr *rta_name = reinterpret_cast<struct rtattr*>(
+ req.buf);
+
+ rta_name->rta_type = IFLA_IFNAME;
+ rta_name->rta_len = RTA_LENGTH(name.size() + 1);
+ strcpy((char*)RTA_DATA(rta_name), name.c_str());
+ EXPECT_EQ(rta_name->rta_len, 4 + 7);
+ rta_len += RTA_ALIGN(rta_name->rta_len);
+ EXPECT_EQ(rta_len, 4 + 7 + 1);
+
+ struct rtattr *rta_info = reinterpret_cast<struct rtattr*>(
+ req.buf + rta_len);
+
+ rta_info->rta_type = IFLA_LINKINFO;
+
+ {
+ struct rtattr *rta_info_kind = reinterpret_cast<struct rtattr*>(
+ RTA_DATA(rta_info));
+ rta_info_kind->rta_type = IFLA_INFO_KIND;
+ rta_info_kind->rta_len = RTA_LENGTH(kind.size());
+ char * rta_info_kind_d = reinterpret_cast<char *>(
+ RTA_DATA(rta_info_kind));
+ strcpy(rta_info_kind_d, kind.c_str());
+
+ rta_info->rta_len = RTA_LENGTH(rta_info_kind->rta_len);
+ EXPECT_EQ(rta_info_kind->rta_len, 4 + 5);
+ }
+
+ EXPECT_EQ(rta_info->rta_len, 4 + (4 + 5));
+
+ // Last attribute doesn't require alignment
+ rta_len += rta_info->rta_len;
+ EXPECT_EQ(rta_len, 4 + 7 + 1 + 4 + (4 + 5));
+
+ req.hdr.nlmsg_type = RTM_NEWLINK;
+ req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
+ req.hdr.nlmsg_seq = kSeq;
+ req.hdr.nlmsg_len = NLMSG_LENGTH(RTA_ALIGN(sizeof(req.ifm)) + rta_len);
+
+ EXPECT_EQ(req.hdr.nlmsg_len, 16 + 16 + 4 + 7 + 1 + 4 + (4 + 5));
+
+ {
+ struct rtattr *pos;
+ struct rtattr *head = reinterpret_cast<struct rtattr *>(req.buf);
+ int rem;
+ int len = IFI_PAYLOAD(&req.hdr);
+ EXPECT_EQ(len, 4 + 7 + 1 + 4 + (4 + 5));
+ int i = 1;
+ for (pos = head, rem = len; rem >= (int)sizeof(struct rtattr); pos = RTA_NEXT(pos, rem), i++) {
+ EXPECT_TRUE(pos->rta_len >= sizeof(struct rtattr));
+ EXPECT_TRUE(pos->rta_len <= rem);
+
+ if (!RTA_OK(pos, rem))
+ break;
+
+ switch(i) {
+ case 1: EXPECT_EQ(pos, rta_name); EXPECT_EQ(pos->rta_type, IFLA_IFNAME); EXPECT_EQ(pos->rta_len, 11); EXPECT_EQ(rem, 4 + 7 + 1 + 4 + (4 + 5)); break;
+ case 2: EXPECT_EQ(pos, rta_info); EXPECT_EQ(pos->rta_type, IFLA_LINKINFO); EXPECT_EQ(pos->rta_len, 13); EXPECT_EQ(rem, 4 + (4 + 5)); break;
+ default: EXPECT_EQ(pos->rta_type, -1); break;
+ }
+
+ }
+
+ EXPECT_EQ(i, 3);
+ EXPECT_EQ(rem, -3);
+ }
+
+ ASSERT_NO_ERRNO(NetlinkRequestAckOrError(fd, kSeq, &req, req.hdr.nlmsg_len));
+
+ ASSERT_GE(system("ls /proc/sys/net/ipv4/conf /proc/sys/net/ipv6/conf"), 0);
+ {
+ Link link = ASSERT_NO_ERRNO_AND_VALUE(EthernetLink());
+
+ FileDescriptor fd =
+ ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket(NETLINK_ROUTE));
+
+ struct in_addr addr;
+ ASSERT_EQ(inet_pton(AF_INET, "10.0.0.1", &addr), 1);
+
+ char lladdr[6] = {0x01, 0, 0, 0, 0, 0};
+
+ // Create should succeed, as no such neighbor in kernel.
+ ASSERT_NO_ERRNO(NeighSet(link.index, AF_INET,
+ &addr, sizeof(addr), lladdr, sizeof(lladdr)));
+ }
+}
+
TEST(NetlinkRouteTest, RemoveLinkByNameNotFound) {
- const std::string name = "nodevice?!";
+ const std::string name = "xdummy1"; //nodevice?!";
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
FileDescriptor fd =
@@ -378,8 +489,7 @@ TEST(NetlinkRouteTest, RemoveLinkByNameNotFound) {
req.hdr.nlmsg_len =
NLMSG_LENGTH(sizeof(req.ifm)) + NLMSG_ALIGN(req.rtattr.rta_len);
- EXPECT_THAT(NetlinkRequestAckOrError(fd, kSeq, &req, sizeof(req)),
- PosixErrorIs(ENODEV, _));
+ ASSERT_NO_ERRNO(NetlinkRequestAckOrError(fd, kSeq, &req, sizeof(req)));
}
// SetNeighRequest tests a RTM_NEWNEIGH + NLM_F_CREATE|NLM_F_REPLACE request.
diff --git a/test/syscalls/linux/socket_netlink_route_util.cc b/test/syscalls/linux/socket_netlink_route_util.cc
index a4980a814..f68dbb649 100644
--- a/test/syscalls/linux/socket_netlink_route_util.cc
+++ b/test/syscalls/linux/socket_netlink_route_util.cc
@@ -227,7 +227,7 @@ PosixErrorOr<Link> LoopbackLink() {
PosixErrorOr<Link> EthernetLink() {
ASSIGN_OR_RETURN_ERRNO(auto links, DumpLinks());
for (const auto& link : links) {
- if (link.type == ARPHRD_ETHER) {
+ if (link.type == ARPHRD_ETHER || link.type == 772) {
return link;
}
}