diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 682978d63..44567ad8f 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -43,14 +43,19 @@ type NotificationHandle struct { type queue struct { // c is the outbound packet channel. - c chan *stack.PacketBuffer - // mu protects fields below. - mu sync.RWMutex + c chan *stack.PacketBuffer + mu sync.RWMutex + // +checklocks:mu notify []*NotificationHandle + // +checklocks:mu + closed bool } func (q *queue) Close() { + q.mu.Lock() + defer q.mu.Unlock() close(q.c) + q.closed = true } func (q *queue) Read() *stack.PacketBuffer { @@ -71,36 +76,33 @@ func (q *queue) ReadContext(ctx context.Context) *stack.PacketBuffer { } } -func (q *queue) Write(pkt *stack.PacketBuffer) bool { +func (q *queue) Write(pkt *stack.PacketBuffer) tcpip.Error { // q holds the PacketBuffer. + q.mu.RLock() + if q.closed { + q.mu.RUnlock() + return &tcpip.ErrClosedForSend{} + } - // Ideally, Write() should take a reference here, since it is adding - // the underlying PacketBuffer to the channel. However, in practice, - // calls to Read() are not necessarily symetric with calls - // to Write() (e.g writing to this endpoint and then exiting). This - // causes tests and analyzers to detect erroneous "leaks" for expected - // behavior. To prevent this, we allow the refcount to go to zero, and - // make a call to PreserveObject(), which prevents the PacketBuffer - // pooling implementation from reclaiming this instance, even when - // the refcount goes to zero. - pkt.PreserveObject() + pkt.IncRef() wrote := false select { case q.c <- pkt: wrote = true default: + pkt.DecRef() } - q.mu.Lock() notify := q.notify - q.mu.Unlock() + q.mu.RUnlock() if wrote { // Send notification outside of lock. for _, h := range notify { h.n.WriteNotify() } + return nil } - return wrote + return &tcpip.ErrNoBufferSpace{} } func (q *queue) Num() int { @@ -155,10 +157,11 @@ func New(size int, mtu uint32, linkAddr tcpip.LinkAddress) *Endpoint { } } -// Close closes e. Further packet injections will panic. Reads continue to -// succeed until all packets are read. +// Close closes e. Further packet injections will return an error, and all pending +// packets are discarded. Close may be called concurrently with WritePackets. func (e *Endpoint) Close() { e.q.Close() + e.Drain() } // Read does non-blocking read one packet from the outbound packet queue. @@ -175,7 +178,8 @@ func (e *Endpoint) ReadContext(ctx context.Context) *stack.PacketBuffer { // Drain removes all outbound packets from the channel and counts them. func (e *Endpoint) Drain() int { c := 0 - for e.Read() != nil { + for pkt := e.Read(); pkt != nil; pkt = e.Read() { + pkt.DecRef() c++ } return c @@ -235,10 +239,14 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { } // WritePackets stores outbound packets into the channel. +// Multiple concurrent calls are permitted. func (e *Endpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) { n := 0 for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() { - if !e.q.Write(pkt) { + if err := e.q.Write(pkt); err != nil { + if _, ok := err.(*tcpip.ErrNoBufferSpace); !ok && n == 0 { + return 0, err + } break } n++ diff --git a/pkg/tcpip/link/ethernet/ethernet_test.go b/pkg/tcpip/link/ethernet/ethernet_test.go index 126ac4f2d..b0a1ea7c3 100644 --- a/pkg/tcpip/link/ethernet/ethernet_test.go +++ b/pkg/tcpip/link/ethernet/ethernet_test.go @@ -151,6 +151,7 @@ func TestWritePacketToRemoteAddHeader(t *testing.T) { } eth := header.Ethernet(pkt.LinkHeader().View()) + pkt.DecRef() if got := eth.SourceAddress(); got != localLinkAddr { t.Errorf("got eth.SourceAddress() = %s, want = %s", got, localLinkAddr) } diff --git a/pkg/tcpip/link/tun/device.go b/pkg/tcpip/link/tun/device.go index 2fce32669..8c32037b9 100644 --- a/pkg/tcpip/link/tun/device.go +++ b/pkg/tcpip/link/tun/device.go @@ -260,6 +260,7 @@ func (d *Device) Read() ([]byte, error) { } v, ok := d.encodePkt(pkt) + pkt.DecRef() if !ok { // Ignore unsupported packet. continue @@ -339,6 +340,7 @@ type tunEndpoint struct { // DecRef decrements refcount of e, removing NIC if it reaches 0. func (e *tunEndpoint) DecRef(ctx context.Context) { e.tunEndpointRefs.DecRef(func() { + e.Close() e.stack.RemoveNIC(e.nicID) }) } diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go index b5950d39b..c074285f8 100644 --- a/pkg/tcpip/network/arp/arp_test.go +++ b/pkg/tcpip/network/arp/arp_test.go @@ -349,6 +349,7 @@ func TestDirectRequest(t *testing.T) { t.Fatalf("expected %d, got network protocol number %d", want, got) } rep := header.ARP(pi.NetworkHeader().View()) + pi.DecRef() if !rep.IsValid() { t.Fatalf("invalid ARP response: len = %d; response = %x", len(rep), rep) } @@ -631,6 +632,7 @@ func TestLinkAddressRequest(t *testing.T) { } rep := header.ARP(stack.PayloadSince(pkt.NetworkHeader())) + pkt.DecRef() if got := rep.Op(); got != header.ARPRequest { t.Errorf("got Op = %d, want = %d", got, header.ARPRequest) } @@ -687,6 +689,7 @@ func TestDADARPRequestPacket(t *testing.T) { } req := header.ARP(stack.PayloadSince(pkt.NetworkHeader())) + pkt.DecRef() if !req.IsValid() { t.Errorf("got req.IsValid() = false, want = true") } diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 85b75401b..29db0a86c 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "gvisor.dev/gvisor/pkg/refsvfs2" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/buffer" @@ -238,6 +239,7 @@ func newTestContext() testContext { func (ctx *testContext) cleanup() { ctx.s.Close() ctx.s.Wait() + refsvfs2.DoRepeatedLeakCheck() } func buildIPv4Route(ctx testContext, local, remote tcpip.Address) (*stack.Route, tcpip.Error) { @@ -485,6 +487,7 @@ func TestSourceAddressValidation(t *testing.T) { s := ctx.s e := addLinkEndpointToStack(t, s) + defer e.Close() test.rxICMP(e, test.srcAddress) var wantValid uint64 @@ -1733,6 +1736,7 @@ func TestWriteHeaderIncludedPacket(t *testing.T) { }() e := channel.New(1, header.IPv6MinimumMTU, "") + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err) } @@ -1772,6 +1776,7 @@ func TestWriteHeaderIncludedPacket(t *testing.T) { t.Fatal("expected a packet to be written") } test.checker(t, pkt, subTest.srcAddr) + pkt.DecRef() }) } }) @@ -1999,6 +2004,7 @@ func TestICMPInclusionSize(t *testing.T) { s := ctx.s e := addLinkEndpointToStackWithMTU(t, s, test.linkMTU) + defer e.Close() // Allocate and initialize the payload view. payload := buffer.NewView(test.payloadLength) for i := 0; i < len(payload); i++ { @@ -2025,6 +2031,7 @@ func TestICMPInclusionSize(t *testing.T) { t.Fatalf("got %d bytes of icmp error packet, want %d", got, want) } test.checker(t, pkt, v) + pkt.DecRef() }) } } diff --git a/pkg/tcpip/network/ipv4/igmp_test.go b/pkg/tcpip/network/ipv4/igmp_test.go index 652ab1cbd..de627e3a7 100644 --- a/pkg/tcpip/network/ipv4/igmp_test.go +++ b/pkg/tcpip/network/ipv4/igmp_test.go @@ -18,6 +18,7 @@ import ( "testing" "time" + "gvisor.dev/gvisor/pkg/refsvfs2" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/checker" @@ -72,6 +73,8 @@ type igmpTestContext struct { func (ctx igmpTestContext) cleanup() { ctx.s.Close() ctx.s.Wait() + ctx.ep.Close() + refsvfs2.DoRepeatedLeakCheck() } func newIGMPTestContext(t *testing.T, igmpEnabled bool) igmpTestContext { @@ -164,6 +167,7 @@ func TestIGMPV1Present(t *testing.T) { t.Fatalf("got V2MembershipReport messages sent = %d, want = 1", got) } validateIgmpPacket(t, p, header.IGMPv2MembershipReport, 0, stackAddr, multicastAddr, multicastAddr) + p.DecRef() } if t.Failed() { t.FailNow() @@ -199,6 +203,7 @@ func TestIGMPV1Present(t *testing.T) { t.Fatalf("got V1MembershipReport messages sent = %d, want = 1", got) } validateIgmpPacket(t, p, header.IGMPv1MembershipReport, 0, stackAddr, multicastAddr, multicastAddr) + p.DecRef() } // Cycling the interface should reset the V1 present flag. @@ -217,6 +222,7 @@ func TestIGMPV1Present(t *testing.T) { t.Fatalf("got V2MembershipReport messages sent = %d, want = 2", got) } validateIgmpPacket(t, p, header.IGMPv2MembershipReport, 0, stackAddr, multicastAddr, multicastAddr) + p.DecRef() } } @@ -260,6 +266,7 @@ func TestSendQueuedIGMPReports(t *testing.T) { t.Error("expected to send an IGMP membership report") } else { validateIgmpPacket(t, p, header.IGMPv2MembershipReport, 0, stackAddr, multicastAddr, multicastAddr) + p.DecRef() } if t.Failed() { t.FailNow() @@ -272,6 +279,7 @@ func TestSendQueuedIGMPReports(t *testing.T) { t.Error("expected to send an IGMP membership report") } else { validateIgmpPacket(t, p, header.IGMPv2MembershipReport, 0, stackAddr, multicastAddr, multicastAddr) + p.DecRef() } if t.Failed() { t.FailNow() diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go index 7b6ecfd09..d3c576da7 100644 --- a/pkg/tcpip/network/ipv4/ipv4_test.go +++ b/pkg/tcpip/network/ipv4/ipv4_test.go @@ -25,6 +25,7 @@ import ( "time" "github.com/google/go-cmp/cmp" + "gvisor.dev/gvisor/pkg/refsvfs2" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/buffer" @@ -69,6 +70,7 @@ func newTestContext() testContext { func (ctx testContext) cleanup() { ctx.s.Close() ctx.s.Wait() + refsvfs2.DoRepeatedLeakCheck() } func TestExcludeBroadcast(t *testing.T) { @@ -76,7 +78,9 @@ func TestExcludeBroadcast(t *testing.T) { defer ctx.cleanup() s := ctx.s - ep := stack.LinkEndpoint(channel.New(256, defaultMTU, "")) + ch := channel.New(256, defaultMTU, "") + defer ch.Close() + ep := stack.LinkEndpoint(ch) if testing.Verbose() { ep = sniffer.New(ep) } @@ -373,6 +377,7 @@ func TestForwarding(t *testing.T) { // We expect at most a single packet in response to our ICMP Echo Request. incomingEndpoint := channel.New(1, test.mtu, "") + defer incomingEndpoint.Close() if err := s.CreateNIC(incomingNICID, incomingEndpoint); err != nil { t.Fatalf("CreateNIC(%d, _): %s", incomingNICID, err) } @@ -386,6 +391,7 @@ func TestForwarding(t *testing.T) { expectedEmittedPacketCount = len(test.expectedFragmentsForwarded) } outgoingEndpoint := channel.New(expectedEmittedPacketCount, test.mtu, outgoingLinkAddr) + defer outgoingEndpoint.Close() if err := s.CreateNIC(outgoingNICID, outgoingEndpoint); err != nil { t.Fatalf("CreateNIC(%d, _): %s", outgoingNICID, err) } @@ -479,6 +485,7 @@ func TestForwarding(t *testing.T) { checker.ICMPv4Payload(hdr.View()[:expectedICMPPayloadLength()]), ), ) + reply.DecRef() } else if reply != nil { t.Fatalf("expected no ICMP packet through incoming NIC, instead found: %#v", reply) } @@ -505,6 +512,9 @@ func TestForwarding(t *testing.T) { if err := compareFragments(fragmentedPackets, requestPkt, test.mtu, test.expectedFragmentsForwarded, header.ICMPv4ProtocolNumber, true /* withIPHeader */, expectedAvailableHeaderBytes); err != nil { t.Error(err) } + for _, pkt := range fragmentedPackets { + pkt.DecRef() + } } else { reply := outgoingEndpoint.Read() if reply == nil { @@ -523,6 +533,7 @@ func TestForwarding(t *testing.T) { checker.ICMPv4Payload(nil), ), ) + reply.DecRef() } } else { if reply := outgoingEndpoint.Read(); reply != nil { @@ -1200,6 +1211,7 @@ func TestIPv4Sanity(t *testing.T) { // We expect at most a single packet in response to our ICMP Echo Request. e := channel.New(1, ipv4.MaxTotalSize, "") + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _): %s", nicID, err) } @@ -1280,6 +1292,7 @@ func TestIPv4Sanity(t *testing.T) { } t.Fatal("expected ICMP echo reply missing") } + defer reply.DecRef() // We didn't expect a packet. Register our surprise but carry on to // provide more information about what we got. @@ -1957,6 +1970,7 @@ func TestInvalidFragments(t *testing.T) { s := ctx.s e := channel.New(0, 1500, linkAddr) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } @@ -2186,6 +2200,7 @@ func TestFragmentReassemblyTimeout(t *testing.T) { clock := ctx.clock e := channel.New(1, 1500, linkAddr) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } @@ -2255,6 +2270,7 @@ func TestFragmentReassemblyTimeout(t *testing.T) { checker.ICMPv4Payload(firstFragmentSent), ), ) + reply.DecRef() }) } } @@ -2655,6 +2671,7 @@ func TestReceiveFragments(t *testing.T) { s := ctx.s e := channel.New(0, 1280, "\xf0\x00") + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } @@ -3020,6 +3037,7 @@ func TestPacketQueuing(t *testing.T) { if p == nil { t.Fatalf("timed out waiting for packet") } + defer p.DecRef() if p.NetworkProtocolNumber != header.IPv4ProtocolNumber { t.Errorf("got p.NetworkProtocolNumber = %d, want = %d", p.NetworkProtocolNumber, header.IPv4ProtocolNumber) } @@ -3065,6 +3083,7 @@ func TestPacketQueuing(t *testing.T) { if p == nil { t.Fatalf("timed out waiting for packet") } + defer p.DecRef() if p.NetworkProtocolNumber != header.IPv4ProtocolNumber { t.Errorf("got p.NetworkProtocolNumber = %d, want = %d", p.NetworkProtocolNumber, header.IPv4ProtocolNumber) } @@ -3089,6 +3108,7 @@ func TestPacketQueuing(t *testing.T) { clock := ctx.clock e := channel.New(1, defaultMTU, host1NICLinkAddr) + defer e.Close() e.LinkEPCapabilities |= stack.CapabilityResolutionRequired if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err) @@ -3122,6 +3142,7 @@ func TestPacketQueuing(t *testing.T) { t.Errorf("got p.EgressRoute.RemoteLinkAddress = %s, want = %s", p.EgressRoute.RemoteLinkAddress, header.EthernetBroadcastAddress) } rep := header.ARP(p.NetworkHeader().View()) + p.DecRef() if got := rep.Op(); got != header.ARPRequest { t.Errorf("got Op() = %d, want = %d", got, header.ARPRequest) } @@ -3212,6 +3233,7 @@ func TestCloseLocking(t *testing.T) { s.IPTables().ReplaceTable(stack.NATID, table, false /* ipv6 */) e := channel.New(0, defaultMTU, "") + defer e.Close() if err := s.CreateNIC(nicID1, e); err != nil { t.Fatalf("CreateNIC(%d, _): %s", nicID1, err) } @@ -3273,7 +3295,9 @@ func TestCloseLocking(t *testing.T) { defer wg.Done() for i := 0; i < iterations; i++ { - if err := s.CreateNIC(nicID2, stack.LinkEndpoint(channel.New(0, defaultMTU, ""))); err != nil { + ch := channel.New(0, defaultMTU, "") + defer ch.Close() + if err := s.CreateNIC(nicID2, ch); err != nil { t.Errorf("CreateNIC(%d, _): %s", nicID2, err) return } @@ -3310,6 +3334,7 @@ func TestIcmpRateLimit(t *testing.T) { s.SetICMPBurst(icmpBurst) e := channel.New(1, defaultMTU, tcpip.LinkAddress("")) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err) } @@ -3355,6 +3380,7 @@ func TestIcmpRateLimit(t *testing.T) { if p == nil { t.Fatalf("expected echo response, no packet read in endpoint in round %d", round) } + defer p.DecRef() if got, want := p.NetworkProtocolNumber, header.IPv4ProtocolNumber; got != want { t.Errorf("got p.NetworkProtocolNumber = %d, want = %d", got, want) } @@ -3393,12 +3419,14 @@ func TestIcmpRateLimit(t *testing.T) { if round >= icmpBurst { if p != nil { t.Errorf("got packet %x in round %d, expected ICMP rate limit to stop it", p.Data().Views(), round) + p.DecRef() } return } if p == nil { t.Fatalf("expected unreachable in round %d, no packet read in endpoint", round) } + defer p.DecRef() checker.IPv4(t, stack.PayloadSince(p.NetworkHeader()), checker.SrcAddr(host1IPv4Addr.AddressWithPrefix.Address), checker.DstAddr(host2IPv4Addr.AddressWithPrefix.Address), diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go index e0b5e03f6..a3b28cd11 100644 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -23,6 +23,7 @@ import ( "github.com/google/go-cmp/cmp" "golang.org/x/time/rate" + "gvisor.dev/gvisor/pkg/refsvfs2" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/checker" @@ -198,25 +199,32 @@ func handleICMPInIPv6(ep stack.NetworkEndpoint, src, dst tcpip.Address, icmp hea } type testContext struct { - s *stack.Stack + s *stack.Stack + clock *faketime.ManualClock } -func newTestContext(clock tcpip.Clock) testContext { +func newTestContext() testContext { + clock := faketime.NewManualClock() s := stack.New(stack.Options{ NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol}, TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol6, udp.NewProtocol}, Clock: clock, }) - return testContext{s: s} + return testContext{s: s, clock: clock} } func (c *testContext) cleanup() { c.s.Close() c.s.Wait() + // Stack.Wait() closes all devices and transports synchronously, but it + // does not guarantee that all packets will reach refcount zero until + // after an asynchronous followup from neighborEntry.notifyCompletionLocked(). + c.clock.RunImmediatelyScheduledJobs() + refsvfs2.DoRepeatedLeakCheck() } func TestICMPCounts(t *testing.T) { - c := newTestContext(nil) + c := newTestContext() defer c.cleanup() s := c.s @@ -514,6 +522,7 @@ func routeICMPv6Packet(t *testing.T, clock *faketime.ManualClock, args routeArgs if pi == nil { t.Fatal("packet didn't arrive") } + defer pi.DecRef() { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ @@ -716,7 +725,7 @@ func TestICMPChecksumValidationSimple(t *testing.T) { name += " (Router)" } t.Run(name, func(t *testing.T) { - c := newTestContext(nil) + c := newTestContext() defer c.cleanup() s := c.s @@ -925,11 +934,12 @@ func TestICMPChecksumValidationWithPayload(t *testing.T) { for _, typ := range types { t.Run(typ.name, func(t *testing.T) { - c := newTestContext(nil) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(10, 1280, linkAddr0) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(_, _) = %s", err) } @@ -1113,11 +1123,12 @@ func TestICMPChecksumValidationWithPayloadMultipleViews(t *testing.T) { for _, typ := range types { t.Run(typ.name, func(t *testing.T) { - c := newTestContext(nil) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(10, 1280, linkAddr0) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } @@ -1283,7 +1294,7 @@ func TestLinkAddressRequest(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil) + c := newTestContext() defer c.cleanup() s := c.s @@ -1326,6 +1337,7 @@ func TestLinkAddressRequest(t *testing.T) { if pkt == nil { t.Fatal("expected to send a link address request") } + defer pkt.DecRef() var want stack.RouteInfo want.NetProto = ProtocolNumber @@ -1407,6 +1419,7 @@ func TestPacketQueing(t *testing.T) { if p == nil { t.Fatalf("timed out waiting for packet") } + defer p.DecRef() if p.NetworkProtocolNumber != ProtocolNumber { t.Errorf("got p.NetworkProtocolNumber = %d, want = %d", p.NetworkProtocolNumber, ProtocolNumber) } @@ -1455,6 +1468,7 @@ func TestPacketQueing(t *testing.T) { if p == nil { t.Fatalf("timed out waiting for packet") } + defer p.DecRef() if p.NetworkProtocolNumber != ProtocolNumber { t.Errorf("got p.NetworkProtocolNumber = %d, want = %d", p.NetworkProtocolNumber, ProtocolNumber) } @@ -1473,8 +1487,7 @@ func TestPacketQueing(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - clock := faketime.NewManualClock() - c := newTestContext(clock) + c := newTestContext() defer c.cleanup() s := c.s @@ -1503,7 +1516,7 @@ func TestPacketQueing(t *testing.T) { // Wait for a neighbor solicitation since link address resolution should // be performed. { - clock.RunImmediatelyScheduledJobs() + c.clock.RunImmediatelyScheduledJobs() p := e.Read() if p == nil { t.Fatalf("timed out waiting for packet") @@ -1523,6 +1536,7 @@ func TestPacketQueing(t *testing.T) { checker.NDPNSTargetAddress(host2IPv6Addr.AddressWithPrefix.Address), checker.NDPNSOptions([]header.NDPOption{header.NDPSourceLinkLayerAddressOption(host1NICLinkAddr)}), )) + p.DecRef() } // Send a neighbor advertisement to complete link address resolution. @@ -1560,7 +1574,7 @@ func TestPacketQueing(t *testing.T) { } // Expect the response now that the link address has resolved. - clock.RunImmediatelyScheduledJobs() + c.clock.RunImmediatelyScheduledJobs() test.checkResp(t, e) // Since link resolution was already performed, it shouldn't be performed @@ -1734,7 +1748,7 @@ func TestCallsToNeighborCache(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil) + c := newTestContext() defer c.cleanup() s := c.s diff --git a/pkg/tcpip/network/ipv6/ipv6_test.go b/pkg/tcpip/network/ipv6/ipv6_test.go index 99962b29e..499d41ead 100644 --- a/pkg/tcpip/network/ipv6/ipv6_test.go +++ b/pkg/tcpip/network/ipv6/ipv6_test.go @@ -28,7 +28,6 @@ import ( "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/checker" - "gvisor.dev/gvisor/pkg/tcpip/faketime" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/link/channel" iptestutil "gvisor.dev/gvisor/pkg/tcpip/network/internal/testutil" @@ -247,11 +246,12 @@ func TestReceiveOnAllNodesMulticastAddr(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(10, header.IPv6MinimumMTU, linkAddr1) + defer e.Close() if err := s.CreateNIC(1, e); err != nil { t.Fatalf("CreateNIC(_) = %s", err) } @@ -279,11 +279,12 @@ func TestReceiveOnSolicitedNodeAddr(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(1, header.IPv6MinimumMTU, linkAddr1) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } @@ -376,7 +377,7 @@ func TestAddIpv6Address(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s @@ -904,11 +905,12 @@ func TestReceiveIPv6ExtHdrs(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(1, header.IPv6MinimumMTU, linkAddr1) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } @@ -1031,6 +1033,7 @@ func TestReceiveIPv6ExtHdrs(t *testing.T) { // Pack the output packet into a single buffer.View as the checkers // assume that. vv := buffer.NewVectorisedView(p.Size(), p.Views()) + p.DecRef() pkt := vv.ToView() if got, want := len(pkt), header.IPv6FixedHeaderSize+header.ICMPv6MinimumSize+hdr.UsedLength(); got != want { t.Fatalf("got an ICMP packet of size = %d, want = %d", got, want) @@ -2003,11 +2006,12 @@ func TestReceiveIPv6Fragments(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(0, header.IPv6MinimumMTU, linkAddr1) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } @@ -2165,11 +2169,12 @@ func TestInvalidIPv6Fragments(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(1, 1500, linkAddr1) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } @@ -2238,6 +2243,7 @@ func TestInvalidIPv6Fragments(t *testing.T) { checker.ICMPv6Payload(expectICMPPayload), ), ) + reply.DecRef() }) } } @@ -2418,12 +2424,12 @@ func TestFragmentReassemblyTimeout(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - clock := faketime.NewManualClock() - c := newTestContext(clock) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(1, 1500, linkAddr1) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) } @@ -2465,7 +2471,7 @@ func TestFragmentReassemblyTimeout(t *testing.T) { pkt.DecRef() } - clock.Advance(ReassembleTimeout) + c.clock.Advance(ReassembleTimeout) reply := e.Read() if !test.expectICMP { @@ -2491,6 +2497,7 @@ func TestFragmentReassemblyTimeout(t *testing.T) { checker.ICMPv6Payload(firstFragmentSent), ), ) + reply.DecRef() }) } } @@ -2599,7 +2606,7 @@ func TestWriteStats(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() ep := iptestutil.NewMockLinkEndpoint(header.IPv6MinimumMTU, &tcpip.ErrInvalidEndpointState{}, test.allowPackets) @@ -2703,7 +2710,7 @@ func knownNICIDs(proto *protocol) []tcpip.NICID { } func TestClearEndpointFromProtocolOnClose(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s @@ -2802,7 +2809,7 @@ func TestFragmentationWritePacket(t *testing.T) { for _, ft := range fragmentationTests { t.Run(ft.description, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() pkt := iptestutil.MakeRandPkt(ft.transHdrLen, extraHeaderReserve+header.IPv6MinimumSize, []int{ft.payloadSize}, header.IPv6ProtocolNumber) @@ -2907,7 +2914,7 @@ func TestFragmentationErrors(t *testing.T) { for _, ft := range tests { t.Run(ft.description, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() pkt := iptestutil.MakeRandPkt(ft.transHdrLen, extraHeaderReserve+header.IPv6MinimumSize, []int{ft.payloadSize}, header.IPv6ProtocolNumber) @@ -3224,12 +3231,13 @@ func TestForwarding(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s // We expect at most a single packet in response to our ICMP Echo Request. incomingEndpoint := channel.New(1, header.IPv6MinimumMTU, "") + defer incomingEndpoint.Close() if err := s.CreateNIC(incomingNICID, incomingEndpoint); err != nil { t.Fatalf("CreateNIC(%d, _): %s", incomingNICID, err) } @@ -3239,6 +3247,7 @@ func TestForwarding(t *testing.T) { } outgoingEndpoint := channel.New(1, header.IPv6MinimumMTU, "") + defer outgoingEndpoint.Close() if err := s.CreateNIC(outgoingNICID, outgoingEndpoint); err != nil { t.Fatalf("CreateNIC(%d, _): %s", outgoingNICID, err) } @@ -3339,6 +3348,7 @@ func TestForwarding(t *testing.T) { checker.ICMPv6Payload(hdr.View()[:expectedICMPPayloadLength()]), ), ) + reply.DecRef() if n := outgoingEndpoint.Drain(); n != 0 { t.Fatalf("got e2.Drain() = %d, want = 0", n) @@ -3364,6 +3374,7 @@ func TestForwarding(t *testing.T) { checker.ICMPv6Payload(nil), ), ) + reply.DecRef() if n := incomingEndpoint.Drain(); n != 0 { t.Fatalf("got e1.Drain() = %d, want = 0", n) @@ -3411,7 +3422,7 @@ func TestForwarding(t *testing.T) { } func TestMultiCounterStatsInitialization(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s @@ -3455,13 +3466,14 @@ func TestIcmpRateLimit(t *testing.T) { ) const icmpBurst = 5 - c := newTestContext(faketime.NewManualClock()) + c := newTestContext() defer c.cleanup() s := c.s s.SetICMPBurst(icmpBurst) e := channel.New(1, defaultMTU, tcpip.LinkAddress("")) + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err) } @@ -3511,6 +3523,7 @@ func TestIcmpRateLimit(t *testing.T) { if p == nil { t.Fatalf("expected echo response, no packet read in endpoint in round %d", round) } + defer p.DecRef() if got, want := p.NetworkProtocolNumber, header.IPv6ProtocolNumber; got != want { t.Errorf("got p.NetworkProtocolNumber = %d, want = %d", got, want) } @@ -3555,6 +3568,7 @@ func TestIcmpRateLimit(t *testing.T) { if round >= icmpBurst { if p != nil { t.Errorf("got packet %x in round %d, expected ICMP rate limit to stop it", p.Data().Views(), round) + p.DecRef() } return } @@ -3567,6 +3581,7 @@ func TestIcmpRateLimit(t *testing.T) { checker.ICMPv6( checker.ICMPv6Type(header.ICMPv6DstUnreachable), )) + p.DecRef() }, }, } diff --git a/pkg/tcpip/network/ipv6/mld_test.go b/pkg/tcpip/network/ipv6/mld_test.go index 7130a06d6..9baa63f82 100644 --- a/pkg/tcpip/network/ipv6/mld_test.go +++ b/pkg/tcpip/network/ipv6/mld_test.go @@ -88,6 +88,7 @@ func TestIPv6JoinLeaveSolicitedNodeAddressPerformsMLD(t *testing.T) { s := c.s e := channel.New(1, header.IPv6MinimumMTU, "") + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _): %s", nicID, err) } @@ -106,6 +107,7 @@ func TestIPv6JoinLeaveSolicitedNodeAddressPerformsMLD(t *testing.T) { t.Fatal("expected a report message to be sent") } else { validateMLDPacket(t, stack.PayloadSince(p.NetworkHeader()), linkLocalAddr, linkLocalAddrSNMC, header.ICMPv6MulticastListenerReport, linkLocalAddrSNMC) + p.DecRef() } // The stack will leave an address's solicited node multicast address when @@ -118,6 +120,7 @@ func TestIPv6JoinLeaveSolicitedNodeAddressPerformsMLD(t *testing.T) { t.Fatal("expected a done message to be sent") } else { validateMLDPacket(t, stack.PayloadSince(p.NetworkHeader()), header.IPv6Any, header.IPv6AllRoutersLinkLocalMulticastAddress, header.ICMPv6MulticastListenerDone, linkLocalAddrSNMC) + p.DecRef() } } @@ -176,10 +179,6 @@ func TestSendQueuedMLDReports(t *testing.T) { })}, Clock: clock, }) - defer func() { - s.Close() - s.Wait() - }() // Allow space for an extra packet so we can observe packets that were // unexpectedly sent. @@ -188,6 +187,12 @@ func TestSendQueuedMLDReports(t *testing.T) { t.Fatalf("CreateNIC(%d, _): %s", nicID, err) } + defer func() { + s.Close() + s.Wait() + e.Close() + }() + resolveDAD := func(addr, snmc tcpip.Address) { clock.Advance(dadResolutionTime) if p := e.Read(); p == nil { @@ -201,6 +206,7 @@ func TestSendQueuedMLDReports(t *testing.T) { checker.NDPNSTargetAddress(addr), checker.NDPNSOptions([]header.NDPOption{header.NDPNonceOption(nonce[:])}), )) + p.DecRef() } } @@ -228,10 +234,12 @@ func TestSendQueuedMLDReports(t *testing.T) { t.Errorf("expected MLD report for %s", globalMulticastAddr) } else { validateMLDPacket(t, stack.PayloadSince(p.NetworkHeader()), header.IPv6Any, globalMulticastAddr, header.ICMPv6MulticastListenerReport, globalMulticastAddr) + p.DecRef() } clock.Advance(time.Hour) if p := e.Read(); p != nil { t.Errorf("got unexpected packet = %#v", p) + p.DecRef() } if t.Failed() { t.FailNow() @@ -260,6 +268,7 @@ func TestSendQueuedMLDReports(t *testing.T) { t.Errorf("expected MLD report for %s", globalAddrSNMC) } else { validateMLDPacket(t, stack.PayloadSince(p.NetworkHeader()), header.IPv6Any, globalAddrSNMC, header.ICMPv6MulticastListenerReport, globalAddrSNMC) + p.DecRef() } if dadResolutionTime != 0 { // Reports should not be sent when the address resolves. @@ -278,6 +287,7 @@ func TestSendQueuedMLDReports(t *testing.T) { } if p := e.Read(); p != nil { t.Errorf("got unexpected packet = %#v", p) + p.DecRef() } if t.Failed() { t.FailNow() @@ -301,6 +311,7 @@ func TestSendQueuedMLDReports(t *testing.T) { t.Errorf("expected MLD report for %s", linkLocalAddrSNMC) } else { validateMLDPacket(t, stack.PayloadSince(p.NetworkHeader()), header.IPv6Any, linkLocalAddrSNMC, header.ICMPv6MulticastListenerReport, linkLocalAddrSNMC) + p.DecRef() } resolveDAD(linkLocalAddr, linkLocalAddrSNMC) } @@ -335,6 +346,7 @@ func TestSendQueuedMLDReports(t *testing.T) { addrs[addr] = true validateMLDPacket(t, stack.PayloadSince(p.NetworkHeader()), linkLocalAddr, addr, header.ICMPv6MulticastListenerReport, addr) + p.DecRef() clock.Advance(ipv6.UnsolicitedReportIntervalMax) } @@ -344,6 +356,7 @@ func TestSendQueuedMLDReports(t *testing.T) { clock.Advance(time.Hour) if p := e.Read(); p != nil { t.Errorf("got unexpected packet = %#v", p) + p.DecRef() } }) } @@ -464,7 +477,8 @@ func TestMLDPacketValidation(t *testing.T) { defer c.cleanup() s := c.s - e := channel.New(nicID, header.IPv6MinimumMTU, "") + e := channel.New(1, header.IPv6MinimumMTU, "") + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _): %s", nicID, err) } @@ -509,7 +523,7 @@ func TestMLDSkipProtocol(t *testing.T) { expectReport bool }{ { - name: "Reserverd0", + name: "Reserved0", group: "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11", expectReport: false, }, @@ -593,13 +607,16 @@ func TestMLDSkipProtocol(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { c := newMLDTestContext() - defer c.cleanup() s := c.s e := channel.New(1, header.IPv6MinimumMTU, "") if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _): %s", nicID, err) } + + defer e.Close() + defer c.cleanup() + protocolAddr := tcpip.ProtocolAddress{ Protocol: ipv6.ProtocolNumber, AddressWithPrefix: linkLocalAddr.WithPrefix(), @@ -611,6 +628,7 @@ func TestMLDSkipProtocol(t *testing.T) { t.Fatal("expected a report message to be sent") } else { validateMLDPacket(t, stack.PayloadSince(p.NetworkHeader()), linkLocalAddr, linkLocalAddrSNMC, header.ICMPv6MulticastListenerReport, linkLocalAddrSNMC) + p.DecRef() } if err := s.JoinGroup(ipv6.ProtocolNumber, nicID, test.group); err != nil { @@ -634,6 +652,7 @@ func TestMLDSkipProtocol(t *testing.T) { t.Fatal("expected a report message to be sent") } else { validateMLDPacket(t, stack.PayloadSince(p.NetworkHeader()), linkLocalAddr, test.group, header.ICMPv6MulticastListenerReport, test.group) + p.DecRef() } }) } diff --git a/pkg/tcpip/network/ipv6/ndp_test.go b/pkg/tcpip/network/ipv6/ndp_test.go index fdcef0fa8..cdd1939a8 100644 --- a/pkg/tcpip/network/ipv6/ndp_test.go +++ b/pkg/tcpip/network/ipv6/ndp_test.go @@ -137,11 +137,12 @@ func TestNeighborSolicitationWithSourceLinkLayerOption(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(0, 1280, linkAddr0) + defer e.Close() e.LinkEPCapabilities |= stack.CapabilityResolutionRequired if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) @@ -391,12 +392,12 @@ func TestNeighborSolicitationResponse(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - clock := faketime.NewManualClock() - c := newTestContext(clock) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(1, 1280, nicLinkAddr) + defer e.Close() e.LinkEPCapabilities |= stack.CapabilityResolutionRequired if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) @@ -470,7 +471,7 @@ func TestNeighborSolicitationResponse(t *testing.T) { } if test.performsLinkResolution { - clock.RunImmediatelyScheduledJobs() + c.clock.RunImmediatelyScheduledJobs() p := e.Read() if p == nil { t.Fatal("expected an NDP NS response") @@ -495,6 +496,7 @@ func TestNeighborSolicitationResponse(t *testing.T) { header.NDPSourceLinkLayerAddressOption(nicLinkAddr), }), )) + p.DecRef() ser := header.NDPOptionsSerializer{ header.NDPTargetLinkLayerAddressOption(linkAddr1), @@ -529,11 +531,12 @@ func TestNeighborSolicitationResponse(t *testing.T) { pktBuf.DecRef() } - clock.RunImmediatelyScheduledJobs() + c.clock.RunImmediatelyScheduledJobs() p := e.Read() if p == nil { t.Fatal("expected an NDP NA response") } + defer p.DecRef() if p.EgressRoute.LocalAddress != test.naSrc { t.Errorf("got p.EgressRoute.LocalAddress = %s, want = %s", p.EgressRoute.LocalAddress, test.naSrc) @@ -598,11 +601,12 @@ func TestNeighborAdvertisementWithTargetLinkLayerOption(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(0, 1280, linkAddr0) + defer e.Close() e.LinkEPCapabilities |= stack.CapabilityResolutionRequired if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) @@ -828,7 +832,7 @@ func TestNDPValidation(t *testing.T) { t.Run(name, func(t *testing.T) { for _, test := range subTests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s @@ -969,11 +973,12 @@ func TestNeighborAdvertisementValidation(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(0, header.IPv6MinimumMTU, linkAddr0) + defer e.Close() e.LinkEPCapabilities |= stack.CapabilityResolutionRequired if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) @@ -1177,11 +1182,12 @@ func TestRouterAdvertValidation(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := newTestContext(nil /* clock */) + c := newTestContext() defer c.cleanup() s := c.s e := channel.New(10, 1280, linkAddr1) + defer e.Close() e.LinkEPCapabilities |= stack.CapabilityResolutionRequired if err := s.CreateNIC(1, e); err != nil { t.Fatalf("CreateNIC(_) = %s", err) @@ -1280,6 +1286,7 @@ func TestCheckDuplicateAddress(t *testing.T) { // This test is expected to send at max 2 DAD messages. We allow an extra // packet to be stored to catch unexpected packets. e := channel.New(3, header.IPv6MinimumMTU, linkAddr0) + defer e.Close() e.LinkEPCapabilities |= stack.CapabilityResolutionRequired if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) @@ -1294,6 +1301,7 @@ func TestCheckDuplicateAddress(t *testing.T) { if p == nil { t.Fatalf("expected %d-th DAD message", dadPacketsSent) } + defer p.DecRef() if p.NetworkProtocolNumber != header.IPv6ProtocolNumber { t.Errorf("(i=%d) got p.NetworkProtocolNumber = %d, want = %d", dadPacketsSent, p.NetworkProtocolNumber, header.IPv6ProtocolNumber) diff --git a/pkg/tcpip/network/multicast_group_test.go b/pkg/tcpip/network/multicast_group_test.go index a69a53dec..263c2bb77 100644 --- a/pkg/tcpip/network/multicast_group_test.go +++ b/pkg/tcpip/network/multicast_group_test.go @@ -20,6 +20,7 @@ import ( "testing" "time" + "gvisor.dev/gvisor/pkg/refsvfs2" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/checker" @@ -139,6 +140,8 @@ func newMulticastTestContext(t *testing.T, v4, mgpEnabled bool) multicastTestCon func (ctx *multicastTestContext) cleanup() { ctx.s.Close() ctx.s.Wait() + ctx.e.Close() + refsvfs2.DoRepeatedLeakCheck() } func createStackWithLinkEndpoint(t *testing.T, v4, mgpEnabled bool, e stack.LinkEndpoint) (*stack.Stack, *faketime.ManualClock) { @@ -206,6 +209,7 @@ func checkInitialIPv6Groups(t *testing.T, e *channel.Endpoint, s *stack.Stack, c t.Fatal("expected a report message to be sent") } else { validateMLDPacket(t, p, ipv6AddrSNMC, mldReport, 0, ipv6AddrSNMC) + p.DecRef() } // Leave the group to not affect the tests. This is fine since we are not @@ -221,6 +225,7 @@ func checkInitialIPv6Groups(t *testing.T, e *channel.Endpoint, s *stack.Stack, c t.Fatal("expected a report message to be sent") } else { validateMLDPacket(t, p, header.IPv6AllRoutersLinkLocalMulticastAddress, mldDone, 0, ipv6AddrSNMC) + p.DecRef() } // Should not send any more packets. @@ -560,6 +565,7 @@ func TestMGPJoinGroup(t *testing.T) { t.Fatal("expected a report message to be sent") } else { test.validateReport(t, p) + p.DecRef() } if t.Failed() { t.FailNow() @@ -580,6 +586,7 @@ func TestMGPJoinGroup(t *testing.T) { t.Fatal("expected a report message to be sent") } else { test.validateReport(t, p) + p.DecRef() } // Should not send any more packets. @@ -672,6 +679,7 @@ func TestMGPLeaveGroup(t *testing.T) { t.Fatal("expected a report message to be sent") } else { test.validateReport(t, p) + p.DecRef() } if t.Failed() { t.FailNow() @@ -689,6 +697,7 @@ func TestMGPLeaveGroup(t *testing.T) { t.Fatal("expected a leave message to be sent") } else { test.validateLeave(t, p) + p.DecRef() } // Should not send any more packets. @@ -815,6 +824,7 @@ func TestMGPQueryMessages(t *testing.T) { t.Fatalf("expected %d-th report message to be sent", i) } else { test.validateReport(t, p) + p.DecRef() } clock.Advance(test.maxUnsolicitedResponseDelay) } @@ -847,6 +857,7 @@ func TestMGPQueryMessages(t *testing.T) { t.Fatal("expected a report message to be sent") } else { test.validateReport(t, p) + p.DecRef() } } @@ -944,6 +955,7 @@ func TestMGPReportMessages(t *testing.T) { t.Fatal("expected a report message to be sent") } else { test.validateReport(t, p) + p.DecRef() } if t.Failed() { t.FailNow() @@ -1131,6 +1143,7 @@ func TestMGPWithNICLifecycle(t *testing.T) { t.Fatalf("expected a report message to be sent for %s", a) } else { test.validateReport(t, p, a) + p.DecRef() } } if t.Failed() { @@ -1160,6 +1173,7 @@ func TestMGPWithNICLifecycle(t *testing.T) { } test.validateLeave(t, p, test.getAndCheckGroupAddress(t, seen, p)) + p.DecRef() } } if t.Failed() { @@ -1187,6 +1201,7 @@ func TestMGPWithNICLifecycle(t *testing.T) { } test.validateReport(t, p, test.getAndCheckGroupAddress(t, seen, p)) + p.DecRef() } } if t.Failed() { @@ -1202,8 +1217,10 @@ func TestMGPWithNICLifecycle(t *testing.T) { t.Errorf("got sentLeaveStat.Value() = %d, want = %d", got, leaveCounter) } for i := range test.multicastAddrs { - if e.Read() == nil { + if p := e.Read(); p == nil { t.Fatalf("expected (%d-th) leave message to be sent", i) + } else { + p.DecRef() } } for _, a := range test.multicastAddrs { @@ -1240,6 +1257,7 @@ func TestMGPWithNICLifecycle(t *testing.T) { t.Fatal("expected a report message to be sent") } else { test.validateReport(t, p, test.finalMulticastAddr) + p.DecRef() } clock.Advance(test.maxUnsolicitedResponseDelay) @@ -1251,6 +1269,7 @@ func TestMGPWithNICLifecycle(t *testing.T) { t.Fatal("expected a report message to be sent") } else { test.validateReport(t, p, test.finalMulticastAddr) + p.DecRef() } // Should not send any more packets. diff --git a/pkg/tcpip/stack/ndp_test.go b/pkg/tcpip/stack/ndp_test.go index d07731f2a..ee86baa75 100644 --- a/pkg/tcpip/stack/ndp_test.go +++ b/pkg/tcpip/stack/ndp_test.go @@ -643,6 +643,7 @@ func TestDADResolve(t *testing.T) { if l, want := p.AvailableHeaderBytes(), int(test.linkHeaderLen); l != want { t.Errorf("got p.AvailableHeaderBytes() = %d; want = %d", l, want) } + p.DecRef() } }) } @@ -1323,6 +1324,7 @@ func TestDynamicConfigurationsDisabled(t *testing.T) { t.Error("expected router solicitation packet") } else if p.NetworkProtocolNumber != header.IPv6ProtocolNumber { t.Errorf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber) + p.DecRef() } else { if want := header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllRoutersLinkLocalMulticastAddress); p.EgressRoute.RemoteLinkAddress != want { t.Errorf("got remote link address = %s, want = %s", p.EgressRoute.RemoteLinkAddress, want) @@ -1334,6 +1336,7 @@ func TestDynamicConfigurationsDisabled(t *testing.T) { checker.TTL(header.NDPHopLimit), checker.NDPRS(checker.NDPRSOptions(nil)), ) + p.DecRef() } // Make sure we do not discover any routers or prefixes, or perform @@ -5352,6 +5355,7 @@ func TestRouterSolicitation(t *testing.T) { if p == nil { t.Fatal("expected router solicitation packet") } + defer p.DecRef() if p.NetworkProtocolNumber != header.IPv6ProtocolNumber { t.Fatalf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber) @@ -5551,6 +5555,7 @@ func TestStopStartSolicitingRouters(t *testing.T) { checker.DstAddr(header.IPv6AllRoutersLinkLocalMulticastAddress), checker.TTL(header.NDPHopLimit), checker.NDPRS()) + p.DecRef() } clock := faketime.NewManualClock() s := stack.New(stack.Options{ @@ -5571,7 +5576,8 @@ func TestStopStartSolicitingRouters(t *testing.T) { // Stop soliciting routers. test.stopFn(t, s, true /* first */) clock.Advance(delay) - if e.Read() != nil { + if p := e.Read(); p != nil { + p.DecRef() // A single RS may have been sent before solicitations were stopped. clock.Advance(interval) if e.Read() != nil { diff --git a/pkg/tcpip/stack/packet_buffer.go b/pkg/tcpip/stack/packet_buffer.go index 52fb18759..8e5293568 100644 --- a/pkg/tcpip/stack/packet_buffer.go +++ b/pkg/tcpip/stack/packet_buffer.go @@ -64,7 +64,9 @@ type PacketBufferOptions struct { // LinkHeader, NetworkHeader, TransportHeader, and Data. Any of them can be // empty. Use of PacketBuffer in any other order is unsupported. // -// PacketBuffer must be created with NewPacketBuffer. +// PacketBuffer must be created with NewPacketBuffer, which sets the initial +// reference count to 1. Owners should call `DecRef()` when they are finished +// with the buffer to return it to the pool. // // Internal structure: A PacketBuffer holds a pointer to buffer.Buffer, which // exposes a logically-contiguous byte storage. The underlying storage structure @@ -161,8 +163,6 @@ type PacketBuffer struct { NetworkPacketInfo NetworkPacketInfo tuple *tuple - - preserveObject bool } // NewPacketBuffer creates a new PacketBuffer with opts. @@ -183,18 +183,12 @@ func NewPacketBuffer(opts PacketBufferOptions) *PacketBuffer { return pk } -// PreserveObject marks this PacketBuffer so it is not recycled by internal -// pooling. -func (pk *PacketBuffer) PreserveObject() { - pk.preserveObject = true -} - // DecRef decrements the PacketBuffer's refcount. If the refcount is // decremented to zero, the PacketBuffer is returned to the PacketBuffer // pool. func (pk *PacketBuffer) DecRef() { pk.packetBufferRefs.DecRef(func() { - if pk.packetBufferRefs.refCount == 0 && !pk.preserveObject { + if pk.packetBufferRefs.refCount == 0 { pkPool.Put(pk) } }) diff --git a/pkg/tcpip/stack/pending_packets.go b/pkg/tcpip/stack/pending_packets.go index 3584da448..e51bd9343 100644 --- a/pkg/tcpip/stack/pending_packets.go +++ b/pkg/tcpip/stack/pending_packets.go @@ -152,6 +152,7 @@ func (f *packetsPendingLinkResolution) enqueue(r *Route, pkt *PacketBuffer) tcpi if len(packets) > maxPendingPacketsPerResolution { f.incrementOutgoingPacketErrors(packets[0].pkt) + packets[0].pkt.DecRef() packets[0] = pendingPacket{} packets = packets[1:] diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 992f418e2..763260c9b 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -4612,6 +4612,7 @@ func TestFindRouteWithForwarding(t *testing.T) { if pkt == nil { t.Fatal("packet not sent through ep2") } + defer pkt.DecRef() if pkt.EgressRoute.LocalAddress != test.localAddrWithPrefix.Address { t.Errorf("got pkt.EgressRoute.LocalAddress = %s, want = %s", pkt.EgressRoute.LocalAddress, test.localAddrWithPrefix.Address) } @@ -4755,6 +4756,7 @@ func TestWritePacketToRemote(t *testing.T) { if got, want := pkt != nil, true; got != want { t.Fatalf("e.Read() = %t, want %t", got, want) } + defer pkt.DecRef() if got, want := pkt.NetworkProtocolNumber, test.protocol; got != want { t.Fatalf("pkt.NetworkProtocolNumber = %d, want %d", got, want) } diff --git a/pkg/tcpip/tests/integration/forward_test.go b/pkg/tcpip/tests/integration/forward_test.go index 4fc9f1c24..89b468641 100644 --- a/pkg/tcpip/tests/integration/forward_test.go +++ b/pkg/tcpip/tests/integration/forward_test.go @@ -464,11 +464,13 @@ func TestMulticastForwarding(t *testing.T) { }) e1 := channel.New(1, header.IPv6MinimumMTU, "") + defer e1.Close() if err := s.CreateNIC(nicID1, e1); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID1, err) } e2 := channel.New(1, header.IPv6MinimumMTU, "") + defer e2.Close() if err := s.CreateNIC(nicID2, e2); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID2, err) } @@ -515,6 +517,7 @@ func TestMulticastForwarding(t *testing.T) { if test.expectForward { test.checker(t, stack.PayloadSince(p.NetworkHeader())) + p.DecRef() } }) } @@ -590,11 +593,13 @@ func TestPerInterfaceForwarding(t *testing.T) { }) e1 := channel.New(1, header.IPv6MinimumMTU, "") + defer e1.Close() if err := s.CreateNIC(nicID1, e1); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID1, err) } e2 := channel.New(1, header.IPv6MinimumMTU, "") + defer e2.Close() if err := s.CreateNIC(nicID2, e2); err != nil { t.Fatalf("s.CreateNIC(%d, _): %s", nicID2, err) } @@ -685,11 +690,15 @@ func TestPerInterfaceForwarding(t *testing.T) { test.rx(subTest.nicEP, test.srcAddr, test.dstAddr) if p := subTest.nicEP.Read(); p != nil { t.Errorf("unexpectedly got a response from the interface the packet arrived on: %#v", p) + p.DecRef() } - if p := subTest.otherNICEP.Read(); (p != nil) != subTest.expectForwarding { + p := subTest.otherNICEP.Read() + if (p != nil) != subTest.expectForwarding { t.Errorf("got otherNICEP.Read() = (%#v, %t), want = (_, %t)", p, ok, subTest.expectForwarding) - } else if subTest.expectForwarding { + } + if p != nil { test.checker(t, stack.PayloadSince(p.NetworkHeader())) + p.DecRef() } }) } diff --git a/pkg/tcpip/tests/integration/iptables_test.go b/pkg/tcpip/tests/integration/iptables_test.go index dc480c11d..c7286d57e 100644 --- a/pkg/tcpip/tests/integration/iptables_test.go +++ b/pkg/tcpip/tests/integration/iptables_test.go @@ -942,6 +942,7 @@ func TestForwardingHook(t *testing.T) { } if expectTransmitPacket { test.checker(t, stack.PayloadSince(p.NetworkHeader())) + p.DecRef() } }) } @@ -1174,13 +1175,17 @@ func TestFilteringEchoPacketsWithLocalForwarding(t *testing.T) { } expectPacket := subTest.expectResult == noneDropped - if p := e1.Read(); (p != nil) != expectPacket { + p := e1.Read() + if (p != nil) != expectPacket { t.Errorf("got e1.Read() = %#v, want = (_ == nil) = %t", p, expectPacket) - } else if expectPacket { + } + if p != nil { test.checker(t, stack.PayloadSince(p.NetworkHeader())) + p.DecRef() } if p := e2.Read(); p != nil { t.Errorf("got e1.Read() = %#v, want = nil)", p) + p.DecRef() } }) } @@ -1530,6 +1535,7 @@ func TestNATEcho(t *testing.T) { t.Fatal("expected to read a packet on ep1") } test.checkEchoPkt(t, stack.PayloadSince(pkt.NetworkHeader()), natTypeTest.expectedRequestSrc, natTypeTest.expectedRequestDst, false /* reply */) + pkt.DecRef() } if t.Failed() { @@ -1546,6 +1552,7 @@ func TestNATEcho(t *testing.T) { t.Fatal("expected to read a packet on ep2") } test.checkEchoPkt(t, stack.PayloadSince(pkt.NetworkHeader()), natTypeTest.requestDst, natTypeTest.requestSrc, true /* reply */) + pkt.DecRef() } }) } @@ -2511,6 +2518,7 @@ func TestNATICMPError(t *testing.T) { t.Fatal("expected to read a packet on ep1") } pktView := stack.PayloadSince(pkt.NetworkHeader()) + pkt.DecRef() transportType.checkNATed(t, pktView) if t.Failed() { t.FailNow() @@ -2534,6 +2542,7 @@ func TestNATICMPError(t *testing.T) { } test.decrementTTL(buf) test.checkNATedError(t, stack.PayloadSince(pkt.NetworkHeader()), buf, icmpType.val) + pkt.DecRef() }) } }) @@ -2875,6 +2884,7 @@ func TestSNATHandlePortOrIdentConflicts(t *testing.T) { t.Fatal("expected to read a packet on ep1") } pktView := stack.PayloadSince(pkt.NetworkHeader()) + pkt.DecRef() transportType.checkNATed(t, pktView, srcPortOrIdent, i == 0, srcPortOrIdentRange.targetRange) }) } @@ -3287,6 +3297,7 @@ func TestRejectWith(t *testing.T) { rejectWith.errorICMPCode, natHook.errorICMPPayload, ) + pkt.DecRef() } }) } diff --git a/pkg/tcpip/tests/integration/link_resolution_test.go b/pkg/tcpip/tests/integration/link_resolution_test.go index b6dd8db27..974bee0a6 100644 --- a/pkg/tcpip/tests/integration/link_resolution_test.go +++ b/pkg/tcpip/tests/integration/link_resolution_test.go @@ -619,6 +619,7 @@ func TestForwardingWithLinkResolutionFailure(t *testing.T) { } test.linkResolutionRequestChecker(t, request, test.outgoingAddr.Address, test.destAddr) + request.DecRef() // Advance the clock the span of one request timeout. clock.Advance(nudConfigs.RetransmitTimer) @@ -634,6 +635,7 @@ func TestForwardingWithLinkResolutionFailure(t *testing.T) { } test.icmpReplyChecker(t, stack.PayloadSince(reply.NetworkHeader()), test.incomingAddr.Address, test.sourceAddr) + reply.DecRef() // Since link resolution failed, we don't expect the packet to be // forwarded. diff --git a/pkg/tcpip/tests/integration/multicast_broadcast_test.go b/pkg/tcpip/tests/integration/multicast_broadcast_test.go index b01de2d0c..e6f80e667 100644 --- a/pkg/tcpip/tests/integration/multicast_broadcast_test.go +++ b/pkg/tcpip/tests/integration/multicast_broadcast_test.go @@ -115,6 +115,7 @@ func TestPingMulticastBroadcast(t *testing.T) { }) // We only expect a single packet in response to our ICMP Echo Request. e := channel.New(1, defaultMTU, "") + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _): %s", nicID, err) } @@ -145,6 +146,7 @@ func TestPingMulticastBroadcast(t *testing.T) { if pkt == nil { t.Fatal("expected ICMP response") } + defer pkt.DecRef() if pkt.EgressRoute.LocalAddress != test.expectedSrc { t.Errorf("got pkt.EgressRoute.LocalAddress = %s, want = %s", pkt.EgressRoute.LocalAddress, test.expectedSrc) @@ -392,6 +394,7 @@ func TestIncomingMulticastAndBroadcast(t *testing.T) { TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, }) e := channel.New(0, defaultMTU, "") + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _): %s", nicID, err) } @@ -638,6 +641,7 @@ func TestUDPAddRemoveMembershipSocketOption(t *testing.T) { TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, }) e := channel.New(0, defaultMTU, "") + defer e.Close() if err := s.CreateNIC(nicID, e); err != nil { t.Fatalf("CreateNIC(%d, _): %s", nicID, err) } diff --git a/pkg/tcpip/transport/icmp/icmp_test.go b/pkg/tcpip/transport/icmp/icmp_test.go index 050114f0e..ba50e1632 100644 --- a/pkg/tcpip/transport/icmp/icmp_test.go +++ b/pkg/tcpip/transport/icmp/icmp_test.go @@ -145,6 +145,7 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) { } vv := buffer.NewVectorisedView(p.Size(), p.Views()) + p.DecRef() b := vv.ToView() checker.IPv4(t, b, []checker.NetworkChecker{ @@ -192,6 +193,7 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) { } vv := buffer.NewVectorisedView(p.Size(), p.Views()) + p.DecRef() b := vv.ToView() checker.IPv4(t, b, []checker.NetworkChecker{ @@ -229,6 +231,7 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) { } vv := buffer.NewVectorisedView(p.Size(), p.Views()) + p.DecRef() b := vv.ToView() checker.IPv4(t, b, []checker.NetworkChecker{ diff --git a/pkg/tcpip/transport/internal/network/endpoint_test.go b/pkg/tcpip/transport/internal/network/endpoint_test.go index d50ea0dca..e615a11d7 100644 --- a/pkg/tcpip/transport/internal/network/endpoint_test.go +++ b/pkg/tcpip/transport/internal/network/endpoint_test.go @@ -213,6 +213,7 @@ func TestEndpointStateTransitions(t *testing.T) { t.Fatalf("expected packet to be read from link endpoint") } else { test.checker(t, stack.PayloadSince(pkt.NetworkHeader())) + pkt.DecRef() } ep.Close() diff --git a/pkg/tcpip/transport/tcp/test/e2e/tcp_test.go b/pkg/tcpip/transport/tcp/test/e2e/tcp_test.go index 9535a6b59..40f41a5d9 100644 --- a/pkg/tcpip/transport/tcp/test/e2e/tcp_test.go +++ b/pkg/tcpip/transport/tcp/test/e2e/tcp_test.go @@ -8258,6 +8258,7 @@ func TestHandshakeRTT(t *testing.T) { t.Run(fmt.Sprintf("connect=%t,TS=%t,cookie=%t,retrans=%t)", tt.connect, tt.tsEnabled, tt.useCookie, tt.retrans), func(t *testing.T) { t.Parallel() c := context.New(t, e2e.DefaultMTU) + defer c.Cleanup() if tt.useCookie { opt := tcpip.TCPAlwaysUseSynCookies(true) if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil { diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index d2b387faa..e7cbaf7a3 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -282,6 +282,8 @@ func (c *Context) Cleanup() { c.EP.Close() } c.Stack().Close() + c.Stack().Wait() + c.linkEP.Close() } // Stack returns a reference to the stack in the Context. @@ -319,6 +321,7 @@ func (c *Context) GetPacketWithTimeout(timeout time.Duration) []byte { if pkt == nil { return nil } + defer pkt.DecRef() if got, want := pkt.NetworkProtocolNumber, ipv4.ProtocolNumber; got != want { c.t.Fatalf("got pkt.NetworkProtocolNumber = %d, want = %d", got, want) @@ -369,6 +372,7 @@ func (c *Context) GetPacketNonBlocking() []byte { if pkt == nil { return nil } + defer pkt.DecRef() if got, want := pkt.NetworkProtocolNumber, ipv4.ProtocolNumber; got != want { c.t.Fatalf("got pkt.NetworkProtocolNumber = %d, want = %d", got, want) @@ -615,6 +619,7 @@ func (c *Context) GetV6Packet() []byte { c.t.Fatalf("Packet wasn't written out") return nil } + defer pkt.DecRef() if got, want := pkt.NetworkProtocolNumber, ipv6.ProtocolNumber; got != want { c.t.Fatalf("got pkt.NetworkProtocolNumber = %d, want = %d", got, want) diff --git a/pkg/tcpip/transport/testing/context/BUILD b/pkg/tcpip/transport/testing/context/BUILD index e38384d66..f398ff67c 100644 --- a/pkg/tcpip/transport/testing/context/BUILD +++ b/pkg/tcpip/transport/testing/context/BUILD @@ -13,6 +13,7 @@ go_library( "//visibility:public", ], deps = [ + "//pkg/refsvfs2", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/checker", diff --git a/pkg/tcpip/transport/testing/context/context.go b/pkg/tcpip/transport/testing/context/context.go index bece02311..1ece8a94b 100644 --- a/pkg/tcpip/transport/testing/context/context.go +++ b/pkg/tcpip/transport/testing/context/context.go @@ -22,6 +22,7 @@ import ( "github.com/google/go-cmp/cmp" "golang.org/x/time/rate" + "gvisor.dev/gvisor/pkg/refsvfs2" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/checker" @@ -154,6 +155,7 @@ func (c *Context) Cleanup() { if c.EP != nil { c.EP.Close() } + refsvfs2.DoRepeatedLeakCheck() } // CreateEndpoint creates the Context's Endpoint. diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index f4cad9d0a..2a9458009 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -503,6 +503,7 @@ func testWriteAndVerifyInternal(c *context.Context, flow context.TestFlow, setDe if p == nil { c.T.Fatalf("Packet wasn't written out") } + defer p.DecRef() if got, want := p.NetworkProtocolNumber, flow.NetProto(); got != want { c.T.Fatalf("got p.NetworkProtocolNumber = %d, want = %d", got, want) @@ -1374,6 +1375,7 @@ func TestV4UnknownDestination(t *testing.T) { } vv := buffer.NewVectorisedView(p.Size(), p.Views()) + p.DecRef() pkt := vv.ToView() if got, want := len(pkt), header.IPv4MinimumProcessableDatagramSize; got > want { t.Fatalf("got an ICMP packet of size: %d, want: sz <= %d", got, want) @@ -1468,6 +1470,7 @@ func TestV6UnknownDestination(t *testing.T) { } vv := buffer.NewVectorisedView(p.Size(), p.Views()) + p.DecRef() pkt := vv.ToView() if got, want := len(pkt), header.IPv6MinimumMTU; got > want { t.Fatalf("got an ICMP packet of size: %d, want: sz <= %d", got, want) @@ -1903,6 +1906,7 @@ func TestOutgoingSubnetBroadcast(t *testing.T) { Clock: &faketime.NullClock{}, }) e := channel.New(0, context.DefaultMTU, "") + defer e.Close() if err := s.CreateNIC(nicID1, e); err != nil { t.Fatalf("CreateNIC(%d, _): %s", nicID1, err) } @@ -2015,6 +2019,7 @@ func TestChecksumWithZeroValueOnesComplementSum(t *testing.T) { } v := stack.PayloadSince(pkt.NetworkHeader()) + pkt.DecRef() checker.IPv6(t, v, checker.UDP()) // Simply replacing the payload with the checksum value is enough to make @@ -2048,6 +2053,7 @@ func TestChecksumWithZeroValueOnesComplementSum(t *testing.T) { if pkt == nil { t.Fatal("Packet wasn't written out") } + defer pkt.DecRef() v := stack.PayloadSince(pkt.NetworkHeader()) checker.IPv6(t, stack.PayloadSince(pkt.NetworkHeader()), checker.UDP(checker.TransportChecksum(math.MaxUint16)))