summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/inet
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/inet')
-rw-r--r--pkg/sentry/inet/BUILD20
-rw-r--r--pkg/sentry/inet/context.go35
-rw-r--r--pkg/sentry/inet/inet.go191
-rw-r--r--pkg/sentry/inet/namespace.go102
-rw-r--r--pkg/sentry/inet/test_stack.go118
5 files changed, 466 insertions, 0 deletions
diff --git a/pkg/sentry/inet/BUILD b/pkg/sentry/inet/BUILD
new file mode 100644
index 000000000..07bf39fed
--- /dev/null
+++ b/pkg/sentry/inet/BUILD
@@ -0,0 +1,20 @@
+load("//tools:defs.bzl", "go_library")
+
+package(
+ default_visibility = ["//:sandbox"],
+ licenses = ["notice"],
+)
+
+go_library(
+ name = "inet",
+ srcs = [
+ "context.go",
+ "inet.go",
+ "namespace.go",
+ "test_stack.go",
+ ],
+ deps = [
+ "//pkg/context",
+ "//pkg/tcpip/stack",
+ ],
+)
diff --git a/pkg/sentry/inet/context.go b/pkg/sentry/inet/context.go
new file mode 100644
index 000000000..e8cc1bffd
--- /dev/null
+++ b/pkg/sentry/inet/context.go
@@ -0,0 +1,35 @@
+// Copyright 2018 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package inet
+
+import (
+ "gvisor.dev/gvisor/pkg/context"
+)
+
+// contextID is the inet package's type for context.Context.Value keys.
+type contextID int
+
+const (
+ // CtxStack is a Context.Value key for a network stack.
+ CtxStack contextID = iota
+)
+
+// StackFromContext returns the network stack associated with ctx.
+func StackFromContext(ctx context.Context) Stack {
+ if v := ctx.Value(CtxStack); v != nil {
+ return v.(Stack)
+ }
+ return nil
+}
diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go
new file mode 100644
index 000000000..2916a0644
--- /dev/null
+++ b/pkg/sentry/inet/inet.go
@@ -0,0 +1,191 @@
+// Copyright 2018 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package inet defines semantics for IP stacks.
+package inet
+
+import "gvisor.dev/gvisor/pkg/tcpip/stack"
+
+// Stack represents a TCP/IP stack.
+type Stack interface {
+ // Interfaces returns all network interfaces as a mapping from interface
+ // indexes to interface properties. Interface indices are strictly positive
+ // integers.
+ Interfaces() map[int32]Interface
+
+ // InterfaceAddrs returns all network interface addresses as a mapping from
+ // interface indexes to a slice of associated interface address properties.
+ InterfaceAddrs() map[int32][]InterfaceAddr
+
+ // AddInterfaceAddr adds an address to the network interface identified by
+ // index.
+ AddInterfaceAddr(idx int32, addr InterfaceAddr) error
+
+ // SupportsIPv6 returns true if the stack supports IPv6 connectivity.
+ SupportsIPv6() bool
+
+ // TCPReceiveBufferSize returns TCP receive buffer size settings.
+ TCPReceiveBufferSize() (TCPBufferSize, error)
+
+ // SetTCPReceiveBufferSize attempts to change TCP receive buffer size
+ // settings.
+ SetTCPReceiveBufferSize(size TCPBufferSize) error
+
+ // TCPSendBufferSize returns TCP send buffer size settings.
+ TCPSendBufferSize() (TCPBufferSize, error)
+
+ // SetTCPSendBufferSize attempts to change TCP send buffer size settings.
+ SetTCPSendBufferSize(size TCPBufferSize) error
+
+ // TCPSACKEnabled returns true if RFC 2018 TCP Selective Acknowledgements
+ // are enabled.
+ TCPSACKEnabled() (bool, error)
+
+ // SetTCPSACKEnabled attempts to change TCP selective acknowledgement
+ // settings.
+ SetTCPSACKEnabled(enabled bool) error
+
+ // Statistics reports stack statistics.
+ Statistics(stat interface{}, arg string) error
+
+ // RouteTable returns the network stack's route table.
+ RouteTable() []Route
+
+ // Resume restarts the network stack after restore.
+ Resume()
+
+ // RegisteredEndpoints returns all endpoints which are currently registered.
+ RegisteredEndpoints() []stack.TransportEndpoint
+
+ // CleanupEndpoints returns endpoints currently in the cleanup state.
+ CleanupEndpoints() []stack.TransportEndpoint
+
+ // RestoreCleanupEndpoints adds endpoints to cleanup tracking. This is useful
+ // for restoring a stack after a save.
+ RestoreCleanupEndpoints([]stack.TransportEndpoint)
+}
+
+// Interface contains information about a network interface.
+type Interface struct {
+ // DeviceType is the device type, a Linux ARPHRD_* constant.
+ DeviceType uint16
+
+ // Flags is the device flags; see netdevice(7), under "Ioctls",
+ // "SIOCGIFFLAGS, SIOCSIFFLAGS".
+ Flags uint32
+
+ // Name is the device name.
+ Name string
+
+ // Addr is the hardware device address.
+ Addr []byte
+
+ // MTU is the maximum transmission unit.
+ MTU uint32
+}
+
+// InterfaceAddr contains information about a network interface address.
+type InterfaceAddr struct {
+ // Family is the address family, a Linux AF_* constant.
+ Family uint8
+
+ // PrefixLen is the address prefix length.
+ PrefixLen uint8
+
+ // Flags is the address flags.
+ Flags uint8
+
+ // Addr is the actual address.
+ Addr []byte
+}
+
+// TCPBufferSize contains settings controlling TCP buffer sizing.
+//
+// +stateify savable
+type TCPBufferSize struct {
+ // Min is the minimum size.
+ Min int
+
+ // Default is the default size.
+ Default int
+
+ // Max is the maximum size.
+ Max int
+}
+
+// StatDev describes one line of /proc/net/dev, i.e., stats for one network
+// interface.
+type StatDev [16]uint64
+
+// Route contains information about a network route.
+type Route struct {
+ // Family is the address family, a Linux AF_* constant.
+ Family uint8
+
+ // DstLen is the length of the destination address.
+ DstLen uint8
+
+ // SrcLen is the length of the source address.
+ SrcLen uint8
+
+ // TOS is the Type of Service filter.
+ TOS uint8
+
+ // Table is the routing table ID.
+ Table uint8
+
+ // Protocol is the route origin, a Linux RTPROT_* constant.
+ Protocol uint8
+
+ // Scope is the distance to destination, a Linux RT_SCOPE_* constant.
+ Scope uint8
+
+ // Type is the route origin, a Linux RTN_* constant.
+ Type uint8
+
+ // Flags are route flags. See rtnetlink(7) under "rtm_flags".
+ Flags uint32
+
+ // DstAddr is the route destination address (RTA_DST).
+ DstAddr []byte
+
+ // SrcAddr is the route source address (RTA_SRC).
+ SrcAddr []byte
+
+ // OutputInterface is the output interface index (RTA_OIF).
+ OutputInterface int32
+
+ // GatewayAddr is the route gateway address (RTA_GATEWAY).
+ GatewayAddr []byte
+}
+
+// Below SNMP metrics are from Linux/usr/include/linux/snmp.h.
+
+// StatSNMPIP describes Ip line of /proc/net/snmp.
+type StatSNMPIP [19]uint64
+
+// StatSNMPICMP describes Icmp line of /proc/net/snmp.
+type StatSNMPICMP [27]uint64
+
+// StatSNMPICMPMSG describes IcmpMsg line of /proc/net/snmp.
+type StatSNMPICMPMSG [512]uint64
+
+// StatSNMPTCP describes Tcp line of /proc/net/snmp.
+type StatSNMPTCP [15]uint64
+
+// StatSNMPUDP describes Udp line of /proc/net/snmp.
+type StatSNMPUDP [8]uint64
+
+// StatSNMPUDPLite describes UdpLite line of /proc/net/snmp.
+type StatSNMPUDPLite [8]uint64
diff --git a/pkg/sentry/inet/namespace.go b/pkg/sentry/inet/namespace.go
new file mode 100644
index 000000000..029af3025
--- /dev/null
+++ b/pkg/sentry/inet/namespace.go
@@ -0,0 +1,102 @@
+// Copyright 2020 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package inet
+
+// Namespace represents a network namespace. See network_namespaces(7).
+//
+// +stateify savable
+type Namespace struct {
+ // stack is the network stack implementation of this network namespace.
+ stack Stack `state:"nosave"`
+
+ // creator allows kernel to create new network stack for network namespaces.
+ // If nil, no networking will function if network is namespaced.
+ //
+ // At afterLoad(), creator will be used to create network stack. Stateify
+ // needs to wait for this field to be loaded before calling afterLoad().
+ creator NetworkStackCreator `state:"wait"`
+
+ // isRoot indicates whether this is the root network namespace.
+ isRoot bool
+}
+
+// NewRootNamespace creates the root network namespace, with creator
+// allowing new network namespaces to be created. If creator is nil, no
+// networking will function if the network is namespaced.
+func NewRootNamespace(stack Stack, creator NetworkStackCreator) *Namespace {
+ return &Namespace{
+ stack: stack,
+ creator: creator,
+ isRoot: true,
+ }
+}
+
+// NewNamespace creates a new network namespace from the root.
+func NewNamespace(root *Namespace) *Namespace {
+ n := &Namespace{
+ creator: root.creator,
+ }
+ n.init()
+ return n
+}
+
+// Stack returns the network stack of n. Stack may return nil if no network
+// stack is configured.
+func (n *Namespace) Stack() Stack {
+ return n.stack
+}
+
+// IsRoot returns whether n is the root network namespace.
+func (n *Namespace) IsRoot() bool {
+ return n.isRoot
+}
+
+// RestoreRootStack restores the root network namespace with stack. This should
+// only be called when restoring kernel.
+func (n *Namespace) RestoreRootStack(stack Stack) {
+ if !n.isRoot {
+ panic("RestoreRootStack can only be called on root network namespace")
+ }
+ if n.stack != nil {
+ panic("RestoreRootStack called after a stack has already been set")
+ }
+ n.stack = stack
+}
+
+func (n *Namespace) init() {
+ // Root network namespace will have stack assigned later.
+ if n.isRoot {
+ return
+ }
+ if n.creator != nil {
+ var err error
+ n.stack, err = n.creator.CreateStack()
+ if err != nil {
+ panic(err)
+ }
+ }
+}
+
+// afterLoad is invoked by stateify.
+func (n *Namespace) afterLoad() {
+ n.init()
+}
+
+// NetworkStackCreator allows new instances of a network stack to be created. It
+// is used by the kernel to create new network namespaces when requested.
+type NetworkStackCreator interface {
+ // CreateStack creates a new network stack for a network namespace.
+ CreateStack() (Stack, error)
+}
diff --git a/pkg/sentry/inet/test_stack.go b/pkg/sentry/inet/test_stack.go
new file mode 100644
index 000000000..d8961fc94
--- /dev/null
+++ b/pkg/sentry/inet/test_stack.go
@@ -0,0 +1,118 @@
+// Copyright 2018 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package inet
+
+import "gvisor.dev/gvisor/pkg/tcpip/stack"
+
+// TestStack is a dummy implementation of Stack for tests.
+type TestStack struct {
+ InterfacesMap map[int32]Interface
+ InterfaceAddrsMap map[int32][]InterfaceAddr
+ RouteList []Route
+ SupportsIPv6Flag bool
+ TCPRecvBufSize TCPBufferSize
+ TCPSendBufSize TCPBufferSize
+ TCPSACKFlag bool
+}
+
+// NewTestStack returns a TestStack with no network interfaces. The value of
+// all other options is unspecified; tests that rely on specific values must
+// set them explicitly.
+func NewTestStack() *TestStack {
+ return &TestStack{
+ InterfacesMap: make(map[int32]Interface),
+ InterfaceAddrsMap: make(map[int32][]InterfaceAddr),
+ }
+}
+
+// Interfaces implements Stack.Interfaces.
+func (s *TestStack) Interfaces() map[int32]Interface {
+ return s.InterfacesMap
+}
+
+// InterfaceAddrs implements Stack.InterfaceAddrs.
+func (s *TestStack) InterfaceAddrs() map[int32][]InterfaceAddr {
+ return s.InterfaceAddrsMap
+}
+
+// AddInterfaceAddr implements Stack.AddInterfaceAddr.
+func (s *TestStack) AddInterfaceAddr(idx int32, addr InterfaceAddr) error {
+ s.InterfaceAddrsMap[idx] = append(s.InterfaceAddrsMap[idx], addr)
+ return nil
+}
+
+// SupportsIPv6 implements Stack.SupportsIPv6.
+func (s *TestStack) SupportsIPv6() bool {
+ return s.SupportsIPv6Flag
+}
+
+// TCPReceiveBufferSize implements Stack.TCPReceiveBufferSize.
+func (s *TestStack) TCPReceiveBufferSize() (TCPBufferSize, error) {
+ return s.TCPRecvBufSize, nil
+}
+
+// SetTCPReceiveBufferSize implements Stack.SetTCPReceiveBufferSize.
+func (s *TestStack) SetTCPReceiveBufferSize(size TCPBufferSize) error {
+ s.TCPRecvBufSize = size
+ return nil
+}
+
+// TCPSendBufferSize implements Stack.TCPSendBufferSize.
+func (s *TestStack) TCPSendBufferSize() (TCPBufferSize, error) {
+ return s.TCPSendBufSize, nil
+}
+
+// SetTCPSendBufferSize implements Stack.SetTCPSendBufferSize.
+func (s *TestStack) SetTCPSendBufferSize(size TCPBufferSize) error {
+ s.TCPSendBufSize = size
+ return nil
+}
+
+// TCPSACKEnabled implements Stack.TCPSACKEnabled.
+func (s *TestStack) TCPSACKEnabled() (bool, error) {
+ return s.TCPSACKFlag, nil
+}
+
+// SetTCPSACKEnabled implements Stack.SetTCPSACKEnabled.
+func (s *TestStack) SetTCPSACKEnabled(enabled bool) error {
+ s.TCPSACKFlag = enabled
+ return nil
+}
+
+// Statistics implements inet.Stack.Statistics.
+func (s *TestStack) Statistics(stat interface{}, arg string) error {
+ return nil
+}
+
+// RouteTable implements Stack.RouteTable.
+func (s *TestStack) RouteTable() []Route {
+ return s.RouteList
+}
+
+// Resume implements Stack.Resume.
+func (s *TestStack) Resume() {}
+
+// RegisteredEndpoints implements inet.Stack.RegisteredEndpoints.
+func (s *TestStack) RegisteredEndpoints() []stack.TransportEndpoint {
+ return nil
+}
+
+// CleanupEndpoints implements inet.Stack.CleanupEndpoints.
+func (s *TestStack) CleanupEndpoints() []stack.TransportEndpoint {
+ return nil
+}
+
+// RestoreCleanupEndpoints implements inet.Stack.RestoreCleanupEndpoints.
+func (s *TestStack) RestoreCleanupEndpoints([]stack.TransportEndpoint) {}