Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 42 additions & 30 deletions pkg/sentry/fsimpl/proc/task_net.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"io"
"reflect"
"strings"
"time"

"gvisor.dev/gvisor/pkg/abi/linux"
Expand Down Expand Up @@ -784,38 +785,49 @@ type netStatData struct {

var _ dynamicInode = (*netStatData)(nil)

const netStatTCPExtFields = "SyncookiesSent SyncookiesRecv SyncookiesFailed " +
"EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps " +
"LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSPassive " +
"PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost " +
"ListenOverflows ListenDrops TCPPrequeued TCPDirectCopyFromBacklog " +
"TCPDirectCopyFromPrequeue TCPPrequeueDropped TCPHPHits TCPHPHitsToUser " +
"TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging " +
"TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo " +
"TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLostRetransmit " +
"TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans " +
"TCPForwardRetrans TCPSlowStartRetrans TCPTimeouts TCPLossProbes " +
"TCPLossProbeRecovery TCPRenoRecoveryFail TCPSackRecoveryFail " +
"TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent " +
"TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnData TCPAbortOnClose " +
"TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed " +
"TCPMemoryPressures TCPSACKDiscard TCPDSACKIgnoredOld " +
"TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected " +
"TCPMD5Failure TCPSackShifted TCPSackMerged TCPSackShiftFallback " +
"TCPBacklogDrop TCPMinTTLDrop TCPDeferAcceptDrop IPReversePathFilter " +
"TCPTimeWaitOverflow TCPReqQFullDoCookies TCPReqQFullDrop TCPRetransFail " +
"TCPRcvCoalesce TCPOFOQueue TCPOFODrop TCPOFOMerge TCPChallengeACK " +
"TCPSYNChallenge TCPFastOpenActive TCPFastOpenActiveFail " +
"TCPFastOpenPassive TCPFastOpenPassiveFail TCPFastOpenListenOverflow " +
"TCPFastOpenCookieReqd TCPSpuriousRtxHostQueues BusyPollRxPackets " +
"TCPAutoCorking TCPFromZeroWindowAdv TCPToZeroWindowAdv " +
"TCPWantZeroWindowAdv TCPSynRetrans TCPOrigDataSent TCPHystartTrainDetect " +
"TCPHystartTrainCwnd TCPHystartDelayDetect TCPHystartDelayCwnd " +
"TCPACKSkippedSynRecv TCPACKSkippedPAWS TCPACKSkippedSeq " +
"TCPACKSkippedFinWait2 TCPACKSkippedTimeWait TCPACKSkippedChallenge " +
"TCPWinProbe TCPKeepAlive TCPMTUPFail TCPMTUPSuccess"

func writeNetStatHeaderAndZeros(buf *bytes.Buffer, prefix, fields string) {
fmt.Fprintf(buf, "%s: %s\n", prefix, fields)
fmt.Fprintf(buf, "%s:", prefix)
for range strings.Fields(fields) {
buf.WriteString(" 0")
}
buf.WriteByte('\n')
}

// Generate implements vfs.DynamicBytesSource.Generate.
// See Linux's net/ipv4/fib_trie.c:fib_route_seq_show.
func (d *netStatData) Generate(ctx context.Context, buf *bytes.Buffer) error {
buf.WriteString("TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed " +
"EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps " +
"LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSPassive " +
"PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost " +
"ListenOverflows ListenDrops TCPPrequeued TCPDirectCopyFromBacklog " +
"TCPDirectCopyFromPrequeue TCPPrequeueDropped TCPHPHits TCPHPHitsToUser " +
"TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging " +
"TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo " +
"TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLostRetransmit " +
"TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans " +
"TCPForwardRetrans TCPSlowStartRetrans TCPTimeouts TCPLossProbes " +
"TCPLossProbeRecovery TCPRenoRecoveryFail TCPSackRecoveryFail " +
"TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent " +
"TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnData TCPAbortOnClose " +
"TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed " +
"TCPMemoryPressures TCPSACKDiscard TCPDSACKIgnoredOld " +
"TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected " +
"TCPMD5Failure TCPSackShifted TCPSackMerged TCPSackShiftFallback " +
"TCPBacklogDrop TCPMinTTLDrop TCPDeferAcceptDrop IPReversePathFilter " +
"TCPTimeWaitOverflow TCPReqQFullDoCookies TCPReqQFullDrop TCPRetransFail " +
"TCPRcvCoalesce TCPOFOQueue TCPOFODrop TCPOFOMerge TCPChallengeACK " +
"TCPSYNChallenge TCPFastOpenActive TCPFastOpenActiveFail " +
"TCPFastOpenPassive TCPFastOpenPassiveFail TCPFastOpenListenOverflow " +
"TCPFastOpenCookieReqd TCPSpuriousRtxHostQueues BusyPollRxPackets " +
"TCPAutoCorking TCPFromZeroWindowAdv TCPToZeroWindowAdv " +
"TCPWantZeroWindowAdv TCPSynRetrans TCPOrigDataSent TCPHystartTrainDetect " +
"TCPHystartTrainCwnd TCPHystartDelayDetect TCPHystartDelayCwnd " +
"TCPACKSkippedSynRecv TCPACKSkippedPAWS TCPACKSkippedSeq " +
"TCPACKSkippedFinWait2 TCPACKSkippedTimeWait TCPACKSkippedChallenge " +
"TCPWinProbe TCPKeepAlive TCPMTUPFail TCPMTUPSuccess\n")
writeNetStatHeaderAndZeros(buf, "TcpExt", netStatTCPExtFields)
return nil
}
29 changes: 29 additions & 0 deletions pkg/sentry/fsimpl/proc/tasks_sys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"bytes"
"reflect"
"slices"
"strings"
"testing"

"gvisor.dev/gvisor/pkg/abi/linux"
Expand Down Expand Up @@ -80,6 +81,34 @@ func TestIfinet6(t *testing.T) {
}
}

func TestNetStatDataRowsHaveMatchingFields(t *testing.T) {
n := &netStatData{}
var buf bytes.Buffer
if err := n.Generate(contexttest.Context(t), &buf); err != nil {
t.Fatalf("n.Generate() failed: %v", err)
}

lines := strings.Split(strings.TrimSpace(buf.String()), "\n")
if len(lines)%2 != 0 {
t.Fatalf("got %d lines, want name/value line pairs: %q", len(lines), buf.String())
}
for i := 0; i < len(lines); i += 2 {
names := strings.Fields(lines[i])
values := strings.Fields(lines[i+1])
if len(names) != len(values) {
t.Errorf("line %d has %d names, line %d has %d values: names=%q values=%q", i, len(names), i+1, len(values), lines[i], lines[i+1])
}
if names[0] != values[0] {
t.Errorf("line %d prefix = %q, line %d prefix = %q, want matching prefixes", i, names[0], i+1, values[0])
}
for _, value := range values[1:] {
if value != "0" {
t.Errorf("got netstat value %q, want 0", value)
}
}
}
}

// TestIPForwarding tests the implementation of
// /proc/sys/net/ipv4/ip_forwarding
func TestConfigureIPForwarding(t *testing.T) {
Expand Down
3 changes: 0 additions & 3 deletions test/syscalls/linux/proc_net.cc
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,6 @@ TEST(ProcNetSnmp, UdpIn) {
}

TEST(ProcNetSnmp, CheckNetStat) {
// TODO(b/155123175): SNMP and netstat don't work on gVisor.
SKIP_IF(IsRunningOnGvisor());

std::string contents =
ASSERT_NO_ERRNO_AND_VALUE(GetContents("/proc/net/netstat"));

Expand Down
Loading