mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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:
@@ -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++
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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,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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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:]
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user