From 90266aa28a2524f928ba1582fa0e6195f97626de Mon Sep 17 00:00:00 2001 From: Nayana Bidari Date: Tue, 21 May 2024 15:15:21 -0700 Subject: [PATCH] Netstack S/R: Mark all the structs in netstack as savable. Marks the structs in netstack as savable. This does not change or break any existing behavior as the netstack itself is not savable yet. PiperOrigin-RevId: 635943481 --- pkg/sentry/socket/netfilter/targets.go | 12 +++ pkg/tcpip/faketime/faketime.go | 56 ++++++++----- pkg/tcpip/link/channel/channel.go | 4 +- pkg/tcpip/link/ethernet/ethernet.go | 2 + pkg/tcpip/link/fdbased/endpoint.go | 10 ++- pkg/tcpip/link/loopback/loopback.go | 3 +- pkg/tcpip/link/muxed/injectable.go | 4 +- pkg/tcpip/link/nested/nested.go | 4 +- pkg/tcpip/link/packetsocket/packetsocket.go | 1 + pkg/tcpip/link/pipe/pipe.go | 4 +- pkg/tcpip/link/sharedmem/sharedmem.go | 10 ++- pkg/tcpip/link/sniffer/sniffer.go | 1 + pkg/tcpip/link/waitable/waitable.go | 4 +- pkg/tcpip/link/xdp/endpoint.go | 8 +- pkg/tcpip/network/arp/arp.go | 6 +- pkg/tcpip/network/arp/stats.go | 4 + .../internal/fragmentation/fragmentation.go | 6 +- .../internal/fragmentation/reassembler.go | 4 +- .../ip/duplicate_address_detection.go | 12 ++- .../internal/ip/generic_multicast_protocol.go | 21 +++-- pkg/tcpip/network/internal/ip/stats.go | 4 + .../network/internal/multicast/route_table.go | 14 +++- pkg/tcpip/network/ipv4/igmp.go | 4 + pkg/tcpip/network/ipv4/ipv4.go | 8 +- pkg/tcpip/network/ipv4/stats.go | 11 +++ pkg/tcpip/network/ipv6/ipv6.go | 78 ++++++++++++------- pkg/tcpip/network/ipv6/mld.go | 4 + pkg/tcpip/network/ipv6/ndp.go | 41 +++++++--- pkg/tcpip/network/ipv6/stats.go | 7 ++ pkg/tcpip/ports/flags.go | 2 + pkg/tcpip/ports/ports.go | 8 +- pkg/tcpip/stack/addressable_endpoint_state.go | 10 ++- pkg/tcpip/stack/conntrack.go | 6 +- pkg/tcpip/stack/icmp_rate_limit.go | 5 +- pkg/tcpip/stack/iptables_targets.go | 22 ++++++ pkg/tcpip/stack/iptables_types.go | 2 +- pkg/tcpip/stack/neighbor_cache.go | 35 +++++---- pkg/tcpip/stack/nic.go | 9 ++- pkg/tcpip/stack/nic_stats.go | 4 + pkg/tcpip/stack/nud.go | 41 ++++++---- pkg/tcpip/stack/pending_packets.go | 35 +++++---- pkg/tcpip/stack/registration.go | 6 ++ pkg/tcpip/stack/stack.go | 22 ++++-- pkg/tcpip/stack/transport_demuxer.go | 10 ++- pkg/tcpip/stdclock.go | 1 + pkg/tcpip/tcpip.go | 70 ++++++++++++++++- pkg/tcpip/timer.go | 9 ++- pkg/tcpip/transport/icmp/protocol.go | 2 + pkg/tcpip/transport/raw/protocol.go | 4 + pkg/tcpip/transport/tcp/dispatcher.go | 29 ++++--- pkg/tcpip/transport/tcp/protocol.go | 3 +- .../transport/tcpconntrack/tcp_conntrack.go | 9 ++- pkg/tcpip/transport/udp/protocol.go | 1 + 53 files changed, 515 insertions(+), 177 deletions(-) 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 }