github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/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 "github.com/nicocha30/gvisor-ligolo/pkg/context" 19 "github.com/nicocha30/gvisor-ligolo/pkg/sentry/fsimpl/nsfs" 20 "github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel/auth" 21 ) 22 23 // Namespace represents a network namespace. See network_namespaces(7). 24 // 25 // +stateify savable 26 type Namespace struct { 27 inode *nsfs.Inode 28 29 // stack is the network stack implementation of this network namespace. 30 stack Stack `state:"nosave"` 31 32 // creator allows kernel to create new network stack for network namespaces. 33 // If nil, no networking will function if network is namespaced. 34 // 35 // At afterLoad(), creator will be used to create network stack. Stateify 36 // needs to wait for this field to be loaded before calling afterLoad(). 37 creator NetworkStackCreator `state:"wait"` 38 39 // isRoot indicates whether this is the root network namespace. 40 isRoot bool 41 42 userNS *auth.UserNamespace 43 } 44 45 // NewRootNamespace creates the root network namespace, with creator 46 // allowing new network namespaces to be created. If creator is nil, no 47 // networking will function if the network is namespaced. 48 func NewRootNamespace(stack Stack, creator NetworkStackCreator, userNS *auth.UserNamespace) *Namespace { 49 n := &Namespace{ 50 stack: stack, 51 creator: creator, 52 isRoot: true, 53 userNS: userNS, 54 } 55 return n 56 } 57 58 // UserNamespace returns the user namespace associated with this namespace. 59 func (n *Namespace) UserNamespace() *auth.UserNamespace { 60 return n.userNS 61 } 62 63 // SetInode sets the nsfs `inode` to the namespace. 64 func (n *Namespace) SetInode(inode *nsfs.Inode) { 65 n.inode = inode 66 } 67 68 // GetInode returns the nsfs inode associated with this namespace. 69 func (n *Namespace) GetInode() *nsfs.Inode { 70 return n.inode 71 } 72 73 // NewNamespace creates a new network namespace from the root. 74 func NewNamespace(root *Namespace, userNS *auth.UserNamespace) *Namespace { 75 n := &Namespace{ 76 creator: root.creator, 77 userNS: userNS, 78 } 79 n.init() 80 return n 81 } 82 83 // Destroy implements nsfs.Namespace.Destroy. 84 func (n *Namespace) Destroy(ctx context.Context) { 85 if s := n.Stack(); s != nil { 86 s.Destroy() 87 } 88 } 89 90 // Type implements nsfs.Namespace.Type. 91 func (n *Namespace) Type() string { 92 return "net" 93 } 94 95 // IncRef increments the Namespace's refcount. 96 func (n *Namespace) IncRef() { 97 n.inode.IncRef() 98 } 99 100 // DecRef decrements the Namespace's refcount. 101 func (n *Namespace) DecRef(ctx context.Context) { 102 n.inode.DecRef(ctx) 103 } 104 105 // Stack returns the network stack of n. Stack may return nil if no network 106 // stack is configured. 107 func (n *Namespace) Stack() Stack { 108 return n.stack 109 } 110 111 // IsRoot returns whether n is the root network namespace. 112 func (n *Namespace) IsRoot() bool { 113 return n.isRoot 114 } 115 116 // RestoreRootStack restores the root network namespace with stack. This should 117 // only be called when restoring kernel. 118 func (n *Namespace) RestoreRootStack(stack Stack) { 119 if !n.isRoot { 120 panic("RestoreRootStack can only be called on root network namespace") 121 } 122 if n.stack != nil { 123 panic("RestoreRootStack called after a stack has already been set") 124 } 125 n.stack = stack 126 } 127 128 func (n *Namespace) init() { 129 // Root network namespace will have stack assigned later. 130 if n.isRoot { 131 return 132 } 133 if n.creator != nil { 134 var err error 135 n.stack, err = n.creator.CreateStack() 136 if err != nil { 137 panic(err) 138 } 139 } 140 } 141 142 // afterLoad is invoked by stateify. 143 func (n *Namespace) afterLoad() { 144 n.init() 145 } 146 147 // NetworkStackCreator allows new instances of a network stack to be created. It 148 // is used by the kernel to create new network namespaces when requested. 149 type NetworkStackCreator interface { 150 // CreateStack creates a new network stack for a network namespace. 151 CreateStack() (Stack, error) 152 }