mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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:
@@ -44,6 +44,7 @@ go_library(
|
||||
"//pkg/refs",
|
||||
"//pkg/sentry/fsimpl/nsfs",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//pkg/sentry/socket/netlink/nlmsg",
|
||||
"//pkg/sentry/socket/unix/transport",
|
||||
"//pkg/sync",
|
||||
"//pkg/sync/locking",
|
||||
|
||||
@@ -17,6 +17,9 @@ package inet
|
||||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/netlink/nlmsg"
|
||||
"gvisor.dev/gvisor/pkg/syserr"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
@@ -39,6 +42,9 @@ type Stack interface {
|
||||
// idx.
|
||||
AddInterfaceAddr(idx int32, addr InterfaceAddr) error
|
||||
|
||||
// SetInterface modifies or adds a new interface.
|
||||
SetInterface(ctx context.Context, msg *nlmsg.Message) *syserr.Error
|
||||
|
||||
// RemoveInterfaceAddr removes an address from the network interface
|
||||
// identified by idx.
|
||||
RemoveInterfaceAddr(idx int32, addr InterfaceAddr) error
|
||||
|
||||
@@ -19,6 +19,9 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/netlink/nlmsg"
|
||||
"gvisor.dev/gvisor/pkg/syserr"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
@@ -61,6 +64,11 @@ func (s *TestStack) RemoveInterface(idx int32) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetInterface implements Stack.
|
||||
func (s *TestStack) SetInterface(ctx context.Context, msg *nlmsg.Message) *syserr.Error {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// InterfaceAddrs implements Stack.
|
||||
func (s *TestStack) InterfaceAddrs() map[int32][]InterfaceAddr {
|
||||
return s.InterfaceAddrsMap
|
||||
|
||||
@@ -39,6 +39,7 @@ go_library(
|
||||
"//pkg/sentry/kernel/time",
|
||||
"//pkg/sentry/socket",
|
||||
"//pkg/sentry/socket/control",
|
||||
"//pkg/sentry/socket/netlink/nlmsg",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/syserr",
|
||||
"//pkg/tcpip",
|
||||
|
||||
@@ -23,10 +23,12 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"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/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/stack"
|
||||
@@ -165,6 +167,64 @@ func (s *Stack) InterfaceAddrs() map[int32][]inet.InterfaceAddr {
|
||||
return addrs
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// AddInterfaceAddr implements inet.Stack.AddInterfaceAddr.
|
||||
func (*Stack) AddInterfaceAddr(idx int32, addr inet.InterfaceAddr) error {
|
||||
return addInterfaceAddr(idx, addr)
|
||||
|
||||
@@ -169,63 +169,7 @@ func (p *Protocol) newLink(ctx context.Context, msg *nlmsg.Message, ms *nlmsg.Me
|
||||
return syserr.ErrProtocolNotSupported
|
||||
}
|
||||
|
||||
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 stack.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 != 0 {
|
||||
return syserr.ErrExists
|
||||
}
|
||||
if flags&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
|
||||
return stack.SetInterface(ctx, msg)
|
||||
}
|
||||
|
||||
// delLink handles RTM_DELLINK requests.
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user