diff options
Diffstat (limited to 'pkg/sentry/socket')
-rw-r--r-- | pkg/sentry/socket/hostinet/stack.go | 5 | ||||
-rw-r--r-- | pkg/sentry/socket/netlink/route/protocol.go | 73 | ||||
-rw-r--r-- | pkg/sentry/socket/netstack/BUILD | 1 | ||||
-rw-r--r-- | pkg/sentry/socket/netstack/stack.go | 24 |
4 files changed, 103 insertions, 0 deletions
diff --git a/pkg/sentry/socket/hostinet/stack.go b/pkg/sentry/socket/hostinet/stack.go index b80d64c9a..85cc1b586 100644 --- a/pkg/sentry/socket/hostinet/stack.go +++ b/pkg/sentry/socket/hostinet/stack.go @@ -309,6 +309,11 @@ func (s *Stack) Interfaces() map[int32]inet.Interface { return interfaces } +// AddDummyInterface implements inet.Stack.AddDummyInterface. +func (s *Stack) AddDummyInterface(name string) (int32, error) { + return -1, linuxerr.EACCES +} + // RemoveInterface implements inet.Stack.RemoveInterface. func (*Stack) RemoveInterface(int32) error { return linuxerr.EACCES diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index 38f714c48..359db6e99 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -161,6 +161,77 @@ func (p *Protocol) getLink(ctx context.Context, msg *netlink.Message, ms *netlin return nil } +// newLink handles RTM_NEWLINK requests. +func (p *Protocol) newLink(ctx context.Context, msg *netlink.Message, ms *netlink.MessageSet) *syserr.Error { + stack := inet.StackFromContext(ctx) + if stack == nil { + // No network devices. + return nil + } + + // Parse message. + var ifi linux.InterfaceInfoMessage + attrs, ok := msg.GetData(&ifi) + if !ok { + return syserr.ErrInvalidArgument + } + + if attrs.Empty() { + return nil + } + + // Parse attributes. + var name []byte + var kind string + + for !attrs.Empty() { + 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 + } + name = value[:len(value)-1] + case linux.IFLA_LINKINFO: + attrs := netlink.AttrsView(value) + for !attrs.Empty() { + ahdr, value, rest, ok := attrs.ParseFirst() + if !ok { + return syserr.ErrInvalidArgument + } + attrs = rest + + switch ahdr.Type { + case linux.IFLA_INFO_KIND: + if len(value) < 1 { + return syserr.ErrInvalidArgument + } + kind = string(value) + } + } + } + } + + var ret *syserr.Error = nil + + switch kind { + case "dummy": + _, err := stack.AddDummyInterface(string(name)) + if err != nil { + ret = syserr.ErrInvalidArgument + } + default: + ret = syserr.ErrInvalidArgument + } + + return ret +} + // delLink handles RTM_DELLINK requests. func (p *Protocol) delLink(ctx context.Context, msg *netlink.Message, ms *netlink.MessageSet) *syserr.Error { stack := inet.StackFromContext(ctx) @@ -704,6 +775,8 @@ func (p *Protocol) ProcessMessage(ctx context.Context, msg *netlink.Message, ms switch hdr.Type { case linux.RTM_GETLINK: return p.getLink(ctx, msg, ms) + case linux.RTM_NEWLINK: + return p.newLink(ctx, msg, ms) case linux.RTM_DELLINK: return p.delLink(ctx, msg, ms) case linux.RTM_GETROUTE: diff --git a/pkg/sentry/socket/netstack/BUILD b/pkg/sentry/socket/netstack/BUILD index bf5ec4558..b6da24820 100644 --- a/pkg/sentry/socket/netstack/BUILD +++ b/pkg/sentry/socket/netstack/BUILD @@ -44,6 +44,7 @@ go_library( "//pkg/syserr", "//pkg/tcpip", "//pkg/tcpip/header", + "//pkg/tcpip/link/dummy", "//pkg/tcpip/link/tun", "//pkg/tcpip/network/ipv4", "//pkg/tcpip/network/ipv6", diff --git a/pkg/sentry/socket/netstack/stack.go b/pkg/sentry/socket/netstack/stack.go index 3fceb4cd5..360b270c1 100644 --- a/pkg/sentry/socket/netstack/stack.go +++ b/pkg/sentry/socket/netstack/stack.go @@ -24,6 +24,7 @@ import ( "gvisor.dev/gvisor/pkg/syserr" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" + "gvisor.dev/gvisor/pkg/tcpip/link/dummy" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" "gvisor.dev/gvisor/pkg/tcpip/stack" @@ -71,6 +72,17 @@ func (s *Stack) Interfaces() map[int32]inet.Interface { return is } +func (s *Stack) AddDummyInterface(name string) (int32, error) { + var idx tcpip.NICID = s.nextInterfaceIndex() + + dummyEP := dummy.New() + if err := s.Stack.CreateNICWithOptions(idx, dummyEP, stack.NICOptions{Name: name}); err != nil { + return -1, syserr.TranslateNetstackError(err).ToError() + } + + return int32(idx), nil +} + // RemoveInterface implements inet.Stack.RemoveInterface. func (s *Stack) RemoveInterface(idx int32) error { nic := tcpip.NICID(idx) @@ -146,6 +158,18 @@ func convertAddr(addr inet.InterfaceAddr) (tcpip.ProtocolAddress, error) { return protocolAddress, nil } +func (s *Stack) nextInterfaceIndex() tcpip.NICID { + var maxIdx tcpip.NICID = 0 + + for id, _ := range s.Stack.NICInfo() { + if id > maxIdx { + maxIdx = id + } + } + + return maxIdx + 1 +} + // AddInterfaceAddr implements inet.Stack.AddInterfaceAddr. func (s *Stack) AddInterfaceAddr(idx int32, addr inet.InterfaceAddr) error { protocolAddress, err := convertAddr(addr) |