github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/inet/namespace.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package inet 16 17 import ( 18 goContext "context" 19 20 "github.com/metacubex/gvisor/pkg/context" 21 "github.com/metacubex/gvisor/pkg/sentry/fsimpl/nsfs" 22 "github.com/metacubex/gvisor/pkg/sentry/kernel/auth" 23 ) 24 25 // Namespace represents a network namespace. See network_namespaces(7). 26 // 27 // +stateify savable 28 type Namespace struct { 29 inode *nsfs.Inode 30 31 // stack is the network stack implementation of this network namespace. 32 stack Stack `state:"nosave"` 33 34 // creator allows kernel to create new network stack for network namespaces. 35 // If nil, no networking will function if network is namespaced. 36 // 37 // At afterLoad(), creator will be used to create network stack. Stateify 38 // needs to wait for this field to be loaded before calling afterLoad(). 39 creator NetworkStackCreator `state:"wait"` 40 41 // isRoot indicates whether this is the root network namespace. 42 isRoot bool 43 44 userNS *auth.UserNamespace 45 46 // abstractSockets tracks abstract sockets that are in use. 47 abstractSockets AbstractSocketNamespace 48 } 49 50 // NewRootNamespace creates the root network namespace, with creator 51 // allowing new network namespaces to be created. If creator is nil, no 52 // networking will function if the network is namespaced. 53 func NewRootNamespace(stack Stack, creator NetworkStackCreator, userNS *auth.UserNamespace) *Namespace { 54 n := &Namespace{ 55 stack: stack, 56 creator: creator, 57 isRoot: true, 58 userNS: userNS, 59 } 60 n.abstractSockets.init() 61 return n 62 } 63 64 // UserNamespace returns the user namespace associated with this namespace. 65 func (n *Namespace) UserNamespace() *auth.UserNamespace { 66 return n.userNS 67 } 68 69 // SetInode sets the nsfs `inode` to the namespace. 70 func (n *Namespace) SetInode(inode *nsfs.Inode) { 71 n.inode = inode 72 } 73 74 // GetInode returns the nsfs inode associated with this namespace. 75 func (n *Namespace) GetInode() *nsfs.Inode { 76 return n.inode 77 } 78 79 // NewNamespace creates a new network namespace from the root. 80 func NewNamespace(root *Namespace, userNS *auth.UserNamespace) *Namespace { 81 n := &Namespace{ 82 creator: root.creator, 83 userNS: userNS, 84 } 85 n.init() 86 return n 87 } 88 89 // Destroy implements nsfs.Namespace.Destroy. 90 func (n *Namespace) Destroy(ctx context.Context) { 91 if s := n.Stack(); s != nil { 92 s.Destroy() 93 } 94 } 95 96 // Type implements nsfs.Namespace.Type. 97 func (n *Namespace) Type() string { 98 return "net" 99 } 100 101 // IncRef increments the Namespace's refcount. 102 func (n *Namespace) IncRef() { 103 n.inode.IncRef() 104 } 105 106 // DecRef decrements the Namespace's refcount. 107 func (n *Namespace) DecRef(ctx context.Context) { 108 n.inode.DecRef(ctx) 109 } 110 111 // Stack returns the network stack of n. Stack may return nil if no network 112 // stack is configured. 113 func (n *Namespace) Stack() Stack { 114 return n.stack 115 } 116 117 // IsRoot returns whether n is the root network namespace. 118 func (n *Namespace) IsRoot() bool { 119 return n.isRoot 120 } 121 122 // RestoreRootStack restores the root network namespace with stack. This should 123 // only be called when restoring kernel. 124 func (n *Namespace) RestoreRootStack(stack Stack) { 125 if !n.isRoot { 126 panic("RestoreRootStack can only be called on root network namespace") 127 } 128 if n.stack != nil { 129 panic("RestoreRootStack called after a stack has already been set") 130 } 131 n.stack = stack 132 } 133 134 // ResetStack resets the stack in the network namespace to nil. This should 135 // only be called when restoring kernel. 136 func (n *Namespace) ResetStack() { 137 n.stack = nil 138 } 139 140 func (n *Namespace) init() { 141 // Root network namespace will have stack assigned later. 142 if n.isRoot { 143 return 144 } 145 if n.creator != nil { 146 var err error 147 n.stack, err = n.creator.CreateStack() 148 if err != nil { 149 panic(err) 150 } 151 } 152 n.abstractSockets.init() 153 } 154 155 // afterLoad is invoked by stateify. 156 func (n *Namespace) afterLoad(goContext.Context) { 157 n.init() 158 } 159 160 // AbstractSockets returns AbstractSocketNamespace. 161 func (n *Namespace) AbstractSockets() *AbstractSocketNamespace { 162 return &n.abstractSockets 163 } 164 165 // NetworkStackCreator allows new instances of a network stack to be created. It 166 // is used by the kernel to create new network namespaces when requested. 167 type NetworkStackCreator interface { 168 // CreateStack creates a new network stack for a network namespace. 169 CreateStack() (Stack, error) 170 }