diff --git a/pkg/sentry/socket/netfilter/targets.go b/pkg/sentry/socket/netfilter/targets.go index f8a892ba3..41a93caf4 100644 --- a/pkg/sentry/socket/netfilter/targets.go +++ b/pkg/sentry/socket/netfilter/targets.go @@ -100,6 +100,7 @@ func init() { // The stack package provides some basic, useful targets for us. The following // types wrap them for compatibility with the extension system. +// +stateify savable type acceptTarget struct { stack.AcceptTarget } @@ -110,6 +111,7 @@ func (at *acceptTarget) id() targetID { } } +// +stateify savable type dropTarget struct { stack.DropTarget } @@ -120,6 +122,7 @@ func (dt *dropTarget) id() targetID { } } +// +stateify savable type errorTarget struct { stack.ErrorTarget } @@ -131,6 +134,7 @@ func (et *errorTarget) id() targetID { } } +// +stateify savable type userChainTarget struct { stack.UserChainTarget } @@ -142,6 +146,7 @@ func (uc *userChainTarget) id() targetID { } } +// +stateify savable type returnTarget struct { stack.ReturnTarget } @@ -152,6 +157,7 @@ func (rt *returnTarget) id() targetID { } } +// +stateify savable type redirectTarget struct { stack.RedirectTarget @@ -167,6 +173,7 @@ func (rt *redirectTarget) id() targetID { } } +// +stateify savable type standardTargetMaker struct { NetworkProtocol tcpip.NetworkProtocolNumber } @@ -224,6 +231,7 @@ func (*standardTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) ( }, nil } +// +stateify savable type errorTargetMaker struct { NetworkProtocol tcpip.NetworkProtocolNumber } @@ -287,6 +295,7 @@ func (*errorTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (tar } } +// +stateify savable type redirectTargetMaker struct { NetworkProtocol tcpip.NetworkProtocolNumber } @@ -364,6 +373,7 @@ func (*redirectTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) ( return &target, nil } +// +stateify savable type nfNATTargetMaker struct { NetworkProtocol tcpip.NetworkProtocolNumber } @@ -478,6 +488,8 @@ func parseTarget(filter stack.IPHeaderFilter, optVal []byte, ipv6 bool) (stack.T } // JumpTarget implements stack.Target. +// +// +stateify savable type JumpTarget struct { // Offset is the byte offset of the rule to jump to. It is used for // marshaling and unmarshaling. diff --git a/pkg/tcpip/faketime/faketime.go b/pkg/tcpip/faketime/faketime.go index 81274a4a8..2b21b3533 100644 --- a/pkg/tcpip/faketime/faketime.go +++ b/pkg/tcpip/faketime/faketime.go @@ -25,6 +25,8 @@ import ( ) // NullClock implements a clock that never advances. +// +// +stateify savable type NullClock struct{} var _ tcpip.Clock = (*NullClock)(nil) @@ -40,6 +42,8 @@ func (*NullClock) NowMonotonic() tcpip.MonotonicTime { } // nullTimer implements a timer that never fires. +// +// +stateify savable type nullTimer struct{} var _ tcpip.Timer = (*nullTimer)(nil) @@ -92,26 +96,31 @@ func (n *notificationChannels) wait() { } } +// +stateify savable +type manualClockMutex struct { + sync.RWMutex `state:"nosave"` + + // now is the current (fake) time of the clock. + now time.Time + + // times is min-heap of times. + times timeHeap + + // timers holds the timers scheduled for each time. + timers map[time.Time]map[*manualTimer]struct{} +} + // ManualClock implements tcpip.Clock and only advances manually with Advance // method. +// +// +stateify savable type ManualClock struct { // runningTimers tracks the completion of timer callbacks that began running // immediately upon their scheduling. It is used to ensure the proper ordering // of timer callback dispatch. runningTimers notificationChannels - mu struct { - sync.RWMutex - - // now is the current (fake) time of the clock. - now time.Time - - // times is min-heap of times. - times timeHeap - - // timers holds the timers scheduled for each time. - timers map[time.Time]map[*manualTimer]struct{} - } + mu manualClockMutex } // NewManualClock creates a new ManualClock instance. @@ -325,18 +334,23 @@ func (mc *ManualClock) stopTimer(mt *manualTimer) bool { return true } +// +stateify savable +type manualTimerMu struct { + sync.Mutex `state:"nosave"` + + // firesAt is the time when the timer will fire. + // + // Zero only when the timer is not active. + firesAt time.Time +} + +// +stateify savable type manualTimer struct { clock *ManualClock - f func() + // TODO(b/341946753): Restore when netstack is savable. + f func() `state:"nosave"` - mu struct { - sync.Mutex - - // firesAt is the time when the timer will fire. - // - // Zero only when the timer is not active. - firesAt time.Time - } + mu manualTimerMu } var _ tcpip.Timer = (*manualTimer)(nil) diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 3ea016cbb..d1d87b6df 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -134,13 +134,15 @@ var _ stack.GSOEndpoint = (*Endpoint)(nil) // Endpoint is link layer endpoint that stores outbound packets in a channel // and allows injection of inbound packets. +// +// +stateify savable type Endpoint struct { mtu uint32 linkAddr tcpip.LinkAddress LinkEPCapabilities stack.LinkEndpointCapabilities SupportedGSOKind stack.SupportedGSO - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checklocks:mu dispatcher stack.NetworkDispatcher diff --git a/pkg/tcpip/link/ethernet/ethernet.go b/pkg/tcpip/link/ethernet/ethernet.go index fd9fbfaca..4e54e0e8e 100644 --- a/pkg/tcpip/link/ethernet/ethernet.go +++ b/pkg/tcpip/link/ethernet/ethernet.go @@ -38,6 +38,8 @@ func New(ep stack.LinkEndpoint) *Endpoint { // It adds an ethernet header to packets before sending them out through its // inner link endpoint and consumes an ethernet header before sending the // packet to the stack. +// +// +stateify savable type Endpoint struct { nested.Endpoint } diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index bff2d0475..91ac25d52 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -107,11 +107,13 @@ func (p PacketDispatchMode) String() string { var _ stack.LinkEndpoint = (*endpoint)(nil) var _ stack.GSOEndpoint = (*endpoint)(nil) +// +stateify savable type fdInfo struct { fd int isSocket bool } +// +stateify savable type endpoint struct { // fds is the set of file descriptors each identifying one inbound/outbound // channel. The endpoint will dispatch from all inbound channels as well as @@ -137,7 +139,7 @@ type endpoint struct { inboundDispatchers []linkDispatcher - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checklocks:mu dispatcher stack.NetworkDispatcher @@ -171,6 +173,8 @@ type endpoint struct { } // Options specify the details about the fd-based endpoint to be created. +// +// +stateify savable type Options struct { // FDs is a set of FDs used to read/write packets. FDs []int @@ -800,10 +804,12 @@ func (e *endpoint) ARPHardwareType() header.ARPHardwareType { // InjectableEndpoint is an injectable fd-based endpoint. The endpoint writes // to the FD, but does not read from it. All reads come from injected packets. +// +// +satetify savable type InjectableEndpoint struct { endpoint - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checklocks:mu dispatcher stack.NetworkDispatcher } diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index f9f74203b..8a263067a 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -28,8 +28,9 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/stack" ) +// +stateify savable type endpoint struct { - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checklocks:mu dispatcher stack.NetworkDispatcher } diff --git a/pkg/tcpip/link/muxed/injectable.go b/pkg/tcpip/link/muxed/injectable.go index 51c675e70..9055e85da 100644 --- a/pkg/tcpip/link/muxed/injectable.go +++ b/pkg/tcpip/link/muxed/injectable.go @@ -28,10 +28,12 @@ import ( // trivial routing rules that determine which InjectableEndpoint a given packet // will be written to. Note that HandleLocal works differently for this // endpoint (see WritePacket). +// +// +stateify savable type InjectableEndpoint struct { routes map[tcpip.Address]stack.InjectableLinkEndpoint - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checklocks:mu dispatcher stack.NetworkDispatcher } diff --git a/pkg/tcpip/link/nested/nested.go b/pkg/tcpip/link/nested/nested.go index 0f04483ad..22c3fa8f9 100644 --- a/pkg/tcpip/link/nested/nested.go +++ b/pkg/tcpip/link/nested/nested.go @@ -28,12 +28,14 @@ import ( // concurrency guards. // // See the tests in this package for example usage. +// +// +stateify savable type Endpoint struct { child stack.LinkEndpoint embedder stack.NetworkDispatcher // mu protects dispatcher. - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` dispatcher stack.NetworkDispatcher } diff --git a/pkg/tcpip/link/packetsocket/packetsocket.go b/pkg/tcpip/link/packetsocket/packetsocket.go index 16284360a..803462185 100644 --- a/pkg/tcpip/link/packetsocket/packetsocket.go +++ b/pkg/tcpip/link/packetsocket/packetsocket.go @@ -25,6 +25,7 @@ import ( var _ stack.NetworkDispatcher = (*endpoint)(nil) var _ stack.LinkEndpoint = (*endpoint)(nil) +// +stateify savable type endpoint struct { nested.Endpoint } diff --git a/pkg/tcpip/link/pipe/pipe.go b/pkg/tcpip/link/pipe/pipe.go index bc0f58725..dddbd3eab 100644 --- a/pkg/tcpip/link/pipe/pipe.go +++ b/pkg/tcpip/link/pipe/pipe.go @@ -42,12 +42,14 @@ func New(linkAddr1, linkAddr2 tcpip.LinkAddress, mtu uint32) (*Endpoint, *Endpoi } // Endpoint is one end of a pipe. +// +// +stateify savable type Endpoint struct { linked *Endpoint linkAddr tcpip.LinkAddress mtu uint32 - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checklocks:mu dispatcher stack.NetworkDispatcher } diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 2cf1f82c3..6f5c44b07 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -41,6 +41,8 @@ import ( // QueueConfig holds all the file descriptors needed to describe a tx or rx // queue over shared memory. It is used when creating new shared memory // endpoints to describe tx and rx queues. +// +// +stateify savable type QueueConfig struct { // DataFD is a file descriptor for the file that contains the data to // be transmitted via this queue. Descriptors contain offsets within @@ -92,6 +94,8 @@ func QueueConfigFromFDs(fds []int) (QueueConfig, error) { } // Options specify the details about the sharedmem endpoint to be created. +// +// +stateify savable type Options struct { // MTU is the mtu to use for this endpoint. MTU uint32 @@ -142,6 +146,7 @@ type Options struct { var _ stack.LinkEndpoint = (*endpoint)(nil) var _ stack.GSOEndpoint = (*endpoint)(nil) +// +stateify savable type endpoint struct { // mtu (maximum transmission unit) is the maximum size of a packet. // mtu is immutable. @@ -187,10 +192,11 @@ type endpoint struct { // onClosed is a function to be called when the FD's peer (if any) closes // its end of the communication pipe. - onClosed func(tcpip.Error) + // TODO(b/341946753): Restore when netstack is savable. + onClosed func(tcpip.Error) `state:"nosave"` // mu protects the following fields. - mu sync.Mutex + mu sync.Mutex `state:"nosave"` // tx is the transmit queue. // +checklocks:mu diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index fcf22340d..9fcff324a 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -44,6 +44,7 @@ var LogPackets atomicbitops.Uint32 = atomicbitops.FromUint32(1) // sniffer was created for this flag to have effect. var LogPacketsToPCAP atomicbitops.Uint32 = atomicbitops.FromUint32(1) +// +stateify savable type endpoint struct { nested.Endpoint writer io.Writer diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index 4447106dc..dee19708a 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -32,10 +32,12 @@ var _ stack.NetworkDispatcher = (*Endpoint)(nil) var _ stack.LinkEndpoint = (*Endpoint)(nil) // Endpoint is a waitable link-layer endpoint. +// +// +stateify savable type Endpoint struct { dispatchGate sync.Gate - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checklocks:mu dispatcher stack.NetworkDispatcher diff --git a/pkg/tcpip/link/xdp/endpoint.go b/pkg/tcpip/link/xdp/endpoint.go index 8a7891de5..834543188 100644 --- a/pkg/tcpip/link/xdp/endpoint.go +++ b/pkg/tcpip/link/xdp/endpoint.go @@ -40,6 +40,7 @@ const MTU = 1500 var _ stack.LinkEndpoint = (*endpoint)(nil) +// +stateify savable type endpoint struct { // fd is the underlying AF_XDP socket. fd int @@ -52,14 +53,15 @@ type endpoint struct { // closed is a function to be called when the FD's peer (if any) closes // its end of the communication pipe. - closed func(tcpip.Error) + // TODO(b/341946753): Restore when netstack is savable. + closed func(tcpip.Error) `state:"nosave"` - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checkloks:mu networkDispatcher stack.NetworkDispatcher // wg keeps track of running goroutines. - wg sync.WaitGroup + wg sync.WaitGroup `state:"nosave"` // control is used to control the AF_XDP socket. control *xdp.ControlBlock diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index d2ab16209..e05f18899 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -45,6 +45,7 @@ var _ ip.DADProtocol = (*endpoint)(nil) // the link-layer is via stack.NetworkEndpoint.HandlePacket. var _ stack.NetworkEndpoint = (*endpoint)(nil) +// +stateify savable type endpoint struct { protocol *protocol @@ -55,7 +56,7 @@ type endpoint struct { stats sharedStats // mu protects annotated fields below. - mu sync.Mutex + mu sync.Mutex `state:"nosave"` // +checklocks:mu dad ip.DAD @@ -257,6 +258,7 @@ func (e *endpoint) Stats() stack.NetworkEndpointStats { var _ stack.NetworkProtocol = (*protocol)(nil) +// +stateify savable type protocol struct { stack *stack.Stack options Options @@ -388,6 +390,8 @@ func (*protocol) Parse(pkt *stack.PacketBuffer) (proto tcpip.TransportProtocolNu } // Options holds options to configure a protocol. +// +// +stateify savable type Options struct { // DADConfigs is the default DAD configurations used by ARP endpoints. DADConfigs stack.DADConfigurations diff --git a/pkg/tcpip/network/arp/stats.go b/pkg/tcpip/network/arp/stats.go index 6d7194c6c..f49742178 100644 --- a/pkg/tcpip/network/arp/stats.go +++ b/pkg/tcpip/network/arp/stats.go @@ -22,6 +22,8 @@ import ( var _ stack.NetworkEndpointStats = (*Stats)(nil) // Stats holds statistics related to ARP. +// +// +stateify savable type Stats struct { // ARP holds ARP statistics. ARP tcpip.ARPStats @@ -30,6 +32,7 @@ type Stats struct { // IsNetworkEndpointStats implements stack.NetworkEndpointStats. func (*Stats) IsNetworkEndpointStats() {} +// +stateify savable type sharedStats struct { localStats Stats arp multiCounterARPStats @@ -37,6 +40,7 @@ type sharedStats struct { // LINT.IfChange(multiCounterARPStats) +// +stateify savable type multiCounterARPStats struct { packetsReceived tcpip.MultiCounterStat disabledPacketsReceived tcpip.MultiCounterStat diff --git a/pkg/tcpip/network/internal/fragmentation/fragmentation.go b/pkg/tcpip/network/internal/fragmentation/fragmentation.go index b7d3c6741..8697d4e4c 100644 --- a/pkg/tcpip/network/internal/fragmentation/fragmentation.go +++ b/pkg/tcpip/network/internal/fragmentation/fragmentation.go @@ -60,6 +60,8 @@ var ( ) // FragmentID is the identifier for a fragment. +// +// +stateify savable type FragmentID struct { // Source is the source address of the fragment. Source tcpip.Address @@ -78,8 +80,10 @@ type FragmentID struct { // Fragmentation is the main structure that other modules // of the stack should use to implement IP Fragmentation. +// +// +stateify savable type Fragmentation struct { - mu sync.Mutex + mu sync.Mutex `state:"nosave"` highLimit int lowLimit int reassemblers map[FragmentID]*reassembler diff --git a/pkg/tcpip/network/internal/fragmentation/reassembler.go b/pkg/tcpip/network/internal/fragmentation/reassembler.go index 59fea4bbe..9aaad7632 100644 --- a/pkg/tcpip/network/internal/fragmentation/reassembler.go +++ b/pkg/tcpip/network/internal/fragmentation/reassembler.go @@ -23,6 +23,7 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/stack" ) +// +stateify savable type hole struct { first uint16 last uint16 @@ -33,12 +34,13 @@ type hole struct { pkt *stack.PacketBuffer } +// +stateify savable type reassembler struct { reassemblerEntry id FragmentID memSize int proto uint8 - mu sync.Mutex + mu sync.Mutex `state:"nosave"` holes []hole filled int done bool diff --git a/pkg/tcpip/network/internal/ip/duplicate_address_detection.go b/pkg/tcpip/network/internal/ip/duplicate_address_detection.go index 5123b7d6a..66661f3c9 100644 --- a/pkg/tcpip/network/internal/ip/duplicate_address_detection.go +++ b/pkg/tcpip/network/internal/ip/duplicate_address_detection.go @@ -33,6 +33,7 @@ const ( extended ) +// +stateify savable type dadState struct { nonce []byte extendRequest extendRequest @@ -50,9 +51,12 @@ type DADProtocol interface { } // DADOptions holds options for DAD. +// +// +stateify savable type DADOptions struct { - Clock tcpip.Clock - SecureRNG io.Reader + Clock tcpip.Clock + // TODO(b/341946753): Restore when netstack is savable. + SecureRNG io.Reader `state:"nosave"` NonceSize uint8 ExtendDADTransmits uint8 Protocol DADProtocol @@ -60,11 +64,13 @@ type DADOptions struct { } // DAD performs duplicate address detection for addresses. +// +// +stateify savable type DAD struct { opts DADOptions configs stack.DADConfigurations - protocolMU sync.Locker + protocolMU sync.Locker `state:"nosave"` addresses map[tcpip.Address]dadState } diff --git a/pkg/tcpip/network/internal/ip/generic_multicast_protocol.go b/pkg/tcpip/network/internal/ip/generic_multicast_protocol.go index 54c38b83b..3e7ca67e5 100644 --- a/pkg/tcpip/network/internal/ip/generic_multicast_protocol.go +++ b/pkg/tcpip/network/internal/ip/generic_multicast_protocol.go @@ -105,6 +105,8 @@ const ( // multicastGroupState holds the Generic Multicast Protocol state for a // multicast group. +// +// +stateify savable type multicastGroupState struct { // joins is the number of times the group has been joined. joins uint64 @@ -130,7 +132,8 @@ type multicastGroupState struct { // delyedReportJobFiresAt is the time when the delayed report job will fire. // // A zero value indicates that the job is not scheduled. - delayedReportJobFiresAt time.Time + // TODO(b/341946753): Restore when netstack is savable. + delayedReportJobFiresAt time.Time `state:"nosave"` // queriedIncludeSources holds sources that were queried for. // @@ -155,9 +158,12 @@ func (m *multicastGroupState) clearQueriedIncludeSources() { // GenericMulticastProtocolOptions holds options for the generic multicast // protocol. +// +// +stateify savable type GenericMulticastProtocolOptions struct { // Rand is the source of random numbers. - Rand *rand.Rand + // TODO(b/341946753): Restore when netstack is savable. + Rand *rand.Rand `state:"nosave"` // Clock is the clock used to create timers. Clock tcpip.Clock @@ -267,9 +273,11 @@ const ( // // GenericMulticastProtocolState.MakeAllNonMemberLocked MUST be called when the // multicast group protocol is disabled so that leave messages may be sent. +// +// +stateify savable type GenericMulticastProtocolState struct { // Do not allow overwriting this state. - _ sync.NoCopy + _ sync.NoCopy `state:"nosave"` opts GenericMulticastProtocolOptions @@ -277,7 +285,7 @@ type GenericMulticastProtocolState struct { memberships map[tcpip.Address]multicastGroupState // protocolMU is the mutex used to protect the protocol. - protocolMU *sync.RWMutex + protocolMU *sync.RWMutex `state:"nosave"` // V2 state. robustnessVariable uint8 @@ -285,8 +293,9 @@ type GenericMulticastProtocolState struct { mode protocolMode modeTimer tcpip.Timer - generalQueryV2Timer tcpip.Timer - generalQueryV2TimerFiresAt time.Time + generalQueryV2Timer tcpip.Timer + // TODO(b/341946753): Restore when netstack is savable. + generalQueryV2TimerFiresAt time.Time `state:"nosave"` stateChangedReportV2Timer tcpip.Timer stateChangedReportV2TimerSet bool diff --git a/pkg/tcpip/network/internal/ip/stats.go b/pkg/tcpip/network/internal/ip/stats.go index 4e8023662..85990f5da 100644 --- a/pkg/tcpip/network/internal/ip/stats.go +++ b/pkg/tcpip/network/internal/ip/stats.go @@ -20,6 +20,8 @@ import "gvisor.dev/gvisor/pkg/tcpip" // MultiCounterIPForwardingStats holds IP forwarding statistics. Each counter // may have several versions. +// +// +stateify savable type MultiCounterIPForwardingStats struct { // Unrouteable is the number of IP packets received which were dropped // because the netstack could not construct a route to their @@ -101,6 +103,8 @@ func (m *MultiCounterIPForwardingStats) Init(a, b *tcpip.IPForwardingStats) { // MultiCounterIPStats holds IP statistics, each counter may have several // versions. +// +// +stateify savable type MultiCounterIPStats struct { // PacketsReceived is the number of IP packets received from the link // layer. diff --git a/pkg/tcpip/network/internal/multicast/route_table.go b/pkg/tcpip/network/internal/multicast/route_table.go index 41227e6ed..d74aa31fd 100644 --- a/pkg/tcpip/network/internal/multicast/route_table.go +++ b/pkg/tcpip/network/internal/multicast/route_table.go @@ -26,6 +26,8 @@ import ( ) // RouteTable represents a multicast routing table. +// +// +stateify savable type RouteTable struct { // Internally, installed and pending routes are stored and locked separately // A couple of reasons for structuring the table this way: @@ -43,13 +45,13 @@ type RouteTable struct { // lock. This ensures that installed routes can continue to be read even when // the pending routes are write locked. - installedMu sync.RWMutex + installedMu sync.RWMutex `state:"nosave"` // Maintaining pointers ensures that the installed routes are exclusively // locked only when a route is being installed. // +checklocks:installedMu installedRoutes map[stack.UnicastSourceAndMulticastDestination]*InstalledRoute - pendingMu sync.RWMutex + pendingMu sync.RWMutex `state:"nosave"` // +checklocks:pendingMu pendingRoutes map[stack.UnicastSourceAndMulticastDestination]PendingRoute // cleanupPendingRoutesTimer is a timer that triggers a routine to remove @@ -79,10 +81,12 @@ var ( // // If a route is in the installed state, then it may be used to forward // multicast packets. +// +// +stateify savable type InstalledRoute struct { stack.MulticastRoute - lastUsedTimestampMu sync.RWMutex + lastUsedTimestampMu sync.RWMutex `state:"nosave"` // +checklocks:lastUsedTimestampMu lastUsedTimestamp tcpip.MonotonicTime } @@ -115,6 +119,8 @@ func (r *InstalledRoute) SetLastUsedTimestamp(monotonicTime tcpip.MonotonicTime) // A route is in the pending state if an installed route does not yet exist // for the entry. For such routes, packets are added to an expiring queue until // a route is installed. +// +// +stateify savable type PendingRoute struct { packets []*stack.PacketBuffer @@ -159,6 +165,8 @@ const ( ) // Config represents the options for configuring a RouteTable. +// +// +stateify savable type Config struct { // MaxPendingQueueSize corresponds to the maximum number of queued packets // for a pending route. diff --git a/pkg/tcpip/network/ipv4/igmp.go b/pkg/tcpip/network/ipv4/igmp.go index afbe4d386..b7a3ce290 100644 --- a/pkg/tcpip/network/ipv4/igmp.go +++ b/pkg/tcpip/network/ipv4/igmp.go @@ -90,6 +90,8 @@ type IGMPEndpoint interface { } // IGMPOptions holds options for IGMP. +// +// +stateify savable type IGMPOptions struct { // Enabled indicates whether IGMP will be performed. // @@ -107,6 +109,8 @@ var _ ip.MulticastGroupProtocol = (*igmpState)(nil) // igmpState is the per-interface IGMP state. // // igmpState.init() MUST be called after creating an IGMP state. +// +// +stateify savable type igmpState struct { // The IPv4 endpoint this igmpState is for. ep *endpoint diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index 37796905e..8b4e24ac3 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -79,6 +79,7 @@ var _ stack.AddressableEndpoint = (*endpoint)(nil) var _ stack.NetworkEndpoint = (*endpoint)(nil) var _ IGMPEndpoint = (*endpoint)(nil) +// +stateify savable type endpoint struct { nic stack.NetworkInterface dispatcher stack.TransportDispatcher @@ -101,7 +102,7 @@ type endpoint struct { multicastForwarding atomicbitops.Uint32 // mu protects below. - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checklocks:mu addressableEndpointState stack.AddressableEndpointState @@ -1505,11 +1506,12 @@ var _ stack.MulticastForwardingNetworkProtocol = (*protocol)(nil) var _ stack.RejectIPv4WithHandler = (*protocol)(nil) var _ fragmentation.TimeoutHandler = (*protocol)(nil) +// +stateify savable type protocol struct { stack *stack.Stack // mu protects annotated fields below. - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // eps is keyed by NICID to allow protocol methods to retrieve an endpoint // when handling a packet, by looking at which NIC handled the packet. @@ -1912,6 +1914,8 @@ func hashRoute(srcAddr, dstAddr tcpip.Address, protocol tcpip.TransportProtocolN } // Options holds options to configure a new protocol. +// +// +stateify savable type Options struct { // IGMP holds options for IGMP. IGMP IGMPOptions diff --git a/pkg/tcpip/network/ipv4/stats.go b/pkg/tcpip/network/ipv4/stats.go index 9ebef99e7..5b59ff5c6 100644 --- a/pkg/tcpip/network/ipv4/stats.go +++ b/pkg/tcpip/network/ipv4/stats.go @@ -23,6 +23,8 @@ import ( var _ stack.IPNetworkEndpointStats = (*Stats)(nil) // Stats holds statistics related to the IPv4 protocol family. +// +// +stateify savable type Stats struct { // IP holds IPv4 statistics. IP tcpip.IPStats @@ -42,6 +44,7 @@ func (s *Stats) IPStats() *tcpip.IPStats { return &s.IP } +// +stateify savable type sharedStats struct { localStats Stats ip ip.MultiCounterIPStats @@ -51,6 +54,7 @@ type sharedStats struct { // LINT.IfChange(multiCounterICMPv4PacketStats) +// +stateify savable type multiCounterICMPv4PacketStats struct { echoRequest tcpip.MultiCounterStat echoReply tcpip.MultiCounterStat @@ -83,6 +87,7 @@ func (m *multiCounterICMPv4PacketStats) init(a, b *tcpip.ICMPv4PacketStats) { // LINT.IfChange(multiCounterICMPv4SentPacketStats) +// +stateify savable type multiCounterICMPv4SentPacketStats struct { multiCounterICMPv4PacketStats dropped tcpip.MultiCounterStat @@ -99,6 +104,7 @@ func (m *multiCounterICMPv4SentPacketStats) init(a, b *tcpip.ICMPv4SentPacketSta // LINT.IfChange(multiCounterICMPv4ReceivedPacketStats) +// +stateify savable type multiCounterICMPv4ReceivedPacketStats struct { multiCounterICMPv4PacketStats invalid tcpip.MultiCounterStat @@ -113,6 +119,7 @@ func (m *multiCounterICMPv4ReceivedPacketStats) init(a, b *tcpip.ICMPv4ReceivedP // LINT.IfChange(multiCounterICMPv4Stats) +// +stateify savable type multiCounterICMPv4Stats struct { packetsSent multiCounterICMPv4SentPacketStats packetsReceived multiCounterICMPv4ReceivedPacketStats @@ -127,6 +134,7 @@ func (m *multiCounterICMPv4Stats) init(a, b *tcpip.ICMPv4Stats) { // LINT.IfChange(multiCounterIGMPPacketStats) +// +stateify savable type multiCounterIGMPPacketStats struct { membershipQuery tcpip.MultiCounterStat v1MembershipReport tcpip.MultiCounterStat @@ -147,6 +155,7 @@ func (m *multiCounterIGMPPacketStats) init(a, b *tcpip.IGMPPacketStats) { // LINT.IfChange(multiCounterIGMPSentPacketStats) +// +stateify savable type multiCounterIGMPSentPacketStats struct { multiCounterIGMPPacketStats dropped tcpip.MultiCounterStat @@ -161,6 +170,7 @@ func (m *multiCounterIGMPSentPacketStats) init(a, b *tcpip.IGMPSentPacketStats) // LINT.IfChange(multiCounterIGMPReceivedPacketStats) +// +stateify savable type multiCounterIGMPReceivedPacketStats struct { multiCounterIGMPPacketStats invalid tcpip.MultiCounterStat @@ -179,6 +189,7 @@ func (m *multiCounterIGMPReceivedPacketStats) init(a, b *tcpip.IGMPReceivedPacke // LINT.IfChange(multiCounterIGMPStats) +// +stateify savable type multiCounterIGMPStats struct { packetsSent multiCounterIGMPSentPacketStats packetsReceived multiCounterIGMPReceivedPacketStats diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index a846ca430..af20f6db5 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -180,6 +180,28 @@ var _ stack.NDPEndpoint = (*endpoint)(nil) var _ MLDEndpoint = (*endpoint)(nil) var _ NDPEndpoint = (*endpoint)(nil) +// +stateify savable +type endpointMu struct { + sync.RWMutex `state:"nosave"` + + addressableEndpointState stack.AddressableEndpointState + ndp ndpState + mld mldState +} + +// +stateify savable +type dadMu struct { + sync.Mutex `state:"nosave"` + + dad ip.DAD +} + +// +stateify savable +type endpointDAD struct { + mu dadMu +} + +// +stateify savable type endpoint struct { nic stack.NetworkInterface dispatcher stack.TransportDispatcher @@ -201,13 +223,7 @@ type endpoint struct { // forwarding. Currently, setting this value to true is a no-op. multicastForwarding atomicbitops.Uint32 - mu struct { - sync.RWMutex - - addressableEndpointState stack.AddressableEndpointState - ndp ndpState - mld mldState - } + mu endpointMu // dad is used to check if an arbitrary address is already assigned to some // neighbor. @@ -218,13 +234,7 @@ type endpoint struct { // not be called with the actual DAD result. // // LOCK ORDERING: mu > dad.mu. - dad struct { - mu struct { - sync.Mutex - - dad ip.DAD - } - } + dad endpointDAD } // NICNameFromID is a function that returns a stable name for the specified NIC, @@ -238,12 +248,14 @@ type NICNameFromID func(tcpip.NICID, string) string // OpaqueInterfaceIdentifierOptions holds the options related to the generation // of opaque interface identifiers (IIDs) as defined by RFC 7217. +// +// +stateify savable type OpaqueInterfaceIdentifierOptions struct { // NICNameFromID is a function that returns a stable name for a specified NIC, // even if the NIC ID changes over time. // // Must be specified to generate the opaque IID. - NICNameFromID NICNameFromID + NICNameFromID NICNameFromID `state:"nosave"` // SecretKey is a pseudo-random number used as the secret key when generating // opaque IIDs as defined by RFC 7217. The key SHOULD be at least @@ -2264,25 +2276,29 @@ var _ stack.MulticastForwardingNetworkProtocol = (*protocol)(nil) var _ stack.RejectIPv6WithHandler = (*protocol)(nil) var _ fragmentation.TimeoutHandler = (*protocol)(nil) +// +stateify savable +type protocolMu struct { + sync.RWMutex `state:"nosave"` + + // eps is keyed by NICID to allow protocol methods to retrieve an endpoint + // when handling a packet, by looking at which NIC handled the packet. + eps map[tcpip.NICID]*endpoint + + // ICMP types for which the stack's global rate limiting must apply. + icmpRateLimitedTypes map[header.ICMPv6Type]struct{} + + // multicastForwardingDisp is the multicast forwarding event dispatcher that + // an integrator can provide to receive multicast forwarding events. Note + // that multicast packets will only be forwarded if this is non-nil. + multicastForwardingDisp stack.MulticastForwardingEventDispatcher +} + +// +stateify savable type protocol struct { stack *stack.Stack options Options - mu struct { - sync.RWMutex - - // eps is keyed by NICID to allow protocol methods to retrieve an endpoint - // when handling a packet, by looking at which NIC handled the packet. - eps map[tcpip.NICID]*endpoint - - // ICMP types for which the stack's global rate limiting must apply. - icmpRateLimitedTypes map[header.ICMPv6Type]struct{} - - // multicastForwardingDisp is the multicast forwarding event dispatcher that - // an integrator can provide to receive multicast forwarding events. Note - // that multicast packets will only be forwarded if this is non-nil. - multicastForwardingDisp stack.MulticastForwardingEventDispatcher - } + mu protocolMu // defaultTTL is the current default TTL for the protocol. Only the // uint8 portion of it is meaningful. @@ -2687,6 +2703,8 @@ func calculateNetworkMTU(linkMTU, networkHeadersLen uint32) (uint32, tcpip.Error } // Options holds options to configure a new protocol. +// +// +stateify savable type Options struct { // NDPConfigs is the default NDP configurations used by interfaces. NDPConfigs NDPConfigurations diff --git a/pkg/tcpip/network/ipv6/mld.go b/pkg/tcpip/network/ipv6/mld.go index 7feb52239..56dba24b7 100644 --- a/pkg/tcpip/network/ipv6/mld.go +++ b/pkg/tcpip/network/ipv6/mld.go @@ -57,6 +57,8 @@ type MLDEndpoint interface { } // MLDOptions holds options for MLD. +// +// +stateify savable type MLDOptions struct { // Enabled indicates whether MLD will be performed. // @@ -74,6 +76,8 @@ var _ ip.MulticastGroupProtocol = (*mldState)(nil) // mldState is the per-interface MLD state. // // mldState.init MUST be called to initialize the MLD state. +// +// +stateify savable type mldState struct { // The IPv6 endpoint this mldState is for. ep *endpoint diff --git a/pkg/tcpip/network/ipv6/ndp.go b/pkg/tcpip/network/ipv6/ndp.go index b44879bc7..41f497f67 100644 --- a/pkg/tcpip/network/ipv6/ndp.go +++ b/pkg/tcpip/network/ipv6/ndp.go @@ -341,6 +341,8 @@ func (c HandleRAsConfiguration) enabled(forwarding bool) bool { } // NDPConfigurations is the NDP configurations for the netstack. +// +// +stateify savable type NDPConfigurations struct { // The number of Router Solicitation messages to send when the IPv6 endpoint // becomes enabled. @@ -461,6 +463,7 @@ func (c *NDPConfigurations) validate() { } } +// +stateify savable type timer struct { // done indicates to the timer that the timer was stopped. done *bool @@ -468,15 +471,18 @@ type timer struct { timer tcpip.Timer } +// +stateify savable type offLinkRoute struct { dest tcpip.Subnet router tcpip.Address } // ndpState is the per-Interface NDP state. +// +// +stateify savable type ndpState struct { // Do not allow overwriting this state. - _ sync.NoCopy + _ sync.NoCopy `state:"nosave"` // The IPv6 endpoint this ndpState is for. ep *endpoint @@ -518,6 +524,8 @@ type ndpState struct { // offLinkRouteState holds data associated with an off-link route discovered by // a Router Advertisement (RA). +// +// +stateify savable type offLinkRouteState struct { prf header.NDPRoutePreference @@ -530,6 +538,8 @@ type offLinkRouteState struct { // onLinkPrefixState holds data associated with an on-link prefix discovered by // a Router Advertisement's Prefix Information option (PI) when the NDP // configurations was configured to do so. +// +// +stateify savable type onLinkPrefixState struct { // Job to invalidate the on-link prefix. // @@ -538,6 +548,8 @@ type onLinkPrefixState struct { } // tempSLAACAddrState holds state associated with a temporary SLAAC address. +// +// +stateify savable type tempSLAACAddrState struct { // Job to deprecate the temporary SLAAC address. // @@ -565,7 +577,22 @@ type tempSLAACAddrState struct { regenerated bool } +// +stateify savable +type stableAddrState struct { + // The address's endpoint. + // + // May only be nil when the address is being (re-)generated. Otherwise, + // must not be nil as all SLAAC prefixes must have a stable address. + addressEndpoint stack.AddressEndpoint + + // The number of times an address has been generated locally where the IPv6 + // endpoint already had the generated address. + localGenerationFailures uint8 +} + // slaacPrefixState holds state associated with a SLAAC prefix. +// +// +stateify savable type slaacPrefixState struct { // Job to deprecate the prefix. // @@ -584,17 +611,7 @@ type slaacPrefixState struct { preferredUntil *tcpip.MonotonicTime // State associated with the stable address generated for the prefix. - stableAddr struct { - // The address's endpoint. - // - // May only be nil when the address is being (re-)generated. Otherwise, - // must not be nil as all SLAAC prefixes must have a stable address. - addressEndpoint stack.AddressEndpoint - - // The number of times an address has been generated locally where the IPv6 - // endpoint already had the generated address. - localGenerationFailures uint8 - } + stableAddr stableAddrState // The temporary (short-lived) addresses generated for the SLAAC prefix. tempAddrs map[tcpip.Address]tempSLAACAddrState diff --git a/pkg/tcpip/network/ipv6/stats.go b/pkg/tcpip/network/ipv6/stats.go index 8a7ae91a3..6c5d98e23 100644 --- a/pkg/tcpip/network/ipv6/stats.go +++ b/pkg/tcpip/network/ipv6/stats.go @@ -23,6 +23,8 @@ import ( var _ stack.IPNetworkEndpointStats = (*Stats)(nil) // Stats holds statistics related to the IPv6 protocol family. +// +// +stateify savable type Stats struct { // IP holds IPv6 statistics. IP tcpip.IPStats @@ -43,6 +45,7 @@ func (s *Stats) IPStats() *tcpip.IPStats { return &s.IP } +// +stateify savable type sharedStats struct { localStats Stats ip ip.MultiCounterIPStats @@ -51,6 +54,7 @@ type sharedStats struct { // LINT.IfChange(multiCounterICMPv6PacketStats) +// +stateify savable type multiCounterICMPv6PacketStats struct { echoRequest tcpip.MultiCounterStat echoReply tcpip.MultiCounterStat @@ -91,6 +95,7 @@ func (m *multiCounterICMPv6PacketStats) init(a, b *tcpip.ICMPv6PacketStats) { // LINT.IfChange(multiCounterICMPv6SentPacketStats) +// +stateify savable type multiCounterICMPv6SentPacketStats struct { multiCounterICMPv6PacketStats dropped tcpip.MultiCounterStat @@ -107,6 +112,7 @@ func (m *multiCounterICMPv6SentPacketStats) init(a, b *tcpip.ICMPv6SentPacketSta // LINT.IfChange(multiCounterICMPv6ReceivedPacketStats) +// +stateify savable type multiCounterICMPv6ReceivedPacketStats struct { multiCounterICMPv6PacketStats unrecognized tcpip.MultiCounterStat @@ -125,6 +131,7 @@ func (m *multiCounterICMPv6ReceivedPacketStats) init(a, b *tcpip.ICMPv6ReceivedP // LINT.IfChange(multiCounterICMPv6Stats) +// +stateify savable type multiCounterICMPv6Stats struct { packetsSent multiCounterICMPv6SentPacketStats packetsReceived multiCounterICMPv6ReceivedPacketStats diff --git a/pkg/tcpip/ports/flags.go b/pkg/tcpip/ports/flags.go index 409ef67e9..251b82e96 100644 --- a/pkg/tcpip/ports/flags.go +++ b/pkg/tcpip/ports/flags.go @@ -91,6 +91,8 @@ func (f BitFlags) ToFlags() Flags { } // FlagCounter counts how many references each flag combination has. +// +// +stateify savable type FlagCounter struct { // refs stores the count for each possible flag combination, (0 though // FlagMask). diff --git a/pkg/tcpip/ports/ports.go b/pkg/tcpip/ports/ports.go index 1e9040e4e..b2feca123 100644 --- a/pkg/tcpip/ports/ports.go +++ b/pkg/tcpip/ports/ports.go @@ -65,12 +65,14 @@ func (rs Reservation) dst() destination { } } +// +stateify savable type portDescriptor struct { network tcpip.NetworkProtocolNumber transport tcpip.TransportProtocolNumber port uint16 } +// +stateify savable type destination struct { addr tcpip.Address port uint16 @@ -214,17 +216,19 @@ func (ad addrToDevice) isAvailable(res Reservation, portSpecified bool) bool { } // PortManager manages allocating, reserving and releasing ports. +// +// +stateify savable type PortManager struct { // mu protects allocatedPorts. // LOCK ORDERING: mu > ephemeralMu. - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // allocatedPorts is a nesting of maps that ultimately map Reservations // to FlagCounters describing whether the Reservation is valid and can // be reused. allocatedPorts map[portDescriptor]addrToDevice // ephemeralMu protects firstEphemeral and numEphemeral. - ephemeralMu sync.RWMutex + ephemeralMu sync.RWMutex `state:"nosave"` firstEphemeral uint16 numEphemeral uint16 } diff --git a/pkg/tcpip/stack/addressable_endpoint_state.go b/pkg/tcpip/stack/addressable_endpoint_state.go index 7695bba92..c0290ca6a 100644 --- a/pkg/tcpip/stack/addressable_endpoint_state.go +++ b/pkg/tcpip/stack/addressable_endpoint_state.go @@ -30,6 +30,8 @@ func (lifetimes *AddressLifetimes) sanitize() { var _ AddressableEndpoint = (*AddressableEndpointState)(nil) // AddressableEndpointState is an implementation of an AddressableEndpoint. +// +// +stateify savable type AddressableEndpointState struct { networkEndpoint NetworkEndpoint options AddressableEndpointStateOptions @@ -38,7 +40,7 @@ type AddressableEndpointState struct { // // AddressableEndpointState.mu // addressState.mu - mu addressableEndpointStateRWMutex + mu addressableEndpointStateRWMutex `state:"nosave"` // +checklocks:mu endpoints map[tcpip.Address]*addressState // +checklocks:mu @@ -47,6 +49,8 @@ type AddressableEndpointState struct { // AddressableEndpointStateOptions contains options used to configure an // AddressableEndpointState. +// +// +stateify savable type AddressableEndpointStateOptions struct { // HiddenWhileDisabled determines whether addresses should be returned to // callers while the NetworkEndpoint this AddressableEndpointState belongs @@ -732,6 +736,8 @@ func (a *AddressableEndpointState) Cleanup() { var _ AddressEndpoint = (*addressState)(nil) // addressState holds state for an address. +// +// +stateify savable type addressState struct { addressableEndpointState *AddressableEndpointState addr tcpip.AddressWithPrefix @@ -742,7 +748,7 @@ type addressState struct { // // AddressableEndpointState.mu // addressState.mu - mu addressStateRWMutex + mu addressStateRWMutex `state:"nosave"` refs addressStateRefs // checklocks:mu kind AddressKind diff --git a/pkg/tcpip/stack/conntrack.go b/pkg/tcpip/stack/conntrack.go index b0378799c..ba11e3812 100644 --- a/pkg/tcpip/stack/conntrack.go +++ b/pkg/tcpip/stack/conntrack.go @@ -135,7 +135,8 @@ type conn struct { // reply is the tuple in reply direction. reply tuple - finalizeOnce sync.Once + // TODO(b/341946753): Restore when netstack is savable. + finalizeOnce sync.Once `state:"nosave"` // Holds a finalizeResult. finalizeResult atomicbitops.Uint32 @@ -228,7 +229,8 @@ type ConnTrack struct { // clock provides timing used to determine conntrack reapings. clock tcpip.Clock - rand *rand.Rand + // TODO(b/341946753): Restore when netstack is savable. + rand *rand.Rand `state:"nosave"` mu connTrackRWMutex `state:"nosave"` // mu protects the buckets slice, but not buckets' contents. Only take diff --git a/pkg/tcpip/stack/icmp_rate_limit.go b/pkg/tcpip/stack/icmp_rate_limit.go index 99e5d2df7..560543db4 100644 --- a/pkg/tcpip/stack/icmp_rate_limit.go +++ b/pkg/tcpip/stack/icmp_rate_limit.go @@ -31,8 +31,11 @@ const ( // ICMPRateLimiter is a global rate limiter that controls the generation of // ICMP messages generated by the stack. +// +// +stateify savable type ICMPRateLimiter struct { - limiter *rate.Limiter + // TODO(b/341946753): Restore when netstack is savable. + limiter *rate.Limiter `state:"nosave"` clock tcpip.Clock } diff --git a/pkg/tcpip/stack/iptables_targets.go b/pkg/tcpip/stack/iptables_targets.go index f47b21fe0..3ddc5d987 100644 --- a/pkg/tcpip/stack/iptables_targets.go +++ b/pkg/tcpip/stack/iptables_targets.go @@ -24,6 +24,8 @@ import ( ) // AcceptTarget accepts packets. +// +// +stateify savable type AcceptTarget struct { // NetworkProtocol is the network protocol the target is used with. NetworkProtocol tcpip.NetworkProtocolNumber @@ -35,6 +37,8 @@ func (*AcceptTarget) Action(*PacketBuffer, Hook, *Route, AddressableEndpoint) (R } // DropTarget drops packets. +// +// +stateify savable type DropTarget struct { // NetworkProtocol is the network protocol the target is used with. NetworkProtocol tcpip.NetworkProtocolNumber @@ -67,6 +71,8 @@ const ( // RejectIPv4Target drops packets and sends back an error packet in response to the // matched packet. +// +// +stateify savable type RejectIPv4Target struct { Handler RejectIPv4WithHandler RejectWith RejectIPv4WithICMPType @@ -107,6 +113,8 @@ const ( // RejectIPv6Target drops packets and sends back an error packet in response to the // matched packet. +// +// +stateify savable type RejectIPv6Target struct { Handler RejectIPv6WithHandler RejectWith RejectIPv6WithICMPType @@ -129,6 +137,8 @@ func (rt *RejectIPv6Target) Action(pkt *PacketBuffer, hook Hook, _ *Route, _ Add // ErrorTarget logs an error and drops the packet. It represents a target that // should be unreachable. +// +// +stateify savable type ErrorTarget struct { // NetworkProtocol is the network protocol the target is used with. NetworkProtocol tcpip.NetworkProtocolNumber @@ -141,6 +151,8 @@ func (*ErrorTarget) Action(*PacketBuffer, Hook, *Route, AddressableEndpoint) (Ru } // UserChainTarget marks a rule as the beginning of a user chain. +// +// +stateify savable type UserChainTarget struct { // Name is the chain name. Name string @@ -156,6 +168,8 @@ func (*UserChainTarget) Action(*PacketBuffer, Hook, *Route, AddressableEndpoint) // ReturnTarget returns from the current chain. If the chain is a built-in, the // hook's underflow should be called. +// +// +stateify savable type ReturnTarget struct { // NetworkProtocol is the network protocol the target is used with. NetworkProtocol tcpip.NetworkProtocolNumber @@ -167,6 +181,8 @@ func (*ReturnTarget) Action(*PacketBuffer, Hook, *Route, AddressableEndpoint) (R } // DNATTarget modifies the destination port/IP of packets. +// +// +stateify savable type DNATTarget struct { // The new destination address for packets. // @@ -219,6 +235,8 @@ func (rt *DNATTarget) Action(pkt *PacketBuffer, hook Hook, r *Route, addressEP A // destination port/IP. Outgoing packets are redirected to the loopback device, // and incoming packets are redirected to the incoming interface (rather than // forwarded). +// +// +stateify savable type RedirectTarget struct { // Port indicates port used to redirect. It is immutable. Port uint16 @@ -258,6 +276,8 @@ func (rt *RedirectTarget) Action(pkt *PacketBuffer, hook Hook, r *Route, address } // SNATTarget modifies the source port/IP in the outgoing packets. +// +// +stateify savable type SNATTarget struct { Addr tcpip.Address Port uint16 @@ -356,6 +376,8 @@ func (st *SNATTarget) Action(pkt *PacketBuffer, hook Hook, r *Route, _ Addressab } // MasqueradeTarget modifies the source port/IP in the outgoing packets. +// +// +stateify savable type MasqueradeTarget struct { // NetworkProtocol is the network protocol the target is used with. It // is immutable. diff --git a/pkg/tcpip/stack/iptables_types.go b/pkg/tcpip/stack/iptables_types.go index 86aef6021..0c7ce686e 100644 --- a/pkg/tcpip/stack/iptables_types.go +++ b/pkg/tcpip/stack/iptables_types.go @@ -84,7 +84,7 @@ type IPTables struct { reaper tcpip.Timer - mu ipTablesRWMutex + mu ipTablesRWMutex `state:"nosave"` // v4Tables and v6tables map tableIDs to tables. They hold builtin // tables only, not user tables. // diff --git a/pkg/tcpip/stack/neighbor_cache.go b/pkg/tcpip/stack/neighbor_cache.go index ce7215ca8..fb01e3058 100644 --- a/pkg/tcpip/stack/neighbor_cache.go +++ b/pkg/tcpip/stack/neighbor_cache.go @@ -31,6 +31,24 @@ type NeighborStats struct { UnreachableEntryLookups *tcpip.StatCounter } +// +stateify savable +type dynamicCacheEntry struct { + lru neighborEntryList + + // count tracks the amount of dynamic entries in the cache. This is + // needed since static entries do not count towards the LRU cache + // eviction strategy. + count uint16 +} + +// +stateify savable +type neighborCacheMu struct { + neighborCacheRWMutex `state:"nosave"` + + cache map[tcpip.Address]*neighborEntry + dynamic dynamicCacheEntry +} + // neighborCache maps IP addresses to link addresses. It uses the Least // Recently Used (LRU) eviction strategy to implement a bounded cache for // dynamically acquired entries. It contains the state machine and configuration @@ -43,24 +61,13 @@ type NeighborStats struct { // 2. Static entries are explicitly added by a user and have no expiration. // Their state is always Static. The amount of static entries stored in the // cache is unbounded. +// +// +stateify savable type neighborCache struct { nic *nic state *NUDState linkRes LinkAddressResolver - - mu struct { - neighborCacheRWMutex - - cache map[tcpip.Address]*neighborEntry - dynamic struct { - lru neighborEntryList - - // count tracks the amount of dynamic entries in the cache. This is - // needed since static entries do not count towards the LRU cache - // eviction strategy. - count uint16 - } - } + mu neighborCacheMu } // getOrCreateEntry retrieves a cache entry associated with addr. The diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index eb298410a..8d7b7b76e 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -23,6 +23,7 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/header" ) +// +stateify savable type linkResolver struct { resolver LinkAddressResolver @@ -34,6 +35,8 @@ var _ NetworkDispatcher = (*nic)(nil) // nic represents a "network interface card" to which the networking stack is // attached. +// +// +stateify savable type nic struct { NetworkLinkEndpoint @@ -47,7 +50,7 @@ type nic struct { // enableDisableMu is used to synchronize attempts to enable/disable the NIC. // Without this mutex, calls to enable/disable the NIC may interleave and // leave the NIC in an inconsistent state. - enableDisableMu nicRWMutex + enableDisableMu nicRWMutex `state:"nosave"` // The network endpoints themselves may be modified by calling the interface's // methods, but the map reference and entries must be constant. @@ -69,7 +72,7 @@ type nic struct { linkResQueue packetsPendingLinkResolution // packetEPsMu protects annotated fields below. - packetEPsMu packetEPsRWMutex + packetEPsMu packetEPsRWMutex `state:"nosave"` // eps is protected by the mutex, but the values contained in it are not. // @@ -95,6 +98,7 @@ func makeNICStats(global tcpip.NICStats) sharedStats { return stats } +// +stateify savable type packetEndpointList struct { mu packetEndpointListRWMutex @@ -138,6 +142,7 @@ func (p *packetEndpointList) forEach(fn func(PacketEndpoint)) { var _ QueueingDiscipline = (*delegatingQueueingDiscipline)(nil) +// +stateify savable type delegatingQueueingDiscipline struct { LinkWriter } diff --git a/pkg/tcpip/stack/nic_stats.go b/pkg/tcpip/stack/nic_stats.go index aa336545b..38081682a 100644 --- a/pkg/tcpip/stack/nic_stats.go +++ b/pkg/tcpip/stack/nic_stats.go @@ -18,6 +18,7 @@ import ( "gvisor.dev/gvisor/pkg/tcpip" ) +// +stateify savable type sharedStats struct { local tcpip.NICStats multiCounterNICStats @@ -25,6 +26,7 @@ type sharedStats struct { // LINT.IfChange(multiCounterNICPacketStats) +// +stateify savable type multiCounterNICPacketStats struct { packets tcpip.MultiCounterStat bytes tcpip.MultiCounterStat @@ -39,6 +41,7 @@ func (m *multiCounterNICPacketStats) init(a, b *tcpip.NICPacketStats) { // LINT.IfChange(multiCounterNICNeighborStats) +// +stateify savable type multiCounterNICNeighborStats struct { unreachableEntryLookups tcpip.MultiCounterStat droppedConfirmationForNoninitiatedNeighbor tcpip.MultiCounterStat @@ -55,6 +58,7 @@ func (m *multiCounterNICNeighborStats) init(a, b *tcpip.NICNeighborStats) { // LINT.IfChange(multiCounterNICStats) +// +stateify savable type multiCounterNICStats struct { unknownL3ProtocolRcvdPacketCounts tcpip.MultiIntegralStatCounterMap unknownL4ProtocolRcvdPacketCounts tcpip.MultiIntegralStatCounterMap diff --git a/pkg/tcpip/stack/nud.go b/pkg/tcpip/stack/nud.go index ae586e528..0c9c6cc8f 100644 --- a/pkg/tcpip/stack/nud.go +++ b/pkg/tcpip/stack/nud.go @@ -165,6 +165,8 @@ type ReachabilityConfirmationFlags struct { // NUDConfigurations is the NUD configurations for the netstack. This is used // by the neighbor cache to operate the NUD state machine on each device in the // local network. +// +// +stateify savable type NUDConfigurations struct { // BaseReachableTime is the base duration for computing the random reachable // time. @@ -314,26 +316,31 @@ func calcMaxRandomFactor(minRandomFactor float32) float32 { return defaultMaxRandomFactor } +// +stateify savable +type nudStateMu struct { + sync.RWMutex `state:"nosave"` + + config NUDConfigurations + + // reachableTime is the duration to wait for a REACHABLE entry to + // transition into STALE after inactivity. This value is calculated with + // the algorithm defined in RFC 4861 section 6.3.2. + reachableTime time.Duration + + expiration tcpip.MonotonicTime + prevBaseReachableTime time.Duration + prevMinRandomFactor float32 + prevMaxRandomFactor float32 +} + // NUDState stores states needed for calculating reachable time. +// +// +stateify savable type NUDState struct { clock tcpip.Clock - rng *rand.Rand - - mu struct { - sync.RWMutex - - config NUDConfigurations - - // reachableTime is the duration to wait for a REACHABLE entry to - // transition into STALE after inactivity. This value is calculated with - // the algorithm defined in RFC 4861 section 6.3.2. - reachableTime time.Duration - - expiration tcpip.MonotonicTime - prevBaseReachableTime time.Duration - prevMinRandomFactor float32 - prevMaxRandomFactor float32 - } + // TODO(b/341946753): Restore when netstack is savable. + rng *rand.Rand `state:"nosave"` + mu nudStateMu } // NewNUDState returns new NUDState using c as configuration and the specified diff --git a/pkg/tcpip/stack/pending_packets.go b/pkg/tcpip/stack/pending_packets.go index a7452f891..b95c3cf0c 100644 --- a/pkg/tcpip/stack/pending_packets.go +++ b/pkg/tcpip/stack/pending_packets.go @@ -27,31 +27,36 @@ const ( maxPendingPacketsPerResolution = 256 ) +// +stateify savable type pendingPacket struct { routeInfo RouteInfo pkt *PacketBuffer } +// +stateify savable +type packetsPendingLinkResolutionMu struct { + packetsPendingLinkResolutionMutex `state:"nosave"` + + // The packets to send once the resolver completes. + // + // The link resolution channel is used as the key for this map. + packets map[<-chan struct{}][]pendingPacket + + // FIFO of channels used to cancel the oldest goroutine waiting for + // link-address resolution. + // + // cancelChans holds the same channels that are used as keys to packets. + cancelChans []<-chan struct{} +} + // packetsPendingLinkResolution is a queue of packets pending link resolution. // // Once link resolution completes successfully, the packets will be written. +// +// +stateify savable type packetsPendingLinkResolution struct { nic *nic - - mu struct { - packetsPendingLinkResolutionMutex - - // The packets to send once the resolver completes. - // - // The link resolution channel is used as the key for this map. - packets map[<-chan struct{}][]pendingPacket - - // FIFO of channels used to cancel the oldest goroutine waiting for - // link-address resolution. - // - // cancelChans holds the same channels that are used as keys to packets. - cancelChans []<-chan struct{} - } + mu packetsPendingLinkResolutionMu } func (f *packetsPendingLinkResolution) incrementOutgoingPacketErrors(pkt *PacketBuffer) { diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 8ac23f164..ed208e675 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -387,6 +387,8 @@ const ( // AddressLifetimes encodes an address' preferred and valid lifetimes, as well // as if the address is deprecated. +// +// +stateify savable type AddressLifetimes struct { // Deprecated is whether the address is deprecated. Deprecated bool @@ -920,6 +922,8 @@ type NetworkProtocol interface { // UnicastSourceAndMulticastDestination is a tuple that represents a unicast // source address and a multicast destination address. +// +// +stateify savable type UnicastSourceAndMulticastDestination struct { // Source represents a unicast source address. Source tcpip.Address @@ -1244,6 +1248,8 @@ const ( ) // DADConfigurations holds configurations for duplicate address detection. +// +// +stateify savable type DADConfigurations struct { // The number of Neighbor Solicitation messages to send when doing // Duplicate Address Detection for a tentative address. diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 9d0009ee5..3c9b6d061 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -43,9 +43,10 @@ const ( DefaultTOS = 0 ) +// +stateify savable type transportProtocolState struct { proto TransportProtocol - defaultHandler func(id TransportEndpointID, pkt *PacketBuffer) bool + defaultHandler func(id TransportEndpointID, pkt *PacketBuffer) bool `state:"nosave"` } // RestoredEndpoint is an endpoint that needs to be restored. @@ -76,6 +77,8 @@ var netRawMissingLogger = log.BasicRateLimitedLogger(time.Minute) // table. // // LOCK ORDERING: mu > routeMu. +// +// +stateify savable type Stack struct { transportProtocols map[tcpip.TransportProtocolNumber]*transportProtocolState networkProtocols map[tcpip.NetworkProtocolNumber]NetworkProtocol @@ -90,18 +93,18 @@ type Stack struct { stats tcpip.Stats // routeMu protects annotated fields below. - routeMu routeStackRWMutex + routeMu routeStackRWMutex `state:"nosave"` // +checklocks:routeMu routeTable []tcpip.Route - mu stackRWMutex + mu stackRWMutex `state:"nosave"` // +checklocks:mu nics map[tcpip.NICID]*nic defaultForwardingEnabled map[tcpip.NetworkProtocolNumber]struct{} // cleanupEndpointsMu protects cleanupEndpoints. - cleanupEndpointsMu cleanupEndpointsMutex + cleanupEndpointsMu cleanupEndpointsMutex `state:"nosave"` // +checklocks:cleanupEndpointsMu cleanupEndpoints map[TransportEndpoint]struct{} @@ -109,7 +112,8 @@ type Stack struct { // If not nil, then any new endpoints will have this probe function // invoked everytime they receive a TCP segment. - tcpProbeFunc atomic.Value // TCPProbeFunc + // TODO(b/341946753): Restore them when netstack is savable. + tcpProbeFunc atomic.Value `state:"nosave"` // TCPProbeFunc // clock is used to generate user-visible times. clock tcpip.Clock @@ -119,7 +123,7 @@ type Stack struct { // tables are the iptables packet filtering and manipulation rules. // TODO(gvisor.dev/issue/4595): S/R this field. - tables *IPTables + tables *IPTables `state:"nosave"` // restoredEndpoints is a list of endpoints that need to be restored if the // stack is being restored. @@ -151,10 +155,12 @@ type Stack struct { // randomGenerator is an injectable pseudo random generator that can be // used when a random number is required. It must not be used in // security-sensitive contexts. - insecureRNG *rand.Rand + // TODO(b/341946753): Restore them when netstack is savable. + insecureRNG *rand.Rand `state:"nosave"` // secureRNG is a cryptographically secure random number generator. - secureRNG cryptorand.RNG + // TODO(b/341946753): Restore them when netstack is savable. + secureRNG cryptorand.RNG `state:"nosave"` // sendBufferSize holds the min/default/max send buffer sizes for // endpoints other than TCP. diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index 089f214b0..98e5b1df7 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -23,6 +23,7 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/ports" ) +// +stateify savable type protocolIDs struct { network tcpip.NetworkProtocolNumber transport tcpip.TransportProtocolNumber @@ -30,8 +31,10 @@ type protocolIDs struct { // transportEndpoints manages all endpoints of a given protocol. It has its own // mutex so as to reduce interference between protocols. +// +// +stateify savable type transportEndpoints struct { - mu transportEndpointsRWMutex + mu transportEndpointsRWMutex `state:"nosave"` // +checklocks:mu endpoints map[TransportEndpointID]*endpointsByNIC // rawEndpoints contains endpoints for raw sockets, which receive all @@ -133,11 +136,12 @@ func (eps *transportEndpoints) findEndpointLocked(id TransportEndpointID) *endpo return matchedEP } +// +stateify savable type endpointsByNIC struct { // seed is a random secret for a jenkins hash. seed uint32 - mu endpointsByNICRWMutex + mu endpointsByNICRWMutex `state:"nosave"` // +checklocks:mu endpoints map[tcpip.NICID]*multiPortEndpoint } @@ -266,6 +270,8 @@ func (epsByNIC *endpointsByNIC) unregisterEndpoint(bindToDevice tcpip.NICID, t T // of demultiplexing: first based on the network and transport protocols, then // based on endpoints IDs. It should only be instantiated via // newTransportDemuxer. +// +// +stateify savable type transportDemuxer struct { stack *Stack diff --git a/pkg/tcpip/stdclock.go b/pkg/tcpip/stdclock.go index cc3397ca9..e80e7c4b1 100644 --- a/pkg/tcpip/stdclock.go +++ b/pkg/tcpip/stdclock.go @@ -91,6 +91,7 @@ func (*stdClock) AfterFunc(d time.Duration, f func()) Timer { } } +// +stateify savable type stdTimer struct { t *time.Timer } diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index ccf95cda6..c4e3b576b 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -378,6 +378,8 @@ func (m AddressMask) Equal(other AddressMask) bool { } // Subnet is a subnet defined by its address and mask. +// +// +stateify savable type Subnet struct { address Address mask AddressMask @@ -1094,6 +1096,8 @@ func (*TCPDelayEnabled) isGettableTransportProtocolOption() {} func (*TCPDelayEnabled) isSettableTransportProtocolOption() {} // TCPSendBufferSizeRangeOption is the send buffer size range for TCP. +// +// +stateify savable type TCPSendBufferSizeRangeOption struct { Min int Default int @@ -1105,6 +1109,8 @@ func (*TCPSendBufferSizeRangeOption) isGettableTransportProtocolOption() {} func (*TCPSendBufferSizeRangeOption) isSettableTransportProtocolOption() {} // TCPReceiveBufferSizeRangeOption is the receive buffer size range for TCP. +// +// +stateify savable type TCPReceiveBufferSizeRangeOption struct { Min int Default int @@ -1408,7 +1414,7 @@ const ( TCPTimeWaitReuseGlobal // TCPTimeWaitReuseLoopbackOnly indicates reuse of port bound by endpoint in TIME-WAIT can - // only be reused if the connection was a connection over loopback. i.e src/dest addresses + // only be reused if the connection was a connection over loopback. i.e. src/dest addresses // are loopback addresses. TCPTimeWaitReuseLoopbackOnly ) @@ -1447,6 +1453,8 @@ type IPv6PacketInfo struct { // SendBufferSizeOption is used by stack.(Stack*).Option/SetOption to // get/set the default, min and max send buffer sizes. +// +// +stateify savable type SendBufferSizeOption struct { // Min is the minimum size for send buffer. Min int @@ -1460,6 +1468,8 @@ type SendBufferSizeOption struct { // ReceiveBufferSizeOption is used by stack.(Stack*).Option/SetOption to // get/set the default, min and max receive buffer sizes. +// +// +stateify savable type ReceiveBufferSizeOption struct { // Min is the minimum size for send buffer. Min int @@ -1498,6 +1508,8 @@ func GetStackReceiveBufferLimits(so StackHandler) ReceiveBufferSizeOption { // Route is a row in the routing table. It specifies through which NIC (and // gateway) sets of packets should be routed. A row is considered viable if the // masked target address matches the destination address in the row. +// +// +stateify savable type Route struct { // Destination must contain the target address for this row to be viable. Destination Subnet @@ -1571,6 +1583,8 @@ func (s *StatCounter) String() string { } // A MultiCounterStat keeps track of two counters at once. +// +// +stateify savable type MultiCounterStat struct { a *StatCounter b *StatCounter @@ -1595,6 +1609,8 @@ func (m *MultiCounterStat) IncrementBy(v uint64) { } // ICMPv4PacketStats enumerates counts for all ICMPv4 packet types. +// +// +stateify savable type ICMPv4PacketStats struct { // LINT.IfChange(ICMPv4PacketStats) @@ -1636,6 +1652,8 @@ type ICMPv4PacketStats struct { } // ICMPv4SentPacketStats collects outbound ICMPv4-specific stats. +// +// +stateify savable type ICMPv4SentPacketStats struct { // LINT.IfChange(ICMPv4SentPacketStats) @@ -1652,6 +1670,8 @@ type ICMPv4SentPacketStats struct { } // ICMPv4ReceivedPacketStats collects inbound ICMPv4-specific stats. +// +// +stateify savable type ICMPv4ReceivedPacketStats struct { // LINT.IfChange(ICMPv4ReceivedPacketStats) @@ -1664,6 +1684,8 @@ type ICMPv4ReceivedPacketStats struct { } // ICMPv4Stats collects ICMPv4-specific stats. +// +// +stateify savable type ICMPv4Stats struct { // LINT.IfChange(ICMPv4Stats) @@ -1677,6 +1699,8 @@ type ICMPv4Stats struct { } // ICMPv6PacketStats enumerates counts for all ICMPv6 packet types. +// +// +stateify savable type ICMPv6PacketStats struct { // LINT.IfChange(ICMPv6PacketStats) @@ -1734,6 +1758,8 @@ type ICMPv6PacketStats struct { } // ICMPv6SentPacketStats collects outbound ICMPv6-specific stats. +// +// +stateify savable type ICMPv6SentPacketStats struct { // LINT.IfChange(ICMPv6SentPacketStats) @@ -1750,6 +1776,8 @@ type ICMPv6SentPacketStats struct { } // ICMPv6ReceivedPacketStats collects inbound ICMPv6-specific stats. +// +// +stateify savable type ICMPv6ReceivedPacketStats struct { // LINT.IfChange(ICMPv6ReceivedPacketStats) @@ -1770,6 +1798,8 @@ type ICMPv6ReceivedPacketStats struct { } // ICMPv6Stats collects ICMPv6-specific stats. +// +// +stateify savable type ICMPv6Stats struct { // LINT.IfChange(ICMPv6Stats) @@ -1783,6 +1813,8 @@ type ICMPv6Stats struct { } // ICMPStats collects ICMP-specific stats (both v4 and v6). +// +// +stateify savable type ICMPStats struct { // V4 contains the ICMPv4-specifics stats. V4 ICMPv4Stats @@ -1792,6 +1824,8 @@ type ICMPStats struct { } // IGMPPacketStats enumerates counts for all IGMP packet types. +// +// +stateify savable type IGMPPacketStats struct { // LINT.IfChange(IGMPPacketStats) @@ -1817,6 +1851,8 @@ type IGMPPacketStats struct { } // IGMPSentPacketStats collects outbound IGMP-specific stats. +// +// +stateify savable type IGMPSentPacketStats struct { // LINT.IfChange(IGMPSentPacketStats) @@ -1829,6 +1865,8 @@ type IGMPSentPacketStats struct { } // IGMPReceivedPacketStats collects inbound IGMP-specific stats. +// +// +stateify savable type IGMPReceivedPacketStats struct { // LINT.IfChange(IGMPReceivedPacketStats) @@ -1841,13 +1879,15 @@ type IGMPReceivedPacketStats struct { ChecksumErrors *StatCounter // Unrecognized is the number of unrecognized messages counted, these are - // silently ignored for forward-compatibilty. + // silently ignored for forward-compatibility. Unrecognized *StatCounter // LINT.ThenChange(network/ipv4/stats.go:multiCounterIGMPReceivedPacketStats) } // IGMPStats collects IGMP-specific stats. +// +// +stateify savable type IGMPStats struct { // LINT.IfChange(IGMPStats) @@ -1861,6 +1901,8 @@ type IGMPStats struct { } // IPForwardingStats collects stats related to IP forwarding (both v4 and v6). +// +// +stateify savable type IPForwardingStats struct { // LINT.IfChange(IPForwardingStats) @@ -1923,6 +1965,8 @@ type IPForwardingStats struct { } // IPStats collects IP-specific stats (both v4 and v6). +// +// +stateify savable type IPStats struct { // LINT.IfChange(IPStats) @@ -2005,6 +2049,8 @@ type IPStats struct { } // ARPStats collects ARP-specific stats. +// +// +stateify savable type ARPStats struct { // LINT.IfChange(ARPStats) @@ -2058,6 +2104,8 @@ type ARPStats struct { } // TCPStats collects TCP-specific stats. +// +// +stateify savable type TCPStats struct { // ActiveConnectionOpenings is the number of connections opened // successfully via Connect. @@ -2182,6 +2230,8 @@ type TCPStats struct { } // UDPStats collects UDP-specific stats. +// +// +stateify savable type UDPStats struct { // PacketsReceived is the number of UDP datagrams received via // HandlePacket. @@ -2210,6 +2260,8 @@ type UDPStats struct { } // NICNeighborStats holds metrics for the neighbor table. +// +// +stateify savable type NICNeighborStats struct { // LINT.IfChange(NICNeighborStats) @@ -2231,6 +2283,8 @@ type NICNeighborStats struct { } // NICPacketStats holds basic packet statistics. +// +// +stateify savable type NICPacketStats struct { // LINT.IfChange(NICPacketStats) @@ -2245,8 +2299,10 @@ type NICPacketStats struct { // IntegralStatCounterMap holds a map associating integral keys with // StatCounters. +// +// +stateify savable type IntegralStatCounterMap struct { - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` // +checklocks:mu counterMap map[uint64]*StatCounter } @@ -2297,6 +2353,8 @@ func (m *IntegralStatCounterMap) Increment(key uint64) { // A MultiIntegralStatCounterMap keeps track of two integral counter maps at // once. +// +// +stateify savable type MultiIntegralStatCounterMap struct { a *IntegralStatCounterMap b *IntegralStatCounterMap @@ -2316,6 +2374,8 @@ func (m *MultiIntegralStatCounterMap) Increment(key uint64) { } // NICStats holds NIC statistics. +// +// +stateify savable type NICStats struct { // LINT.IfChange(NICStats) @@ -2361,6 +2421,8 @@ func (s NICStats) FillIn() NICStats { } // Stats holds statistics about the networking stack. +// +// +stateify savable type Stats struct { // TODO(https://gvisor.dev/issues/5986): Make the DroppedPackets stat less // ambiguous. @@ -2711,6 +2773,8 @@ func (a AddressWithPrefix) Subnet() Subnet { // ProtocolAddress is an address and the network protocol it is associated // with. +// +// +stateify savable type ProtocolAddress struct { // Protocol is the protocol of the address. Protocol NetworkProtocolNumber diff --git a/pkg/tcpip/timer.go b/pkg/tcpip/timer.go index b80b34581..28bc2897b 100644 --- a/pkg/tcpip/timer.go +++ b/pkg/tcpip/timer.go @@ -56,6 +56,8 @@ import ( // // To address the above concerns the simplest solution was to give each timer // its own earlyReturn signal. +// +// +stateify savable type jobInstance struct { timer Timer @@ -93,6 +95,8 @@ func (j *jobInstance) stop() { // // Note, it is not safe to copy a Job as its timer instance creates // a closure over the address of the Job. +// +// +stateify savable type Job struct { _ sync.NoCopy @@ -106,7 +110,7 @@ type Job struct { // be held when attempting to stop the timer. // // Must never change after being assigned. - locker sync.Locker + locker sync.Locker `state:"nosave"` // fn is the function that will be called when a timer fires and has not been // signaled to early return. @@ -114,7 +118,8 @@ type Job struct { // fn MUST NOT attempt to lock locker. // // Must never change after being assigned. - fn func() + // TODO(b/341946753): Restore when netstack is savable. + fn func() `state:"nosave"` } // Cancel prevents the Job from executing if it has not executed already. diff --git a/pkg/tcpip/transport/icmp/protocol.go b/pkg/tcpip/transport/icmp/protocol.go index 7e6e3db18..8bca0fa5a 100644 --- a/pkg/tcpip/transport/icmp/protocol.go +++ b/pkg/tcpip/transport/icmp/protocol.go @@ -35,6 +35,8 @@ const ( ) // protocol implements stack.TransportProtocol. +// +// +stateify savable type protocol struct { stack *stack.Stack diff --git a/pkg/tcpip/transport/raw/protocol.go b/pkg/tcpip/transport/raw/protocol.go index 63122b1cb..786f0896d 100644 --- a/pkg/tcpip/transport/raw/protocol.go +++ b/pkg/tcpip/transport/raw/protocol.go @@ -23,6 +23,8 @@ import ( ) // EndpointFactory implements stack.RawFactory. +// +// +stateify savable type EndpointFactory struct{} // NewUnassociatedEndpoint implements stack.RawFactory.NewUnassociatedEndpoint. @@ -37,6 +39,8 @@ func (EndpointFactory) NewPacketEndpoint(stack *stack.Stack, cooked bool, netPro // CreateOnlyFactory implements stack.RawFactory. It allows creation of raw // endpoints that do not support reading, writing, binding, etc. +// +// +stateify savable type CreateOnlyFactory struct{} // NewUnassociatedEndpoint implements stack.RawFactory.NewUnassociatedEndpoint. diff --git a/pkg/tcpip/transport/tcp/dispatcher.go b/pkg/tcpip/transport/tcp/dispatcher.go index 043b84109..aeebbd641 100644 --- a/pkg/tcpip/transport/tcp/dispatcher.go +++ b/pkg/tcpip/transport/tcp/dispatcher.go @@ -29,8 +29,10 @@ import ( ) // epQueue is a queue of endpoints. +// +// +stateify savable type epQueue struct { - mu sync.Mutex + mu sync.Mutex `state:"nosave"` list endpointList } @@ -73,14 +75,17 @@ func (q *epQueue) empty() bool { } // processor is responsible for processing packets queued to a tcp endpoint. +// +// +stateify savable type processor struct { - epQ epQueue - sleeper sleep.Sleeper - newEndpointWaker sleep.Waker - closeWaker sleep.Waker - pauseWaker sleep.Waker - pauseChan chan struct{} - resumeChan chan struct{} + epQ epQueue + sleeper sleep.Sleeper + // TODO(b/341946753): Restore them when netstack is savable. + newEndpointWaker sleep.Waker `state:"nosave"` + closeWaker sleep.Waker `state:"nosave"` + pauseWaker sleep.Waker `state:"nosave"` + pauseChan chan struct{} `state:"nosave"` + resumeChan chan struct{} `state:"nosave"` } func (p *processor) close() { @@ -355,11 +360,13 @@ func (p *processor) resume() { // goroutines do full tcp processing. The processor is selected based on the // hash of the endpoint id to ensure that delivery for the same endpoint happens // in-order. +// +// +stateify savable type dispatcher struct { processors []processor - wg sync.WaitGroup + wg sync.WaitGroup `state:"nosave"` hasher jenkinsHasher - mu sync.Mutex + mu sync.Mutex `state:"nosave"` // +checklocks:mu paused bool // +checklocks:mu @@ -491,6 +498,8 @@ func (d *dispatcher) resume() { } // jenkinsHasher contains state needed to for a jenkins hash. +// +// +stateify savable type jenkinsHasher struct { seed uint32 } diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index 2d07cc6af..9e3a7a14e 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -86,10 +86,11 @@ const ( ccCubic = "cubic" ) +// +stateify savable type protocol struct { stack *stack.Stack - mu sync.RWMutex + mu sync.RWMutex `state:"nosave"` sackEnabled bool recovery tcpip.TCPRecovery delayEnabled bool diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go index 012d3f60d..4d74a6dd8 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go @@ -55,14 +55,17 @@ const maxWindowShift = 14 // TCB is a TCP Control Block. It holds state necessary to keep track of a TCP // connection and inform the caller when the connection has been closed. +// +// +stateify savable type TCB struct { reply stream original stream // State handlers. hdr is not guaranteed to contain bytes beyond the TCP // header itself, i.e. it may not contain the payload. - handlerReply func(tcb *TCB, hdr header.TCP, dataLen int) Result - handlerOriginal func(tcb *TCB, hdr header.TCP, dataLen int) Result + // TODO(b/341946753): Restore them when netstack is savable. + handlerReply func(tcb *TCB, hdr header.TCP, dataLen int) Result `state:"nosave"` + handlerOriginal func(tcb *TCB, hdr header.TCP, dataLen int) Result `state:"nosave"` // firstFin holds a pointer to the first stream to send a FIN. firstFin *stream @@ -321,6 +324,8 @@ func allOtherOriginal(t *TCB, tcp header.TCP, dataLen int) Result { } // streams holds the state of a TCP unidirectional stream. +// +// +stateify savable type stream struct { // The interval [una, end) is the allowed interval as defined by the // receiver, i.e., anything less than una has already been acknowledged diff --git a/pkg/tcpip/transport/udp/protocol.go b/pkg/tcpip/transport/udp/protocol.go index c26ac4d64..49870ab89 100644 --- a/pkg/tcpip/transport/udp/protocol.go +++ b/pkg/tcpip/transport/udp/protocol.go @@ -43,6 +43,7 @@ const ( MaxBufferSize = 4 << 20 // 4MiB ) +// +stateify savable type protocol struct { stack *stack.Stack }