diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index ace574b7c7..7f227592a1 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -190,6 +190,10 @@ type Stack struct { // externalNetworkingDisabled indicates whether external networking is // disabled. This means all non-loopback NICs are disabled. externalNetworkingDisabled bool + + // allowConnectedOnSave indicates whether connections should be + // allowed to remain connected during save. + allowConnectedOnSave bool } // NetworkProtocolFactory instantiates a network protocol. @@ -2548,6 +2552,20 @@ func (s *Stack) GetRemoveConf() bool { return s.removeConf } +// SetAllowConnectedOnSave sets allowConnectedOnSave in stack with the given value. +func (s *Stack) SetAllowConnectedOnSave(allowConnectedOnSave bool) { + s.mu.Lock() + defer s.mu.Unlock() + s.allowConnectedOnSave = allowConnectedOnSave +} + +// GetAllowConnectedOnSave gets the allowConnectedOnSave from stack. +func (s *Stack) GetAllowConnectedOnSave() bool { + s.mu.RLock() + defer s.mu.RUnlock() + return s.allowConnectedOnSave +} + // DisableAllNonLoopbackNICs disables all non-loopback NICs in the stack. func (s *Stack) DisableAllNonLoopbackNICs() { s.mu.Lock() diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index 3f703d52eb..67f093b9b1 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -49,7 +49,7 @@ func (e *Endpoint) beforeSave() { case epState == StateInitial || epState == StateBound: case epState.connected() || epState.handshake(): // Terminate valid connections only for restore. - if !e.route.HasSaveRestoreCapability() { + if !e.stack.GetAllowConnectedOnSave() && !e.route.HasSaveRestoreCapability() { if e.stack.GetRemoveConf() { // Terminate the endpoint when resume=false. logDisconnect() diff --git a/runsc/boot/network.go b/runsc/boot/network.go index 299830d9b7..f44b7244ed 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -186,6 +186,10 @@ type CreateLinksAndRoutesArgs struct { // PauseExternalNetworking indicates whether external networking should be // disabled initially. PauseExternalNetworking bool + + // AllowConnectedOnSave indicates whether connections should be allowed to + // remain connected during save. + AllowConnectedOnSave bool } // InitPluginStackArgs are arguments to InitPluginStack. @@ -548,6 +552,8 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct n.Stack.DisableAllNonLoopbackNICs() } + n.Stack.SetAllowConnectedOnSave(args.AllowConnectedOnSave) + return nil } diff --git a/runsc/config/config.go b/runsc/config/config.go index 0bae4a8ebe..a81bac0286 100644 --- a/runsc/config/config.go +++ b/runsc/config/config.go @@ -419,6 +419,9 @@ type Config struct { // and can be unpaused manually. PauseExternalNetworking bool `flag:"pause-external-networking"` + // AllowConnectedOnSave allows network connections to stay established on save. + AllowConnectedOnSave bool `flag:"allow-connected-on-save"` + // AllowRootfsTarAnnotation indicates whether the rootfs tar annotation // should be allowed. AllowRootfsTarAnnotation bool `flag:"allow-rootfs-tar-annotation"` diff --git a/runsc/config/flags.go b/runsc/config/flags.go index e2d8fbfb0c..b08b6cccb2 100644 --- a/runsc/config/flags.go +++ b/runsc/config/flags.go @@ -43,9 +43,9 @@ const ( flagOverlay2 = "overlay2" flagAllowFlagOverride = "allow-flag-override" flagPauseExternalNetworking = "pause-external-networking" - - defaultRootDir = "/var/run/runsc" - xdgRuntimeDirEnvVar = "XDG_RUNTIME_DIR" + flagAllowConnectedOnSave = "allow-connected-on-save" + defaultRootDir = "/var/run/runsc" + xdgRuntimeDirEnvVar = "XDG_RUNTIME_DIR" ) // RegisterFlags registers flags used to populate Config. @@ -158,6 +158,7 @@ func RegisterFlags(flagSet *flag.FlagSet) { flagSet.Bool(flagReproduceNFTables, false, "Attempt to scrape and reproduce nftable rules inside the sandbox. Overrides reproduce-nat when true.") flagSet.Bool(flagNetDisconnectOK, true, "Indicates whether open network connections and open unix domain sockets should be disconnected upon save.") flagSet.Bool(flagPauseExternalNetworking, false, "Start the sandbox with external networking disabled. Only supported when using the sandbox network type. The network can be unpaused manually after the sandbox is running.") + flagSet.Bool(flagAllowConnectedOnSave, false, "Allow network connections to stay established on save.") // Flags that control sandbox runtime behavior: accelerator related. flagSet.Bool("nvproxy", false, "EXPERIMENTAL: enable support for Nvidia GPUs") @@ -195,6 +196,7 @@ var overrideAllowlist = map[string]struct { flagOverlay2: {check: checkOverlay2}, flagOCISeccomp: {check: checkOciSeccomp}, flagPauseExternalNetworking: {}, + flagAllowConnectedOnSave: {}, } // checkOverlay2 ensures that overlay2 can only be enabled using "memory" or diff --git a/runsc/sandbox/network.go b/runsc/sandbox/network.go index ef3fea2f72..f3c03566f4 100644 --- a/runsc/sandbox/network.go +++ b/runsc/sandbox/network.go @@ -165,6 +165,7 @@ func collectLinksAndRoutes(conf *config.Config, disableIPv6 bool) (boot.CreateLi args := boot.CreateLinksAndRoutesArgs{ PauseExternalNetworking: conf.PauseExternalNetworking, + AllowConnectedOnSave: conf.AllowConnectedOnSave, } for _, iface := range ifaces {