github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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  // Namespace represents a network namespace. See network_namespaces(7).
    18  //
    19  // +stateify savable
    20  type Namespace struct {
    21  	// stack is the network stack implementation of this network namespace.
    22  	stack Stack `state:"nosave"`
    23  
    24  	// creator allows kernel to create new network stack for network namespaces.
    25  	// If nil, no networking will function if network is namespaced.
    26  	//
    27  	// At afterLoad(), creator will be used to create network stack. Stateify
    28  	// needs to wait for this field to be loaded before calling afterLoad().
    29  	creator NetworkStackCreator `state:"wait"`
    30  
    31  	// isRoot indicates whether this is the root network namespace.
    32  	isRoot bool
    33  }
    34  
    35  // NewRootNamespace creates the root network namespace, with creator
    36  // allowing new network namespaces to be created. If creator is nil, no
    37  // networking will function if the network is namespaced.
    38  func NewRootNamespace(stack Stack, creator NetworkStackCreator) *Namespace {
    39  	return &Namespace{
    40  		stack:   stack,
    41  		creator: creator,
    42  		isRoot:  true,
    43  	}
    44  }
    45  
    46  // NewNamespace creates a new network namespace from the root.
    47  func NewNamespace(root *Namespace) *Namespace {
    48  	n := &Namespace{
    49  		creator: root.creator,
    50  	}
    51  	n.init()
    52  	return n
    53  }
    54  
    55  // Stack returns the network stack of n. Stack may return nil if no network
    56  // stack is configured.
    57  func (n *Namespace) Stack() Stack {
    58  	return n.stack
    59  }
    60  
    61  // IsRoot returns whether n is the root network namespace.
    62  func (n *Namespace) IsRoot() bool {
    63  	return n.isRoot
    64  }
    65  
    66  // RestoreRootStack restores the root network namespace with stack. This should
    67  // only be called when restoring kernel.
    68  func (n *Namespace) RestoreRootStack(stack Stack) {
    69  	if !n.isRoot {
    70  		panic("RestoreRootStack can only be called on root network namespace")
    71  	}
    72  	if n.stack != nil {
    73  		panic("RestoreRootStack called after a stack has already been set")
    74  	}
    75  	n.stack = stack
    76  }
    77  
    78  func (n *Namespace) init() {
    79  	// Root network namespace will have stack assigned later.
    80  	if n.isRoot {
    81  		return
    82  	}
    83  	if n.creator != nil {
    84  		var err error
    85  		n.stack, err = n.creator.CreateStack()
    86  		if err != nil {
    87  			panic(err)
    88  		}
    89  	}
    90  }
    91  
    92  // afterLoad is invoked by stateify.
    93  func (n *Namespace) afterLoad() {
    94  	n.init()
    95  }
    96  
    97  // NetworkStackCreator allows new instances of a network stack to be created. It
    98  // is used by the kernel to create new network namespaces when requested.
    99  type NetworkStackCreator interface {
   100  	// CreateStack creates a new network stack for a network namespace.
   101  	CreateStack() (Stack, error)
   102  }