diff --git a/pkg/tcpip/network/internal/fragmentation/fragmentation.go b/pkg/tcpip/network/internal/fragmentation/fragmentation.go index 762cd751d..e0b64a6b7 100644 --- a/pkg/tcpip/network/internal/fragmentation/fragmentation.go +++ b/pkg/tcpip/network/internal/fragmentation/fragmentation.go @@ -19,9 +19,9 @@ package fragmentation import ( "errors" "fmt" - "log" "time" + "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/buffer" @@ -219,6 +219,16 @@ func (f *Fragmentation) Process( return resPkt, firstFragmentProto, done, nil } +// Release releases all underlying resources. +func (f *Fragmentation) Release() { + f.mu.Lock() + defer f.mu.Unlock() + for _, r := range f.reassemblers { + f.release(r, false /* timedOut */) + } + f.reassemblers = nil +} + func (f *Fragmentation) release(r *reassembler, timedOut bool) { // Before releasing a fragment we need to check if r is already marked as done. // Otherwise, we would delete it twice. @@ -230,7 +240,7 @@ func (f *Fragmentation) release(r *reassembler, timedOut bool) { f.rList.Remove(r) f.memSize -= r.memSize if f.memSize < 0 { - log.Printf("memory counter < 0 (%d), this is an accounting bug that requires investigation", f.memSize) + log.Warningf("memory counter < 0 (%d), this is an accounting bug that requires investigation", f.memSize) f.memSize = 0 } @@ -239,12 +249,15 @@ func (f *Fragmentation) release(r *reassembler, timedOut bool) { } if r.pkt != nil { r.pkt.DecRef() + r.pkt = nil } for _, h := range r.holes { if h.pkt != nil { h.pkt.DecRef() + h.pkt = nil } } + r.holes = nil } // releaseReassemblersLocked releases already-expired reassemblers, then diff --git a/pkg/tcpip/network/internal/fragmentation/reassembler.go b/pkg/tcpip/network/internal/fragmentation/reassembler.go index f00c57b86..acf4abaaa 100644 --- a/pkg/tcpip/network/internal/fragmentation/reassembler.go +++ b/pkg/tcpip/network/internal/fragmentation/reassembler.go @@ -174,7 +174,7 @@ func (r *reassembler) process(first, last uint16, more bool, proto uint8, pkt *s for i := 1; i < len(r.holes); i++ { stack.MergeFragment(resPkt, r.holes[i].pkt) } - return resPkt, r.proto, true, memConsumed, nil + return resPkt, r.proto, true /* done */, memConsumed, nil } func (r *reassembler) checkDoneOrMark() bool { diff --git a/pkg/tcpip/network/internal/testutil/testutil.go b/pkg/tcpip/network/internal/testutil/testutil.go index c03e6072b..67e42f799 100644 --- a/pkg/tcpip/network/internal/testutil/testutil.go +++ b/pkg/tcpip/network/internal/testutil/testutil.go @@ -69,6 +69,7 @@ func (ep *MockLinkEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpi return n, ep.err } ep.allowPackets-- + pkt.IncRef() ep.WrittenPackets = append(ep.WrittenPackets, pkt) n++ } @@ -90,6 +91,14 @@ func (*MockLinkEndpoint) ARPHardwareType() header.ARPHardwareType { return heade // AddHeader implements LinkEndpoint.AddHeader. func (*MockLinkEndpoint) AddHeader(*stack.PacketBuffer) {} +// Close releases all resources. +func (ep *MockLinkEndpoint) Close() { + for _, pkt := range ep.WrittenPackets { + pkt.DecRef() + } + ep.WrittenPackets = nil +} + // MakeRandPkt generates a randomized packet. transportHeaderLength indicates // how many random bytes will be copied in the Transport Header. // extraHeaderReserveLength indicates how much extra space will be reserved for diff --git a/pkg/tcpip/network/ipv4/BUILD b/pkg/tcpip/network/ipv4/BUILD index 2257f728e..5e931277e 100644 --- a/pkg/tcpip/network/ipv4/BUILD +++ b/pkg/tcpip/network/ipv4/BUILD @@ -30,8 +30,11 @@ go_test( srcs = [ "igmp_test.go", "ipv4_test.go", + "main_test.go", ], deps = [ + "//pkg/refs", + "//pkg/refsvfs2", "//pkg/sync", "//pkg/tcpip", "//pkg/tcpip/buffer", diff --git a/pkg/tcpip/network/ipv4/igmp_test.go b/pkg/tcpip/network/ipv4/igmp_test.go index 4178d61f8..652ab1cbd 100644 --- a/pkg/tcpip/network/ipv4/igmp_test.go +++ b/pkg/tcpip/network/ipv4/igmp_test.go @@ -63,7 +63,18 @@ func validateIgmpPacket(t *testing.T, pkt *stack.PacketBuffer, igmpType header.I ) } -func createStack(t *testing.T, igmpEnabled bool) (*channel.Endpoint, *stack.Stack, *faketime.ManualClock) { +type igmpTestContext struct { + s *stack.Stack + ep *channel.Endpoint + clock *faketime.ManualClock +} + +func (ctx igmpTestContext) cleanup() { + ctx.s.Close() + ctx.s.Wait() +} + +func newIGMPTestContext(t *testing.T, igmpEnabled bool) igmpTestContext { t.Helper() // Create an endpoint of queue size 1, since no more than 1 packets are ever @@ -81,7 +92,12 @@ func createStack(t *testing.T, igmpEnabled bool) (*channel.Endpoint, *stack.Stac if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } - return e, s, clock + + return igmpTestContext{ + ep: e, + s: s, + clock: clock, + } } func createAndInjectIGMPPacket(e *channel.Endpoint, igmpType header.IGMPType, maxRespTime byte, ttl uint8, srcAddr, dstAddr, groupAddress tcpip.Address, hasRouterAlertOption bool) { @@ -109,17 +125,22 @@ func createAndInjectIGMPPacket(e *channel.Endpoint, igmpType header.IGMPType, ma igmp.SetMaxRespTime(maxRespTime) igmp.SetGroupAddress(groupAddress) igmp.SetChecksum(header.IGMPCalculateChecksum(igmp)) - - e.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ + pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: buf.ToVectorisedView(), - })) + }) + e.InjectInbound(ipv4.ProtocolNumber, pkt) + pkt.DecRef() } // TestIGMPV1Present tests the node's ability to fallback to V1 when a V1 // router is detected. V1 present status is expected to be reset when the NIC // cycles. func TestIGMPV1Present(t *testing.T) { - e, s, clock := createStack(t, true) + ctx := newIGMPTestContext(t, true /* igmpEnabled */) + defer ctx.cleanup() + s := ctx.s + e := ctx.ep + protocolAddr := tcpip.ProtocolAddress{ Protocol: ipv4.ProtocolNumber, AddressWithPrefix: tcpip.AddressWithPrefix{Address: stackAddr, PrefixLen: defaultPrefixLength}, @@ -168,7 +189,7 @@ func TestIGMPV1Present(t *testing.T) { if p := e.Read(); p != nil { t.Fatalf("sent unexpected packet, expected V1MembershipReport only after advancing the clock = %+v", p) } - clock.Advance(ipv4.UnsolicitedReportIntervalMax) + ctx.clock.Advance(ipv4.UnsolicitedReportIntervalMax) { p := e.Read() if p == nil { @@ -200,7 +221,11 @@ func TestIGMPV1Present(t *testing.T) { } func TestSendQueuedIGMPReports(t *testing.T) { - e, s, clock := createStack(t, true) + ctx := newIGMPTestContext(t, true /* igmpEnabled */) + defer ctx.cleanup() + s := ctx.s + e := ctx.ep + clock := ctx.clock // Joining a group without an assigned address should queue IGMP packets; none // should be sent without an assigned address. @@ -358,7 +383,11 @@ func TestIGMPPacketValidation(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - e, s, _ := createStack(t, true) + ctx := newIGMPTestContext(t, true /* igmpEnabled */) + defer ctx.cleanup() + s := ctx.s + e := ctx.ep + for _, address := range test.stackAddresses { protocolAddr := tcpip.ProtocolAddress{ Protocol: ipv4.ProtocolNumber, diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index d2a41a9d4..031cac9e9 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -417,13 +417,13 @@ func (e *endpoint) handleFragments(_ *stack.Route, networkMTU uint32, pkt *stack var n int for { fragPkt, more := buildNextFragment(&pf, networkHeader) - if err := handler(fragPkt); err != nil { - fragPkt.DecRef() + err := handler(fragPkt) + fragPkt.DecRef() + if err != nil { return n, pf.RemainingFragmentCount() + 1, err } n++ if !more { - fragPkt.DecRef() return n, pf.RemainingFragmentCount(), nil } } @@ -1239,7 +1239,9 @@ func (p *protocol) DefaultTTL() uint8 { } // Close implements stack.TransportProtocol. -func (*protocol) Close() {} +func (p *protocol) Close() { + p.fragmentation.Release() +} // Wait implements stack.TransportProtocol. func (*protocol) Wait() {} diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go index 001f16f5b..7b6ecfd09 100644 --- a/pkg/tcpip/network/ipv4/ipv4_test.go +++ b/pkg/tcpip/network/ipv4/ipv4_test.go @@ -50,11 +50,31 @@ const ( defaultMTU = 65536 ) -func TestExcludeBroadcast(t *testing.T) { +type testContext struct { + s *stack.Stack + clock *faketime.ManualClock +} + +func newTestContext() testContext { + clock := faketime.NewManualClock() s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol}, + NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol}, TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, + Clock: clock, + RawFactory: raw.EndpointFactory{}, }) + return testContext{s: s, clock: clock} +} + +func (ctx testContext) cleanup() { + ctx.s.Close() + ctx.s.Wait() +} + +func TestExcludeBroadcast(t *testing.T) { + ctx := newTestContext() + defer ctx.cleanup() + s := ctx.s ep := stack.LinkEndpoint(channel.New(256, defaultMTU, "")) if testing.Verbose() { @@ -342,13 +362,10 @@ func TestForwarding(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - clock := faketime.NewManualClock() - - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4}, - Clock: clock, - }) + ctx := newTestContext() + defer ctx.cleanup() + s := ctx.s + clock := ctx.clock // Advance the clock by some unimportant amount to make // it give a more recognisable signature than 00,00,00,00. @@ -429,9 +446,9 @@ func TestForwarding(t *testing.T) { requestPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: hdr.View().ToVectorisedView(), }) + defer requestPkt.DecRef() requestPkt.NetworkProtocolNumber = header.IPv4ProtocolNumber incomingEndpoint.InjectInbound(header.IPv4ProtocolNumber, requestPkt) - reply := incomingEndpoint.Read() if test.expectErrorICMP { @@ -1172,12 +1189,11 @@ func TestIPv4Sanity(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - clock := faketime.NewManualClock() - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4}, - Clock: clock, - }) + ctx := newTestContext() + defer ctx.cleanup() + s := ctx.s + clock := ctx.clock + // Advance the clock by some unimportant amount to make // it give a more recognisable signature than 00,00,00,00. clock.Advance(time.Millisecond * randomTimeOffset) @@ -1252,6 +1268,7 @@ func TestIPv4Sanity(t *testing.T) { requestPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: hdr.View().ToVectorisedView(), }) + defer requestPkt.DecRef() e.InjectInbound(header.IPv4ProtocolNumber, requestPkt) reply := e.Read() if reply == nil { @@ -1544,10 +1561,16 @@ func TestFragmentationWritePacket(t *testing.T) { for _, ft := range fragmentationTests { t.Run(ft.description, func(t *testing.T) { + ctx := newTestContext() + defer ctx.cleanup() + ep := iptestutil.NewMockLinkEndpoint(ft.mtu, nil, math.MaxInt32) - r := buildRoute(t, ep) + defer ep.Close() + r := buildRoute(t, ctx, ep) pkt := iptestutil.MakeRandPkt(ft.transportHeaderLength, extraHeaderReserve+header.IPv4MinimumSize, []int{ft.payloadSize}, header.IPv4ProtocolNumber) + defer pkt.DecRef() source := pkt.Clone() + defer source.DecRef() err := r.WritePacket(stack.NetworkHeaderParams{ Protocol: tcp.ProtocolNumber, TTL: ttl, @@ -1641,9 +1664,14 @@ func TestFragmentationErrors(t *testing.T) { for _, ft := range tests { t.Run(ft.description, func(t *testing.T) { - pkt := iptestutil.MakeRandPkt(ft.transportHeaderLength, extraHeaderReserve+header.IPv4MinimumSize, []int{ft.payloadSize}, header.IPv4ProtocolNumber) + ctx := newTestContext() + defer ctx.cleanup() + ep := iptestutil.NewMockLinkEndpoint(ft.mtu, ft.mockError, ft.allowPackets) - r := buildRoute(t, ep) + defer ep.Close() + r := buildRoute(t, ctx, ep) + pkt := iptestutil.MakeRandPkt(ft.transportHeaderLength, extraHeaderReserve+header.IPv4MinimumSize, []int{ft.payloadSize}, header.IPv4ProtocolNumber) + defer pkt.DecRef() err := r.WritePacket(stack.NetworkHeaderParams{ Protocol: tcp.ProtocolNumber, TTL: ttl, @@ -1924,11 +1952,10 @@ func TestInvalidFragments(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ - ipv4.NewProtocol, - }, - }) + ctx := newTestContext() + defer ctx.cleanup() + s := ctx.s + e := channel.New(0, 1500, linkAddr) if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) @@ -1967,9 +1994,11 @@ func TestInvalidFragments(t *testing.T) { } vv := hdr.View().ToVectorisedView() - e.InjectInbound(header.IPv4ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ + pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: vv, - })) + }) + e.InjectInbound(header.IPv4ProtocolNumber, pkt) + pkt.DecRef() } if got, want := s.Stats().IP.MalformedPacketsReceived.Value(), test.wantMalformedIPPackets; got != want { @@ -2151,13 +2180,11 @@ func TestFragmentReassemblyTimeout(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - clock := faketime.NewManualClock() - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ - ipv4.NewProtocol, - }, - Clock: clock, - }) + ctx := newTestContext() + defer ctx.cleanup() + s := ctx.s + clock := ctx.clock + e := channel.New(1, 1500, linkAddr) if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) @@ -2197,6 +2224,7 @@ func TestFragmentReassemblyTimeout(t *testing.T) { } e.InjectInbound(header.IPv4ProtocolNumber, pkt) + pkt.DecRef() } clock.Advance(ipv4.ReassembleTimeout) @@ -2622,12 +2650,10 @@ func TestReceiveFragments(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - // Setup a stack and endpoint. - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, - RawFactory: raw.EndpointFactory{}, - }) + ctx := newTestContext() + defer ctx.cleanup() + s := ctx.s + e := channel.New(0, 1280, "\xf0\x00") if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) @@ -2683,10 +2709,11 @@ func TestReceiveFragments(t *testing.T) { vv := hdr.View().ToVectorisedView() vv.AppendView(frag.payload) - - e.InjectInbound(header.IPv4ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ + pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: vv, - })) + }) + e.InjectInbound(header.IPv4ProtocolNumber, pkt) + pkt.DecRef() } if got, want := s.Stats().UDP.PacketsReceived.Value(), uint64(len(test.expectedPayloads)); got != want { @@ -2840,8 +2867,12 @@ func TestWriteStats(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { + ctx := newTestContext() + defer ctx.cleanup() + ep := iptestutil.NewMockLinkEndpoint(header.IPv4MinimumMTU, &tcpip.ErrInvalidEndpointState{}, test.allowPackets) - rt := buildRoute(t, ep) + defer ep.Close() + rt := buildRoute(t, ctx, ep) test.setup(t, rt.Stack()) nWritten := 0 @@ -2850,6 +2881,7 @@ func TestWriteStats(t *testing.T) { ReserveHeaderBytes: header.UDPMinimumSize + int(rt.MaxHeaderLength()), Data: buffer.NewView(0).ToVectorisedView(), }) + defer pkt.DecRef() pkt.TransportHeader().Push(header.UDPMinimumSize) if err := rt.WritePacket(stack.NetworkHeaderParams{}, pkt); err != nil { break @@ -2873,10 +2905,8 @@ func TestWriteStats(t *testing.T) { } } -func buildRoute(t *testing.T, ep stack.LinkEndpoint) *stack.Route { - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol}, - }) +func buildRoute(t *testing.T, c testContext, ep stack.LinkEndpoint) *stack.Route { + s := c.s if err := s.CreateNIC(1, ep); err != nil { t.Fatalf("CreateNIC(1, _) failed: %s", err) } @@ -2979,9 +3009,11 @@ func TestPacketQueuing(t *testing.T) { DstAddr: host1IPv4Addr.AddressWithPrefix.Address, }) ip.SetChecksum(^ip.CalculateChecksum()) - e.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ + pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: hdr.View().ToVectorisedView(), - })) + }) + defer pkt.DecRef() + e.InjectInbound(ipv4.ProtocolNumber, pkt) }, checkResp: func(t *testing.T, e *channel.Endpoint) { p := e.Read() @@ -3022,9 +3054,11 @@ func TestPacketQueuing(t *testing.T) { DstAddr: host1IPv4Addr.AddressWithPrefix.Address, }) ip.SetChecksum(^ip.CalculateChecksum()) - e.InjectInbound(header.IPv4ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ + echoPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: hdr.View().ToVectorisedView(), - })) + }) + defer echoPkt.DecRef() + e.InjectInbound(header.IPv4ProtocolNumber, echoPkt) }, checkResp: func(t *testing.T, e *channel.Endpoint) { p := e.Read() @@ -3049,15 +3083,13 @@ func TestPacketQueuing(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { + ctx := newTestContext() + defer ctx.cleanup() + s := ctx.s + clock := ctx.clock + e := channel.New(1, defaultMTU, host1NICLinkAddr) e.LinkEPCapabilities |= stack.CapabilityResolutionRequired - clock := faketime.NewManualClock() - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, - Clock: clock, - }) - if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err) } @@ -3114,9 +3146,11 @@ func TestPacketQueuing(t *testing.T) { copy(packet.ProtocolAddressSender(), host2IPv4Addr.AddressWithPrefix.Address) copy(packet.HardwareAddressTarget(), host1NICLinkAddr) copy(packet.ProtocolAddressTarget(), host1IPv4Addr.AddressWithPrefix.Address) - e.InjectInbound(arp.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ + pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: hdr.ToVectorisedView(), - })) + }) + e.InjectInbound(arp.ProtocolNumber, pkt) + pkt.DecRef() } // Expect the response now that the link address has resolved. @@ -3146,10 +3180,9 @@ func TestCloseLocking(t *testing.T) { dst = testutil.MustParse4("16.0.0.2") ) - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, - }) + ctx := newTestContext() + defer ctx.cleanup() + s := ctx.s // Perform NAT so that the endpoint tries to search for a sibling endpoint // which ends up taking the protocol and endpoint lock (in that order). @@ -3269,15 +3302,14 @@ func TestIcmpRateLimit(t *testing.T) { }, } ) + ctx := newTestContext() + defer ctx.cleanup() + s := ctx.s + const icmpBurst = 5 - e := channel.New(1, defaultMTU, tcpip.LinkAddress("")) - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, - Clock: faketime.NewManualClock(), - }) s.SetICMPBurst(icmpBurst) + e := channel.New(1, defaultMTU, tcpip.LinkAddress("")) if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err) } @@ -3379,9 +3411,11 @@ func TestIcmpRateLimit(t *testing.T) { for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { for round := 0; round < icmpBurst+1; round++ { - e.InjectInbound(header.IPv4ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ + pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: testCase.createPacket().ToVectorisedView(), - })) + }) + e.InjectInbound(header.IPv4ProtocolNumber, pkt) + pkt.DecRef() testCase.check(t, e, round) } }) diff --git a/pkg/tcpip/network/ipv4/main_test.go b/pkg/tcpip/network/ipv4/main_test.go new file mode 100644 index 000000000..33d605f95 --- /dev/null +++ b/pkg/tcpip/network/ipv4/main_test.go @@ -0,0 +1,30 @@ +// Copyright 2022 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ipv4_test + +import ( + "os" + "testing" + + "gvisor.dev/gvisor/pkg/refs" + "gvisor.dev/gvisor/pkg/refsvfs2" +) + +func TestMain(m *testing.M) { + refs.SetLeakMode(refs.LeaksPanic) + code := m.Run() + refsvfs2.DoLeakCheck() + os.Exit(code) +} diff --git a/pkg/tcpip/network/ipv4/stats_test.go b/pkg/tcpip/network/ipv4/stats_test.go index c968c47c6..0d25999d4 100644 --- a/pkg/tcpip/network/ipv4/stats_test.go +++ b/pkg/tcpip/network/ipv4/stats_test.go @@ -45,10 +45,27 @@ func knownNICIDs(proto *protocol) []tcpip.NICID { return nicIDs } -func TestClearEndpointFromProtocolOnClose(t *testing.T) { +type statsTestContext struct { + s *stack.Stack +} + +func newStatsTestContext() statsTestContext { s := stack.New(stack.Options{ NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol}, }) + return statsTestContext{s: s} +} + +func (ctx statsTestContext) cleanup() { + ctx.s.Close() + ctx.s.Wait() +} + +func TestClearEndpointFromProtocolOnClose(t *testing.T) { + ctx := newStatsTestContext() + defer ctx.cleanup() + s := ctx.s + proto := s.NetworkProtocolInstance(ProtocolNumber).(*protocol) nic := testInterface{nicID: 1} ep := proto.NewEndpoint(&nic, nil).(*endpoint) @@ -78,9 +95,10 @@ func TestClearEndpointFromProtocolOnClose(t *testing.T) { } func TestMultiCounterStatsInitialization(t *testing.T) { - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol}, - }) + ctx := newStatsTestContext() + defer ctx.cleanup() + s := ctx.s + proto := s.NetworkProtocolInstance(ProtocolNumber).(*protocol) var nic testInterface ep := proto.NewEndpoint(&nic, nil).(*endpoint)