diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/e2e/integration_test.go | 46 | ||||
-rw-r--r-- | test/syscalls/linux/socket_netlink_route.cc | 116 |
2 files changed, 157 insertions, 5 deletions
diff --git a/test/e2e/integration_test.go b/test/e2e/integration_test.go index 9e22c9a7d..d41139944 100644 --- a/test/e2e/integration_test.go +++ b/test/e2e/integration_test.go @@ -742,3 +742,49 @@ func TestUnmount(t *testing.T) { t.Fatalf("docker run failed: %v", err) } } + +func TestDeleteInterface(t *testing.T) { + if testutil.IsRunningWithHostNet() { + t.Skip("not able to remove interfaces on hostnet") + } + + ctx := context.Background() + d := dockerutil.MakeContainer(ctx, t) + defer d.CleanUp(ctx) + + opts := dockerutil.RunOpts{ + Image: "basic/alpine", + CapAdd: []string{"NET_ADMIN"}, + } + if err := d.Spawn(ctx, opts, "sleep", "1000"); err != nil { + t.Fatalf("docker run failed: %v", err) + } + + // We should be able to remove eth0. + output, err := d.Exec(ctx, dockerutil.ExecOpts{}, "/bin/sh", "-c", "ip link del dev eth0") + if err != nil { + t.Fatalf("failed to remove eth0: %s, output: %s", err, output) + } + // Verify that eth0 is no longer there. + output, err = d.Exec(ctx, dockerutil.ExecOpts{}, "/bin/sh", "-c", "ip link show") + if err != nil { + t.Fatalf("docker exec ip link show failed: %s, output: %s", err, output) + } + if strings.Contains(output, "eth0") { + t.Fatalf("failed to remove eth0") + } + + // Loopback device can't be removed. + output, err = d.Exec(ctx, dockerutil.ExecOpts{}, "/bin/sh", "-c", "ip link del dev lo") + if err == nil { + t.Fatalf("should not remove the loopback device: %v", output) + } + // Verify that lo is still there. + output, err = d.Exec(ctx, dockerutil.ExecOpts{}, "/bin/sh", "-c", "ip link show") + if err != nil { + t.Fatalf("docker exec ip link show failed: %s, output: %s", err, output) + } + if !strings.Contains(output, "lo") { + t.Fatalf("loopback interface is removed") + } +} diff --git a/test/syscalls/linux/socket_netlink_route.cc b/test/syscalls/linux/socket_netlink_route.cc index a5c788346..d5e1ce0cc 100644 --- a/test/syscalls/linux/socket_netlink_route.cc +++ b/test/syscalls/linux/socket_netlink_route.cc @@ -44,6 +44,7 @@ namespace { constexpr uint32_t kSeq = 12345; +using ::testing::_; using ::testing::AnyOf; using ::testing::Eq; @@ -244,7 +245,7 @@ TEST(NetlinkRouteTest, GetLinkByIndexNotFound) { req.ifm.ifi_index = 1234590; EXPECT_THAT(NetlinkRequestAckOrError(fd, kSeq, &req, sizeof(req)), - PosixErrorIs(ENODEV, ::testing::_)); + PosixErrorIs(ENODEV, _)); } TEST(NetlinkRouteTest, GetLinkByNameNotFound) { @@ -273,7 +274,112 @@ TEST(NetlinkRouteTest, GetLinkByNameNotFound) { NLMSG_LENGTH(sizeof(req.ifm)) + NLMSG_ALIGN(req.rtattr.rta_len); EXPECT_THAT(NetlinkRequestAckOrError(fd, kSeq, &req, sizeof(req)), - PosixErrorIs(ENODEV, ::testing::_)); + PosixErrorIs(ENODEV, _)); +} + +TEST(NetlinkRouteTest, RemoveLoopbackByName) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))); + Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink()); + + FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket(NETLINK_ROUTE)); + + struct request { + struct nlmsghdr hdr; + struct ifinfomsg ifm; + struct rtattr rtattr; + char ifname[IFNAMSIZ]; + char pad[NLMSG_ALIGNTO + RTA_ALIGNTO]; + }; + + struct request req = {}; + req.hdr.nlmsg_type = RTM_DELLINK; + req.hdr.nlmsg_flags = NLM_F_REQUEST; + 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.hdr.nlmsg_len = + NLMSG_LENGTH(sizeof(req.ifm)) + NLMSG_ALIGN(req.rtattr.rta_len); + + EXPECT_THAT(NetlinkRequestAckOrError(fd, kSeq, &req, sizeof(req)), + PosixErrorIs(ENOTSUP, _)); +} + +TEST(NetlinkRouteTest, RemoveLoopbackByIndex) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))); + Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink()); + FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(NetlinkBoundSocket(NETLINK_ROUTE)); + + struct request { + struct nlmsghdr hdr; + struct ifinfomsg ifm; + }; + + struct request req = {}; + req.hdr.nlmsg_len = sizeof(req); + req.hdr.nlmsg_type = RTM_DELLINK; + 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; + + EXPECT_THAT(NetlinkRequestAckOrError(fd, kSeq, &req, sizeof(req)), + PosixErrorIs(ENOTSUP, _)); +} + +TEST(NetlinkRouteTest, RemoveLinkByIndexNotFound) { + 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; + }; + + struct request req = {}; + req.hdr.nlmsg_len = sizeof(req); + req.hdr.nlmsg_type = RTM_GETLINK; + req.hdr.nlmsg_flags = NLM_F_REQUEST; + req.hdr.nlmsg_seq = kSeq; + req.ifm.ifi_family = AF_UNSPEC; + req.ifm.ifi_index = 1234590; + + EXPECT_THAT(NetlinkRequestAckOrError(fd, kSeq, &req, sizeof(req)), + PosixErrorIs(ENODEV, _)); +} + +TEST(NetlinkRouteTest, RemoveLinkByNameNotFound) { + const std::string name = "nodevice?!"; + + 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; + struct rtattr rtattr; + char ifname[IFNAMSIZ]; + char pad[NLMSG_ALIGNTO + RTA_ALIGNTO]; + }; + + struct request req = {}; + req.hdr.nlmsg_type = RTM_DELLINK; + req.hdr.nlmsg_flags = NLM_F_REQUEST; + req.hdr.nlmsg_seq = kSeq; + req.ifm.ifi_family = AF_UNSPEC; + req.rtattr.rta_type = IFLA_IFNAME; + req.rtattr.rta_len = RTA_LENGTH(name.size() + 1); + strncpy(req.ifname, name.c_str(), sizeof(req.ifname)); + 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, _)); } TEST(NetlinkRouteTest, MsgHdrMsgUnsuppType) { @@ -295,7 +401,7 @@ TEST(NetlinkRouteTest, MsgHdrMsgUnsuppType) { req.ifm.ifi_family = AF_UNSPEC; EXPECT_THAT(NetlinkRequestAckOrError(fd, kSeq, &req, sizeof(req)), - PosixErrorIs(EOPNOTSUPP, ::testing::_)); + PosixErrorIs(EOPNOTSUPP, _)); } TEST(NetlinkRouteTest, MsgHdrMsgTrunc) { @@ -536,7 +642,7 @@ TEST(NetlinkRouteTest, AddAndRemoveAddr) { // Second delete should fail, as address no longer exists. EXPECT_THAT(LinkDelLocalAddr(loopback_link.index, AF_INET, /*prefixlen=*/24, &addr, sizeof(addr)), - PosixErrorIs(EADDRNOTAVAIL, ::testing::_)); + PosixErrorIs(EADDRNOTAVAIL, _)); }); // Replace an existing address should succeed. @@ -546,7 +652,7 @@ TEST(NetlinkRouteTest, AddAndRemoveAddr) { // Create exclusive should fail, as we created the address above. EXPECT_THAT(LinkAddExclusiveLocalAddr(loopback_link.index, AF_INET, /*prefixlen=*/24, &addr, sizeof(addr)), - PosixErrorIs(EEXIST, ::testing::_)); + PosixErrorIs(EEXIST, _)); } // GetRouteDump tests a RTM_GETROUTE + NLM_F_DUMP request. |