diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2021-09-26 11:22:35 +0000 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2021-09-26 11:22:35 +0000 |
commit | ea43d9ffc0fd7bc1f42bada76006dbcf26f752af (patch) | |
tree | b6921fcae6d5154ae292510c16d042abed112774 /test/syscalls/linux/socket_netlink_route.cc | |
parent | 96667cf4a3c30726cb4242f749afcee42ce7cd43 (diff) |
WIP: testfeature/nl-neighbor
Diffstat (limited to 'test/syscalls/linux/socket_netlink_route.cc')
-rw-r--r-- | test/syscalls/linux/socket_netlink_route.cc | 116 |
1 files changed, 113 insertions, 3 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. |