Support RTM_SETLINK in gVisor.

RTM_NEWLINK is the preferred way to change a link's configs. RTM_SETLINK is
needed by setting up Docker in gVisor.

PiperOrigin-RevId: 649789500
This commit is contained in:
Jing Chen
2024-07-06 00:49:54 -07:00
committed by gVisor bot
parent 8820fde4ea
commit 222258a585
2 changed files with 30 additions and 6 deletions
+19 -2
View File
@@ -162,6 +162,7 @@ func (p *Protocol) getLink(ctx context.Context, s *netlink.Socket, msg *nlmsg.Me
return nil
}
// newLink handles RTM_NEWLINK reqeusts.
func (p *Protocol) newLink(ctx context.Context, s *netlink.Socket, msg *nlmsg.Message, ms *nlmsg.MessageSet) *syserr.Error {
stack := s.Stack()
if stack == nil {
@@ -172,6 +173,21 @@ func (p *Protocol) newLink(ctx context.Context, s *netlink.Socket, msg *nlmsg.Me
return stack.SetInterface(ctx, msg)
}
// setLink handles RTM_SETLINK requests.
func (p *Protocol) setLink(ctx context.Context, s *netlink.Socket, msg *nlmsg.Message, ms *nlmsg.MessageSet) *syserr.Error {
stack := s.Stack()
if stack == nil {
// No network stack.
return syserr.ErrProtocolNotSupported
}
if msg.Header().Flags&linux.NLM_F_CREATE == linux.NLM_F_CREATE {
return syserr.ErrInvalidArgument
}
return stack.SetInterface(ctx, msg)
}
// delLink handles RTM_DELLINK requests.
func (p *Protocol) delLink(ctx context.Context, s *netlink.Socket, msg *nlmsg.Message, ms *nlmsg.MessageSet) *syserr.Error {
stack := s.Stack()
@@ -594,14 +610,15 @@ func (p *Protocol) ProcessMessage(ctx context.Context, s *netlink.Socket, msg *n
return p.getLink(ctx, s, msg, ms)
case linux.RTM_DELLINK:
return p.delLink(ctx, s, msg, ms)
case linux.RTM_SETLINK:
// RTM_NEWLINK is backward compatible to RTM_SETLINK.
return p.setLink(ctx, s, msg, ms)
case linux.RTM_GETROUTE:
return p.dumpRoutes(ctx, s, msg, ms)
case linux.RTM_NEWADDR:
return p.newAddr(ctx, s, msg, ms)
case linux.RTM_DELADDR:
return p.delAddr(ctx, s, msg, ms)
case linux.RTM_SETLINK:
return nil
default:
return syserr.ErrNotSupported
}
+11 -4
View File
@@ -207,7 +207,14 @@ TEST(NetlinkRouteTest, GetLinkByIndex) {
EXPECT_TRUE(found) << "Netlink response does not contain any links.";
}
TEST(NetlinkRouteTest, ChangeLinkName) {
// NetlinkRouteTest with a single parameter that must be RTM_NEWLINK or
// RTM_SETLINK.
using NetlinkSetLinkTest = ::testing::TestWithParam<int>;
INSTANTIATE_TEST_SUITE_P(_, NetlinkSetLinkTest,
::testing::Values(RTM_NEWLINK, RTM_SETLINK));
TEST_P(NetlinkSetLinkTest, ChangeLinkName) {
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
SKIP_IF(IsRunningWithHostinet());
// Hosts that run with old kernel allow renaming only when
@@ -231,7 +238,7 @@ TEST(NetlinkRouteTest, ChangeLinkName) {
// Change the link name.
struct request req = {};
req.hdr.nlmsg_len = sizeof(req);
req.hdr.nlmsg_type = RTM_NEWLINK;
req.hdr.nlmsg_type = GetParam();
req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
req.hdr.nlmsg_seq = kSeq;
req.ifm.ifi_family = AF_UNSPEC;
@@ -265,7 +272,7 @@ TEST(NetlinkRouteTest, ChangeLinkName) {
EXPECT_TRUE(found) << "Netlink response does not contain any links.";
}
TEST(NetlinkRouteTest, ChangeMTU) {
TEST_P(NetlinkSetLinkTest, ChangeMTU) {
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
SKIP_IF(IsRunningWithHostinet());
SKIP_IF(!IsRunningOnGvisor());
@@ -283,7 +290,7 @@ TEST(NetlinkRouteTest, ChangeMTU) {
// Change the MTU.
req.hdr.nlmsg_len = sizeof(req);
req.hdr.nlmsg_type = RTM_NEWLINK;
req.hdr.nlmsg_type = GetParam();
req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
req.hdr.nlmsg_seq = kSeq;
req.ifm.ifi_family = AF_UNSPEC;