Add reference counting for packets in channel.Endpoint

This reduces GC pressure when using a TUN device or similar link.

Updates #6910

PiperOrigin-RevId: 431441991
This commit is contained in:
bemasc
2022-02-28 08:33:36 -08:00
committed by gVisor bot
parent 7f3fdc910f
commit f375784d83
27 changed files with 265 additions and 85 deletions
+29 -21
View File
@@ -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++
+1
View File
@@ -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)
}
+2
View File
@@ -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)
})
}
+3
View File
@@ -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")
}
+7
View File
@@ -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()
})
}
}
+8
View File
@@ -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()
+30 -2
View File
@@ -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),
+27 -13
View File
@@ -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
+32 -17
View File
@@ -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()
},
},
}
+26 -7
View File
@@ -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()
}
})
}
+17 -9
View File
@@ -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)
+20 -1
View File
@@ -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.
+7 -1
View File
@@ -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 {
+4 -10
View File
@@ -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)
}
})
+1
View File
@@ -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:]
+2
View File
@@ -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)
}
+11 -2
View File
@@ -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()
}
})
}
+13 -2
View File
@@ -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()
}
})
}
@@ -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.
@@ -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)
}

Some files were not shown because too many files have changed in this diff Show More