Skip to content

Commit

Permalink
netstack refactor
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 719364530
  • Loading branch information
nybidari authored and gvisor-bot committed Jan 24, 2025
1 parent 1c38b6c commit 3b3694c
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 115 deletions.
8 changes: 0 additions & 8 deletions pkg/sentry/inet/inet.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,6 @@ type Stack interface {
// Restore restarts the network stack after restore.
Restore()

// ReplaceConfig replaces the new network stack configuration to the
// loaded or saved network stack after restore.
// TODO(b/379115439): This method is a workaround to update netstack config
// during restore. It should be removed after a new method is added to
// extract the complete config from the spec and update it in the loaded
// stack during restore.
ReplaceConfig(st Stack)

// Destroy the network stack.
Destroy()

Expand Down
3 changes: 0 additions & 3 deletions pkg/sentry/inet/test_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,6 @@ func (s *TestStack) Pause() {}
// Restore implements Stack.
func (s *TestStack) Restore() {}

// ReplaceConfig implements Stack.
func (s *TestStack) ReplaceConfig(_ Stack) {}

// Resume implements Stack.
func (s *TestStack) Resume() {}

Expand Down
12 changes: 1 addition & 11 deletions pkg/sentry/kernel/kernel.go
Original file line number Diff line number Diff line change
Expand Up @@ -834,18 +834,8 @@ func (k *Kernel) LoadFrom(ctx context.Context, r, pagesMetadata io.Reader, pages
close(timeReady)
}

if saveRestoreNet {
log.Infof("netstack save restore is enabled")
s := k.rootNetworkNamespace.Stack()
if s == nil {
panic("inet.Stack cannot be nil when netstack s/r is enabled")
}
if net != nil {
s.ReplaceConfig(net)
}
if s := k.RootNetworkNamespace().Stack(); s != nil {
s.Restore()
} else if net != nil {
net.Restore()
}

if err := k.vfs.CompleteRestore(ctx, vfsOpts); err != nil {
Expand Down
3 changes: 0 additions & 3 deletions pkg/sentry/socket/hostinet/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,6 @@ func (*Stack) Pause() {}
// Restore implements inet.Stack.Restore.
func (*Stack) Restore() {}

// ReplaceConfig implements inet.Stack.ReplaceConfig.
func (s *Stack) ReplaceConfig(_ inet.Stack) {}

// Resume implements inet.Stack.Resume.
func (*Stack) Resume() {}

Expand Down
12 changes: 3 additions & 9 deletions pkg/sentry/socket/netstack/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/refs"
"gvisor.dev/gvisor/pkg/sentry/inet"
"gvisor.dev/gvisor/pkg/sentry/socket/netfilter"
"gvisor.dev/gvisor/pkg/sentry/socket/netlink/nlmsg"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
Expand Down Expand Up @@ -922,15 +923,8 @@ func (s *Stack) Pause() {

// Restore implements inet.Stack.Restore.
func (s *Stack) Restore() {
s.Stack.Restore()
}

// ReplaceConfig implements inet.Stack.ReplaceConfig.
func (s *Stack) ReplaceConfig(st inet.Stack) {
if _, ok := st.(*Stack); !ok {
panic("netstack.Stack cannot be nil when netstack s/r is enabled")
}
s.Stack.ReplaceConfig(st.(*Stack).Stack)
tables := netfilter.DefaultLinuxTables
s.Stack.Restore(tables)
}

// Resume implements inet.Stack.Resume.
Expand Down
4 changes: 4 additions & 0 deletions pkg/tcpip/stack/save_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ import (
"time"

cryptorand "gvisor.dev/gvisor/pkg/rand"
"gvisor.dev/gvisor/pkg/tcpip"
)

// afterLoad is invoked by stateify.
func (s *Stack) afterLoad(context.Context) {
s.insecureRNG = rand.New(rand.NewSource(time.Now().UnixNano()))
s.secureRNG = cryptorand.RNGFrom(cryptorand.Reader)
s.mu.Lock()
s.nics = make(map[tcpip.NICID]*nic)
s.mu.Unlock()
}
4 changes: 3 additions & 1 deletion pkg/tcpip/stack/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -1998,13 +1998,15 @@ func (s *Stack) ReplaceConfig(st *Stack) {

// Restore restarts the stack after a restore. This must be called after the
// entire system has been restored.
func (s *Stack) Restore() {
func (s *Stack) Restore(fn func(clock tcpip.Clock, rand *rand.Rand) *IPTables) {
// RestoredEndpoint.Restore() may call other methods on s, so we can't hold
// s.mu while restoring the endpoints.
s.mu.Lock()
eps := s.restoredEndpoints
s.restoredEndpoints = nil
saveRestoreEnabled := s.saveRestoreEnabled
s.tables = fn(s.clock, s.insecureRNG)
s.icmpRateLimiter = NewICMPRateLimiter(s.clock)
s.mu.Unlock()
for _, e := range eps {
e.Restore(s)
Expand Down
12 changes: 12 additions & 0 deletions runsc/boot/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ const (

// ContMgrContainerRuntimeState returns the runtime state of a container.
ContMgrContainerRuntimeState = "containerManager.ContainerRuntimeState"

// ContMgrStoreNetworkConfig stores the network configuration in the loader.
ContMgrStoreNetworkConfig = "containerManager.StoreNetworkConfig"
)

const (
Expand All @@ -131,6 +134,9 @@ const (

// DebugStacks collects sandbox stacks for debugging.
DebugStacks = "debug.Stacks"

// NetworkSetupNetwork sets up network.
NetworkSetupNetwork = "Network.SetupNetwork"
)

// Profiling related commands (see pprof.go for more details).
Expand Down Expand Up @@ -943,3 +949,9 @@ func (cm *containerManager) ContainerRuntimeState(cid *string, state *ContainerR
*state = cm.l.containerRuntimeState(*cid)
return nil
}

// StoreNetworkConfig stores the network configuration.
func (cm *containerManager) StoreNetworkConfig(netConf *NetworkConfig, _ *struct{}) error {
cm.l.netConf = netConf
return nil
}
3 changes: 3 additions & 0 deletions runsc/boot/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,9 @@ type Loader struct {
// saveRestoreNet indicates if the saved network stack should be used
// during restore.
saveRestoreNet bool

// netConf contains the network configuration.
netConf *NetworkConfig
}

// execID uniquely identifies a sentry process that is executed in a container.
Expand Down
24 changes: 24 additions & 0 deletions runsc/boot/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,3 +605,27 @@ func ipMaskToAddressMask(ipMask net.IPMask) tcpip.AddressMask {
addr := ipToAddress(net.IP(ipMask))
return tcpip.MaskFromBytes(addr.AsSlice())
}

// NetworkConfig contains network configuration.
type NetworkConfig struct {
Args *CreateLinksAndRoutesArgs
InitArgs *InitPluginStackArgs
Network config.NetworkType
}

// SetupNetwork sets up the network during start and restore.
func (n *Network) SetupNetwork(netConf *NetworkConfig, _ *struct{}) error {
switch netConf.Network {
case config.NetworkNone, config.NetworkSandbox:
if err := n.CreateLinksAndRoutes(netConf.Args, nil); err != nil {
return err
}
case config.NetworkPlugin:
if err := n.InitPluginStack(netConf.InitArgs, nil); err != nil {
return err
}
default:
return fmt.Errorf("invalid network type: %v", netConf.Network)
}
return nil
}
14 changes: 14 additions & 0 deletions runsc/boot/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,20 @@ func (r *restorer) restore(l *Loader) error {
// Release `l.mu` before calling into callbacks.
cu.Clean()

curNetwork := l.k.RootNetworkNamespace().Stack()
if eps, ok := curNetwork.(*netstack.Stack); ok {
n := &Network{
Stack: eps.Stack,
Kernel: l.k,
}
log.Infof("netconf %+v", n)
if err := n.SetupNetwork(l.netConf, nil); err != nil {
return fmt.Errorf("SetupNetwork failed with error: %v", err)
}
} else {
l.k.RootNetworkNamespace().RestoreRootStack(hostinet.NewStack())
}

// r.restoreDone() signals and waits for the sandbox to start.
if err := r.restoreDone(); err != nil {
return fmt.Errorf("restorer.restoreDone callback failed: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion runsc/config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func RegisterFlags(flagSet *flag.FlagSet) {
flagSet.Bool("TESTONLY-afs-syscall-panic", false, "TEST ONLY; do not ever use! Used for tests exercising gVisor panic reporting.")
flagSet.String("TESTONLY-autosave-image-path", "", "TEST ONLY; enable auto save for syscall tests and set path for state file.")
flagSet.Bool("TESTONLY-autosave-resume", false, "TEST ONLY; enable auto save and resume for syscall tests and set path for state file.")
flagSet.Bool("TESTONLY-save-restore-netstack", false, "TEST ONLY; enable save/restore for netstack.")
flagSet.Bool("TESTONLY-save-restore-netstack", true, "TEST ONLY; enable save/restore for netstack.")
}

// overrideAllowlist lists all flags that can be changed using OCI
Expand Down
Loading

0 comments on commit 3b3694c

Please sign in to comment.