Encapsulate netstack metrics
PiperOrigin-RevId: 209943212 Change-Id: I96dcbc7c2ab2426e510b94a564436505256c5c79
This commit is contained in:
parent
a78df1d874
commit
abe7764928
|
@ -282,12 +282,12 @@ func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error {
|
|||
func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) {
|
||||
netProto, ok := n.stack.networkProtocols[protocol]
|
||||
if !ok {
|
||||
atomic.AddUint64(&n.stack.stats.UnknownProtocolRcvdPackets, 1)
|
||||
n.stack.stats.UnknownProtocolRcvdPackets.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
if len(vv.First()) < netProto.MinimumPacketSize() {
|
||||
atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1)
|
||||
n.stack.stats.MalformedRcvdPackets.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -330,7 +330,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin
|
|||
}
|
||||
|
||||
if ref == nil {
|
||||
atomic.AddUint64(&n.stack.stats.UnknownNetworkEndpointRcvdPackets, 1)
|
||||
n.stack.stats.UnknownNetworkEndpointRcvdPackets.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -345,19 +345,19 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin
|
|||
func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView) {
|
||||
state, ok := n.stack.transportProtocols[protocol]
|
||||
if !ok {
|
||||
atomic.AddUint64(&n.stack.stats.UnknownProtocolRcvdPackets, 1)
|
||||
n.stack.stats.UnknownProtocolRcvdPackets.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
transProto := state.proto
|
||||
if len(vv.First()) < transProto.MinimumPacketSize() {
|
||||
atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1)
|
||||
n.stack.stats.MalformedRcvdPackets.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
srcPort, dstPort, err := transProto.ParsePorts(vv.First())
|
||||
if err != nil {
|
||||
atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1)
|
||||
n.stack.stats.MalformedRcvdPackets.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -379,7 +379,7 @@ func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolN
|
|||
// We could not find an appropriate destination for this packet, so
|
||||
// deliver it to the global handler.
|
||||
if !transProto.HandleUnknownDestinationPacket(r, id, vv) {
|
||||
atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1)
|
||||
n.stack.stats.MalformedRcvdPackets.Increment()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ package stack
|
|||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"gvisor.googlesource.com/gvisor/pkg/sleep"
|
||||
|
@ -308,6 +307,9 @@ type Options struct {
|
|||
//
|
||||
// If no Clock is specified, the clock source will be time.Now.
|
||||
Clock tcpip.Clock
|
||||
|
||||
// Stats are optional statistic counters.
|
||||
Stats tcpip.Stats
|
||||
}
|
||||
|
||||
// New allocates a new networking stack with only the requested networking and
|
||||
|
@ -331,6 +333,7 @@ func New(network []string, transport []string, opts Options) *Stack {
|
|||
linkAddrCache: newLinkAddrCache(ageLimit, resolutionTimeout, resolutionAttempts),
|
||||
PortManager: ports.NewPortManager(),
|
||||
clock: clock,
|
||||
stats: opts.Stats.FillIn(),
|
||||
}
|
||||
|
||||
// Add specified network protocols.
|
||||
|
@ -437,27 +440,12 @@ func (s *Stack) NowNanoseconds() int64 {
|
|||
return s.clock.NowNanoseconds()
|
||||
}
|
||||
|
||||
// Stats returns a snapshot of the current stats.
|
||||
//
|
||||
// NOTE: The underlying stats are updated using atomic instructions as a result
|
||||
// the snapshot returned does not represent the value of all the stats at any
|
||||
// single given point of time.
|
||||
// TODO: Make stats available in sentry for debugging/diag.
|
||||
func (s *Stack) Stats() tcpip.Stats {
|
||||
return tcpip.Stats{
|
||||
UnknownProtocolRcvdPackets: atomic.LoadUint64(&s.stats.UnknownProtocolRcvdPackets),
|
||||
UnknownNetworkEndpointRcvdPackets: atomic.LoadUint64(&s.stats.UnknownNetworkEndpointRcvdPackets),
|
||||
MalformedRcvdPackets: atomic.LoadUint64(&s.stats.MalformedRcvdPackets),
|
||||
DroppedPackets: atomic.LoadUint64(&s.stats.DroppedPackets),
|
||||
}
|
||||
}
|
||||
|
||||
// MutableStats returns a mutable copy of the current stats.
|
||||
// Stats returns a mutable copy of the current stats.
|
||||
//
|
||||
// This is not generally exported via the public interface, but is available
|
||||
// internally.
|
||||
func (s *Stack) MutableStats() *tcpip.Stats {
|
||||
return &s.stats
|
||||
func (s *Stack) Stats() tcpip.Stats {
|
||||
return s.stats
|
||||
}
|
||||
|
||||
// SetRouteTable assigns the route table to be used by this stack. It
|
||||
|
|
|
@ -34,6 +34,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"
|
||||
|
@ -465,23 +466,62 @@ type TransportProtocolNumber uint32
|
|||
// NetworkProtocolNumber is the number of a network protocol.
|
||||
type NetworkProtocolNumber uint32
|
||||
|
||||
// A StatCounter keeps track of a statistic.
|
||||
type StatCounter struct {
|
||||
count uint64
|
||||
}
|
||||
|
||||
// Increment adds one to the counter.
|
||||
func (s *StatCounter) Increment() {
|
||||
atomic.AddUint64(&s.count, 1)
|
||||
}
|
||||
|
||||
// Value returns the current value of the counter.
|
||||
func (s *StatCounter) Value() uint64 {
|
||||
return atomic.LoadUint64(&s.count)
|
||||
}
|
||||
|
||||
// IncrementBy increments the counter by v.
|
||||
func (s *StatCounter) IncrementBy(v uint64) {
|
||||
atomic.AddUint64(&s.count, v)
|
||||
}
|
||||
|
||||
// Stats holds statistics about the networking stack.
|
||||
//
|
||||
// All fields are optional.
|
||||
type Stats struct {
|
||||
// UnknownProtocolRcvdPackets is the number of packets received by the
|
||||
// stack that were for an unknown or unsupported protocol.
|
||||
UnknownProtocolRcvdPackets uint64
|
||||
UnknownProtocolRcvdPackets *StatCounter
|
||||
|
||||
// UnknownNetworkEndpointRcvdPackets is the number of packets received
|
||||
// by the stack that were for a supported network protocol, but whose
|
||||
// destination address didn't having a matching endpoint.
|
||||
UnknownNetworkEndpointRcvdPackets uint64
|
||||
UnknownNetworkEndpointRcvdPackets *StatCounter
|
||||
|
||||
// MalformedRcvPackets is the number of packets received by the stack
|
||||
// that were deemed malformed.
|
||||
MalformedRcvdPackets uint64
|
||||
MalformedRcvdPackets *StatCounter
|
||||
|
||||
// DroppedPackets is the number of packets dropped due to full queues.
|
||||
DroppedPackets uint64
|
||||
DroppedPackets *StatCounter
|
||||
}
|
||||
|
||||
// FillIn returns a copy of s with nil fields initialized to new StatCounters.
|
||||
func (s Stats) FillIn() Stats {
|
||||
if s.UnknownProtocolRcvdPackets == nil {
|
||||
s.UnknownProtocolRcvdPackets = &StatCounter{}
|
||||
}
|
||||
if s.UnknownNetworkEndpointRcvdPackets == nil {
|
||||
s.UnknownNetworkEndpointRcvdPackets = &StatCounter{}
|
||||
}
|
||||
if s.MalformedRcvdPackets == nil {
|
||||
s.MalformedRcvdPackets = &StatCounter{}
|
||||
}
|
||||
if s.DroppedPackets == nil {
|
||||
s.DroppedPackets = &StatCounter{}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
|
|
|
@ -16,7 +16,6 @@ package tcp
|
|||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"gvisor.googlesource.com/gvisor/pkg/rand"
|
||||
|
@ -292,7 +291,7 @@ func (h *handshake) synRcvdState(s *segment) *tcpip.Error {
|
|||
// not carry a timestamp option then the segment must be dropped
|
||||
// as per https://tools.ietf.org/html/rfc7323#section-3.2.
|
||||
if h.ep.sendTSOk && !s.parsedOptions.TS {
|
||||
atomic.AddUint64(&h.ep.stack.MutableStats().DroppedPackets, 1)
|
||||
h.ep.stack.Stats().DroppedPackets.Increment()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -793,7 +792,7 @@ func (e *endpoint) handleSegments() *tcpip.Error {
|
|||
// must be dropped as per
|
||||
// https://tools.ietf.org/html/rfc7323#section-3.2.
|
||||
if e.sendTSOk && !s.parsedOptions.TS {
|
||||
atomic.AddUint64(&e.stack.MutableStats().DroppedPackets, 1)
|
||||
e.stack.Stats().DroppedPackets.Increment()
|
||||
s.decRef()
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -1225,7 +1225,7 @@ func (e *endpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Error) {
|
|||
func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) {
|
||||
s := newSegment(r, id, vv)
|
||||
if !s.parse() {
|
||||
atomic.AddUint64(&e.stack.MutableStats().MalformedRcvdPackets, 1)
|
||||
e.stack.Stats().MalformedRcvdPackets.Increment()
|
||||
s.decRef()
|
||||
return
|
||||
}
|
||||
|
@ -1235,7 +1235,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv
|
|||
e.newSegmentWaker.Assert()
|
||||
} else {
|
||||
// The queue is full, so we drop the segment.
|
||||
atomic.AddUint64(&e.stack.MutableStats().DroppedPackets, 1)
|
||||
e.stack.Stats().DroppedPackets.Increment()
|
||||
s.decRef()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,7 +268,8 @@ func TestSegmentDropWhenTimestampMissing(t *testing.T) {
|
|||
defer c.WQ.EventUnregister(&we)
|
||||
|
||||
stk := c.Stack()
|
||||
droppedPackets := stk.Stats().DroppedPackets
|
||||
droppedPacketsStat := stk.Stats().DroppedPackets
|
||||
droppedPackets := droppedPacketsStat.Value()
|
||||
data := []byte{1, 2, 3}
|
||||
// Save the sequence number as we will reset it later down
|
||||
// in the test.
|
||||
|
@ -283,11 +284,11 @@ func TestSegmentDropWhenTimestampMissing(t *testing.T) {
|
|||
}
|
||||
|
||||
// Assert that DroppedPackets was incremented by 1.
|
||||
if got, want := stk.Stats().DroppedPackets, droppedPackets+1; got != want {
|
||||
if got, want := droppedPacketsStat.Value(), droppedPackets+1; got != want {
|
||||
t.Fatalf("incorrect number of dropped packets, got: %v, want: %v", got, want)
|
||||
}
|
||||
|
||||
droppedPackets = stk.Stats().DroppedPackets
|
||||
droppedPackets = droppedPacketsStat.Value()
|
||||
// Reset the sequence number so that the other endpoint accepts
|
||||
// this segment and does not treat it like an out of order delivery.
|
||||
rep.NextSeqNum = savedSeqNum
|
||||
|
@ -301,7 +302,7 @@ func TestSegmentDropWhenTimestampMissing(t *testing.T) {
|
|||
}
|
||||
|
||||
// Assert that DroppedPackets was not incremented by 1.
|
||||
if got, want := stk.Stats().DroppedPackets, droppedPackets; got != want {
|
||||
if got, want := droppedPacketsStat.Value(), droppedPackets; got != want {
|
||||
t.Fatalf("incorrect number of dropped packets, got: %v, want: %v", got, want)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue