Pass NEWLINK netlink commands to network stacks

The NEWLINK commands contains many properties and here is no reason to have
another abstract interface between the Sentry and network stacks.

PiperOrigin-RevId: 627916629
This commit is contained in:
Andrei Vagin
2024-04-24 18:42:44 -07:00
committed by gVisor bot
parent 9c7a659d7b
commit 129734a352
8 changed files with 138 additions and 57 deletions
+1
View File
@@ -39,6 +39,7 @@ go_library(
"//pkg/sentry/kernel/time",
"//pkg/sentry/socket",
"//pkg/sentry/socket/netfilter",
"//pkg/sentry/socket/netlink/nlmsg",
"//pkg/sentry/vfs",
"//pkg/sync",
"//pkg/syserr",
+60
View File
@@ -18,10 +18,12 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/refs"
"gvisor.dev/gvisor/pkg/sentry/inet"
"gvisor.dev/gvisor/pkg/sentry/socket/netlink/nlmsg"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/header"
@@ -99,6 +101,64 @@ func (s *Stack) RemoveInterface(idx int32) error {
return syserr.TranslateNetstackError(s.Stack.RemoveNIC(nic)).ToError()
}
// SetInterface implements inet.Stack.SetInterface.
func (s *Stack) SetInterface(ctx context.Context, msg *nlmsg.Message) *syserr.Error {
var ifinfomsg linux.InterfaceInfoMessage
attrs, ok := msg.GetData(&ifinfomsg)
if !ok {
return syserr.ErrInvalidArgument
}
for !attrs.Empty() {
// The index is unspecified, search by the interface name.
ahdr, value, rest, ok := attrs.ParseFirst()
if !ok {
return syserr.ErrInvalidArgument
}
attrs = rest
switch ahdr.Type {
case linux.IFLA_IFNAME:
if len(value) < 1 {
return syserr.ErrInvalidArgument
}
if ifinfomsg.Index != 0 {
// Device name changing isn't supported yet.
return syserr.ErrNotSupported
}
ifname := string(value[:len(value)-1])
for idx, ifa := range s.Interfaces() {
if ifname == ifa.Name {
ifinfomsg.Index = idx
break
}
}
default:
ctx.Warningf("unexpected attribute: %x", ahdr.Type)
return syserr.ErrNotSupported
}
}
if ifinfomsg.Index == 0 {
return syserr.ErrNoDevice
}
flags := msg.Header().Flags
if flags&(linux.NLM_F_EXCL|linux.NLM_F_REPLACE) != 0 {
return syserr.ErrExists
}
if ifinfomsg.Flags != 0 || ifinfomsg.Change != 0 {
if ifinfomsg.Change & ^uint32(linux.IFF_UP) != 0 {
ctx.Warningf("Unsupported ifi_change flags: %x", ifinfomsg.Change)
return syserr.ErrInvalidArgument
}
if ifinfomsg.Flags & ^uint32(linux.IFF_UP) != 0 {
ctx.Warningf("Unsupported ifi_flags: %x", ifinfomsg.Change)
return syserr.ErrInvalidArgument
}
// Netstack interfaces are always up.
}
return nil
}
// InterfaceAddrs implements inet.Stack.InterfaceAddrs.
func (s *Stack) InterfaceAddrs() map[int32][]inet.InterfaceAddr {
nicAddrs := make(map[int32][]inet.InterfaceAddr)