mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Do not hold NIC local address in neighbor entries
Previously, the NIC local address used when completing link resolution was held in the neighbor entry. A neighbor is not identified by any NIC local address so remove it. PiperOrigin-RevId: 338699695
This commit is contained in:
committed by
gVisor bot
parent
5d909dd49c
commit
dad08229b8
@@ -151,7 +151,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, pkt *stack.PacketBuffer) {
|
||||
|
||||
remoteAddr := tcpip.Address(h.ProtocolAddressSender())
|
||||
remoteLinkAddr := tcpip.LinkAddress(h.HardwareAddressSender())
|
||||
e.nud.HandleProbe(remoteAddr, localAddr, ProtocolNumber, remoteLinkAddr, e.protocol)
|
||||
e.nud.HandleProbe(remoteAddr, ProtocolNumber, remoteLinkAddr, e.protocol)
|
||||
}
|
||||
|
||||
respPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||
@@ -208,6 +208,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, pkt *stack.PacketBuffer) {
|
||||
|
||||
// protocol implements stack.NetworkProtocol and stack.LinkAddressResolver.
|
||||
type protocol struct {
|
||||
stack *stack.Stack
|
||||
}
|
||||
|
||||
func (p *protocol) Number() tcpip.NetworkProtocolNumber { return ProtocolNumber }
|
||||
@@ -236,11 +237,27 @@ func (*protocol) LinkAddressProtocol() tcpip.NetworkProtocolNumber {
|
||||
}
|
||||
|
||||
// LinkAddressRequest implements stack.LinkAddressResolver.LinkAddressRequest.
|
||||
func (*protocol) LinkAddressRequest(targetAddr, localAddr tcpip.Address, remoteLinkAddr tcpip.LinkAddress, nic stack.NetworkInterface) *tcpip.Error {
|
||||
func (p *protocol) LinkAddressRequest(targetAddr, localAddr tcpip.Address, remoteLinkAddr tcpip.LinkAddress, nic stack.NetworkInterface) *tcpip.Error {
|
||||
if len(remoteLinkAddr) == 0 {
|
||||
remoteLinkAddr = header.EthernetBroadcastAddress
|
||||
}
|
||||
|
||||
nicID := nic.ID()
|
||||
if len(localAddr) == 0 {
|
||||
addr, err := p.stack.GetMainNICAddress(nicID, header.IPv4ProtocolNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(addr.Address) == 0 {
|
||||
return tcpip.ErrNetworkUnreachable
|
||||
}
|
||||
|
||||
localAddr = addr.Address
|
||||
} else if p.stack.CheckLocalAddress(nicID, header.IPv4ProtocolNumber, localAddr) == 0 {
|
||||
return tcpip.ErrBadLocalAddress
|
||||
}
|
||||
|
||||
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||
ReserveHeaderBytes: int(nic.MaxHeaderLength()) + header.ARPSize,
|
||||
})
|
||||
@@ -297,6 +314,6 @@ func (*protocol) Parse(pkt *stack.PacketBuffer) (proto tcpip.TransportProtocolNu
|
||||
// Note, to make sure that the ARP endpoint receives ARP packets, the "arp"
|
||||
// address must be added to every NIC that should respond to ARP requests. See
|
||||
// ProtocolAddress for more details.
|
||||
func NewProtocol(*stack.Stack) stack.NetworkProtocol {
|
||||
return &protocol{}
|
||||
func NewProtocol(s *stack.Stack) stack.NetworkProtocol {
|
||||
return &protocol{stack: s}
|
||||
}
|
||||
|
||||
@@ -404,9 +404,6 @@ func TestDirectRequestWithNeighborCache(t *testing.T) {
|
||||
if got, want := neigh.LinkAddr, test.senderLinkAddr; got != want {
|
||||
t.Errorf("got neighbor LinkAddr = %s, want = %s", got, want)
|
||||
}
|
||||
if got, want := neigh.LocalAddr, stackAddr; got != want {
|
||||
t.Errorf("got neighbor LocalAddr = %s, want = %s", got, want)
|
||||
}
|
||||
if got, want := neigh.State, stack.Stale; got != want {
|
||||
t.Errorf("got neighbor State = %s, want = %s", got, want)
|
||||
}
|
||||
@@ -427,10 +424,12 @@ var _ stack.NetworkInterface = (*testInterface)(nil)
|
||||
|
||||
type testInterface struct {
|
||||
stack.LinkEndpoint
|
||||
|
||||
nicID tcpip.NICID
|
||||
}
|
||||
|
||||
func (*testInterface) ID() tcpip.NICID {
|
||||
return 1
|
||||
func (t *testInterface) ID() tcpip.NICID {
|
||||
return t.nicID
|
||||
}
|
||||
|
||||
func (*testInterface) IsLoopback() bool {
|
||||
@@ -454,42 +453,131 @@ func (t *testInterface) WritePacketToRemote(remoteLinkAddr tcpip.LinkAddress, gs
|
||||
}
|
||||
|
||||
func TestLinkAddressRequest(t *testing.T) {
|
||||
const nicID = 1
|
||||
|
||||
testAddr := tcpip.Address([]byte{1, 2, 3, 4})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
nicAddr tcpip.Address
|
||||
localAddr tcpip.Address
|
||||
remoteLinkAddr tcpip.LinkAddress
|
||||
expectLinkAddr tcpip.LinkAddress
|
||||
|
||||
expectedErr *tcpip.Error
|
||||
expectedLocalAddr tcpip.Address
|
||||
expectedRemoteLinkAddr tcpip.LinkAddress
|
||||
}{
|
||||
{
|
||||
name: "Unicast",
|
||||
remoteLinkAddr: remoteLinkAddr,
|
||||
expectLinkAddr: remoteLinkAddr,
|
||||
name: "Unicast",
|
||||
nicAddr: stackAddr,
|
||||
localAddr: stackAddr,
|
||||
remoteLinkAddr: remoteLinkAddr,
|
||||
expectedLocalAddr: stackAddr,
|
||||
expectedRemoteLinkAddr: remoteLinkAddr,
|
||||
},
|
||||
{
|
||||
name: "Multicast",
|
||||
name: "Multicast",
|
||||
nicAddr: stackAddr,
|
||||
localAddr: stackAddr,
|
||||
remoteLinkAddr: "",
|
||||
expectedLocalAddr: stackAddr,
|
||||
expectedRemoteLinkAddr: header.EthernetBroadcastAddress,
|
||||
},
|
||||
{
|
||||
name: "Unicast with unspecified source",
|
||||
nicAddr: stackAddr,
|
||||
remoteLinkAddr: remoteLinkAddr,
|
||||
expectedLocalAddr: stackAddr,
|
||||
expectedRemoteLinkAddr: remoteLinkAddr,
|
||||
},
|
||||
{
|
||||
name: "Multicast with unspecified source",
|
||||
nicAddr: stackAddr,
|
||||
remoteLinkAddr: "",
|
||||
expectedLocalAddr: stackAddr,
|
||||
expectedRemoteLinkAddr: header.EthernetBroadcastAddress,
|
||||
},
|
||||
{
|
||||
name: "Unicast with unassigned address",
|
||||
localAddr: testAddr,
|
||||
remoteLinkAddr: remoteLinkAddr,
|
||||
expectedErr: tcpip.ErrBadLocalAddress,
|
||||
},
|
||||
{
|
||||
name: "Multicast with unassigned address",
|
||||
localAddr: testAddr,
|
||||
remoteLinkAddr: "",
|
||||
expectLinkAddr: header.EthernetBroadcastAddress,
|
||||
expectedErr: tcpip.ErrBadLocalAddress,
|
||||
},
|
||||
{
|
||||
name: "Unicast with no local address available",
|
||||
remoteLinkAddr: remoteLinkAddr,
|
||||
expectedErr: tcpip.ErrNetworkUnreachable,
|
||||
},
|
||||
{
|
||||
name: "Multicast with no local address available",
|
||||
remoteLinkAddr: "",
|
||||
expectedErr: tcpip.ErrNetworkUnreachable,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
p := arp.NewProtocol(nil)
|
||||
linkRes, ok := p.(stack.LinkAddressResolver)
|
||||
if !ok {
|
||||
t.Fatal("expected ARP protocol to implement stack.LinkAddressResolver")
|
||||
}
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
s := stack.New(stack.Options{
|
||||
NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol},
|
||||
})
|
||||
p := s.NetworkProtocolInstance(arp.ProtocolNumber)
|
||||
linkRes, ok := p.(stack.LinkAddressResolver)
|
||||
if !ok {
|
||||
t.Fatal("expected ARP protocol to implement stack.LinkAddressResolver")
|
||||
}
|
||||
|
||||
linkEP := channel.New(defaultChannelSize, defaultMTU, stackLinkAddr)
|
||||
if err := linkRes.LinkAddressRequest(stackAddr, remoteAddr, test.remoteLinkAddr, &testInterface{LinkEndpoint: linkEP}); err != nil {
|
||||
t.Errorf("got p.LinkAddressRequest(%s, %s, %s, _) = %s", stackAddr, remoteAddr, test.remoteLinkAddr, err)
|
||||
}
|
||||
linkEP := channel.New(defaultChannelSize, defaultMTU, stackLinkAddr)
|
||||
if err := s.CreateNIC(nicID, linkEP); err != nil {
|
||||
t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
|
||||
}
|
||||
|
||||
pkt, ok := linkEP.Read()
|
||||
if !ok {
|
||||
t.Fatal("expected to send a link address request")
|
||||
}
|
||||
if len(test.nicAddr) != 0 {
|
||||
if err := s.AddAddress(nicID, ipv4.ProtocolNumber, test.nicAddr); err != nil {
|
||||
t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, ipv4.ProtocolNumber, test.nicAddr, err)
|
||||
}
|
||||
}
|
||||
|
||||
if got, want := pkt.Route.RemoteLinkAddress, test.expectLinkAddr; got != want {
|
||||
t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", got, want)
|
||||
}
|
||||
// We pass a test network interface to LinkAddressRequest with the same
|
||||
// NIC ID and link endpoint used by the NIC we created earlier so that we
|
||||
// can mock a link address request and observe the packets sent to the
|
||||
// link endpoint even though the stack uses the real NIC to validate the
|
||||
// local address.
|
||||
if err := linkRes.LinkAddressRequest(remoteAddr, test.localAddr, test.remoteLinkAddr, &testInterface{LinkEndpoint: linkEP, nicID: nicID}); err != test.expectedErr {
|
||||
t.Fatalf("got p.LinkAddressRequest(%s, %s, %s, _) = %s, want = %s", remoteAddr, test.localAddr, test.remoteLinkAddr, err, test.expectedErr)
|
||||
}
|
||||
|
||||
if test.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
pkt, ok := linkEP.Read()
|
||||
if !ok {
|
||||
t.Fatal("expected to send a link address request")
|
||||
}
|
||||
|
||||
if pkt.Route.RemoteLinkAddress != test.expectedRemoteLinkAddr {
|
||||
t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, test.expectedRemoteLinkAddr)
|
||||
}
|
||||
|
||||
rep := header.ARP(stack.PayloadSince(pkt.Pkt.NetworkHeader()))
|
||||
if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != stackLinkAddr {
|
||||
t.Errorf("got HardwareAddressSender = %s, want = %s", got, stackLinkAddr)
|
||||
}
|
||||
if got := tcpip.Address(rep.ProtocolAddressSender()); got != test.expectedLocalAddr {
|
||||
t.Errorf("got ProtocolAddressSender = %s, want = %s", got, test.expectedLocalAddr)
|
||||
}
|
||||
if got, want := tcpip.LinkAddress(rep.HardwareAddressTarget()), tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"); got != want {
|
||||
t.Errorf("got HardwareAddressTarget = %s, want = %s", got, want)
|
||||
}
|
||||
if got := tcpip.Address(rep.ProtocolAddressTarget()); got != remoteAddr {
|
||||
t.Errorf("got ProtocolAddressTarget = %s, want = %s", got, remoteAddr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ func (e *endpoint) handleICMP(r *stack.Route, pkt *stack.PacketBuffer, hasFragme
|
||||
received.Invalid.Increment()
|
||||
return
|
||||
} else if e.nud != nil {
|
||||
e.nud.HandleProbe(r.RemoteAddress, r.LocalAddress, header.IPv6ProtocolNumber, sourceLinkAddr, e.protocol)
|
||||
e.nud.HandleProbe(r.RemoteAddress, header.IPv6ProtocolNumber, sourceLinkAddr, e.protocol)
|
||||
} else {
|
||||
e.linkAddrCache.AddLinkAddress(e.nic.ID(), r.RemoteAddress, sourceLinkAddr)
|
||||
}
|
||||
@@ -558,7 +558,7 @@ func (e *endpoint) handleICMP(r *stack.Route, pkt *stack.PacketBuffer, hasFragme
|
||||
if e.nud != nil {
|
||||
// A RS with a specified source IP address modifies the NUD state
|
||||
// machine in the same way a reachability probe would.
|
||||
e.nud.HandleProbe(r.RemoteAddress, r.LocalAddress, header.IPv6ProtocolNumber, sourceLinkAddr, e.protocol)
|
||||
e.nud.HandleProbe(r.RemoteAddress, header.IPv6ProtocolNumber, sourceLinkAddr, e.protocol)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,7 +608,7 @@ func (e *endpoint) handleICMP(r *stack.Route, pkt *stack.PacketBuffer, hasFragme
|
||||
// If the RA has the source link layer option, update the link address
|
||||
// cache with the link address for the advertised router.
|
||||
if len(sourceLinkAddr) != 0 && e.nud != nil {
|
||||
e.nud.HandleProbe(routerAddr, r.LocalAddress, header.IPv6ProtocolNumber, sourceLinkAddr, e.protocol)
|
||||
e.nud.HandleProbe(routerAddr, header.IPv6ProtocolNumber, sourceLinkAddr, e.protocol)
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
|
||||
@@ -51,6 +51,7 @@ const (
|
||||
var (
|
||||
lladdr0 = header.LinkLocalAddr(linkAddr0)
|
||||
lladdr1 = header.LinkLocalAddr(linkAddr1)
|
||||
lladdr2 = header.LinkLocalAddr(linkAddr2)
|
||||
)
|
||||
|
||||
type stubLinkEndpoint struct {
|
||||
@@ -108,15 +109,15 @@ type stubNUDHandler struct {
|
||||
|
||||
var _ stack.NUDHandler = (*stubNUDHandler)(nil)
|
||||
|
||||
func (s *stubNUDHandler) HandleProbe(remoteAddr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, linkRes stack.LinkAddressResolver) {
|
||||
func (s *stubNUDHandler) HandleProbe(tcpip.Address, tcpip.NetworkProtocolNumber, tcpip.LinkAddress, stack.LinkAddressResolver) {
|
||||
s.probeCount++
|
||||
}
|
||||
|
||||
func (s *stubNUDHandler) HandleConfirmation(addr tcpip.Address, linkAddr tcpip.LinkAddress, flags stack.ReachabilityConfirmationFlags) {
|
||||
func (s *stubNUDHandler) HandleConfirmation(tcpip.Address, tcpip.LinkAddress, stack.ReachabilityConfirmationFlags) {
|
||||
s.confirmationCount++
|
||||
}
|
||||
|
||||
func (*stubNUDHandler) HandleUpperLevelConfirmation(addr tcpip.Address) {
|
||||
func (*stubNUDHandler) HandleUpperLevelConfirmation(tcpip.Address) {
|
||||
}
|
||||
|
||||
var _ stack.NetworkInterface = (*testInterface)(nil)
|
||||
@@ -1245,22 +1246,66 @@ func TestLinkAddressRequest(t *testing.T) {
|
||||
mcaddr := header.EthernetAddressFromMulticastIPv6Address(snaddr)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
remoteLinkAddr tcpip.LinkAddress
|
||||
expectedLinkAddr tcpip.LinkAddress
|
||||
expectedAddr tcpip.Address
|
||||
name string
|
||||
nicAddr tcpip.Address
|
||||
localAddr tcpip.Address
|
||||
remoteLinkAddr tcpip.LinkAddress
|
||||
|
||||
expectedErr *tcpip.Error
|
||||
expectedRemoteAddr tcpip.Address
|
||||
expectedRemoteLinkAddr tcpip.LinkAddress
|
||||
}{
|
||||
{
|
||||
name: "Unicast",
|
||||
remoteLinkAddr: linkAddr1,
|
||||
expectedLinkAddr: linkAddr1,
|
||||
expectedAddr: lladdr0,
|
||||
name: "Unicast",
|
||||
nicAddr: lladdr1,
|
||||
localAddr: lladdr1,
|
||||
remoteLinkAddr: linkAddr1,
|
||||
expectedRemoteAddr: lladdr0,
|
||||
expectedRemoteLinkAddr: linkAddr1,
|
||||
},
|
||||
{
|
||||
name: "Multicast",
|
||||
remoteLinkAddr: "",
|
||||
expectedLinkAddr: mcaddr,
|
||||
expectedAddr: snaddr,
|
||||
name: "Multicast",
|
||||
nicAddr: lladdr1,
|
||||
localAddr: lladdr1,
|
||||
remoteLinkAddr: "",
|
||||
expectedRemoteAddr: snaddr,
|
||||
expectedRemoteLinkAddr: mcaddr,
|
||||
},
|
||||
{
|
||||
name: "Unicast with unspecified source",
|
||||
nicAddr: lladdr1,
|
||||
remoteLinkAddr: linkAddr1,
|
||||
expectedRemoteAddr: lladdr0,
|
||||
expectedRemoteLinkAddr: linkAddr1,
|
||||
},
|
||||
{
|
||||
name: "Multicast with unspecified source",
|
||||
nicAddr: lladdr1,
|
||||
remoteLinkAddr: "",
|
||||
expectedRemoteAddr: snaddr,
|
||||
expectedRemoteLinkAddr: mcaddr,
|
||||
},
|
||||
{
|
||||
name: "Unicast with unassigned address",
|
||||
localAddr: lladdr1,
|
||||
remoteLinkAddr: linkAddr1,
|
||||
expectedErr: tcpip.ErrNetworkUnreachable,
|
||||
},
|
||||
{
|
||||
name: "Multicast with unassigned address",
|
||||
localAddr: lladdr1,
|
||||
remoteLinkAddr: "",
|
||||
expectedErr: tcpip.ErrNetworkUnreachable,
|
||||
},
|
||||
{
|
||||
name: "Unicast with no local address available",
|
||||
remoteLinkAddr: linkAddr1,
|
||||
expectedErr: tcpip.ErrNetworkUnreachable,
|
||||
},
|
||||
{
|
||||
name: "Multicast with no local address available",
|
||||
remoteLinkAddr: "",
|
||||
expectedErr: tcpip.ErrNetworkUnreachable,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1278,34 +1323,40 @@ func TestLinkAddressRequest(t *testing.T) {
|
||||
if err := s.CreateNIC(nicID, linkEP); err != nil {
|
||||
t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
|
||||
}
|
||||
if err := s.AddAddress(nicID, ProtocolNumber, lladdr1); err != nil {
|
||||
t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, ProtocolNumber, lladdr1, err)
|
||||
if len(test.nicAddr) != 0 {
|
||||
if err := s.AddAddress(nicID, ProtocolNumber, test.nicAddr); err != nil {
|
||||
t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, ProtocolNumber, test.nicAddr, err)
|
||||
}
|
||||
}
|
||||
|
||||
// We pass a test network interface to LinkAddressRequest with the same NIC
|
||||
// ID and link endpoint used by the NIC we created earlier so that we can
|
||||
// mock a link address request and observe the packets sent to the link
|
||||
// endpoint even though the stack uses the real NIC.
|
||||
if err := linkRes.LinkAddressRequest(lladdr0, lladdr1, test.remoteLinkAddr, &testInterface{LinkEndpoint: linkEP, nicID: nicID}); err != nil {
|
||||
t.Errorf("got p.LinkAddressRequest(%s, %s, %s, _) = %s", lladdr0, lladdr1, test.remoteLinkAddr, err)
|
||||
if err := linkRes.LinkAddressRequest(lladdr0, test.localAddr, test.remoteLinkAddr, &testInterface{LinkEndpoint: linkEP, nicID: nicID}); err != test.expectedErr {
|
||||
t.Errorf("got p.LinkAddressRequest(%s, %s, %s, _) = %s, want = %s", lladdr0, test.localAddr, test.remoteLinkAddr, err, test.expectedErr)
|
||||
}
|
||||
|
||||
if test.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
pkt, ok := linkEP.Read()
|
||||
if !ok {
|
||||
t.Fatal("expected to send a link address request")
|
||||
}
|
||||
if pkt.Route.RemoteLinkAddress != test.expectedLinkAddr {
|
||||
t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, test.expectedLinkAddr)
|
||||
if pkt.Route.RemoteLinkAddress != test.expectedRemoteLinkAddr {
|
||||
t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, test.expectedRemoteLinkAddr)
|
||||
}
|
||||
if pkt.Route.RemoteAddress != test.expectedAddr {
|
||||
t.Errorf("got pkt.Route.RemoteAddress = %s, want = %s", pkt.Route.RemoteAddress, test.expectedAddr)
|
||||
if pkt.Route.RemoteAddress != test.expectedRemoteAddr {
|
||||
t.Errorf("got pkt.Route.RemoteAddress = %s, want = %s", pkt.Route.RemoteAddress, test.expectedRemoteAddr)
|
||||
}
|
||||
if pkt.Route.LocalAddress != lladdr1 {
|
||||
t.Errorf("got pkt.Route.LocalAddress = %s, want = %s", pkt.Route.LocalAddress, lladdr1)
|
||||
}
|
||||
checker.IPv6(t, stack.PayloadSince(pkt.Pkt.NetworkHeader()),
|
||||
checker.SrcAddr(lladdr1),
|
||||
checker.DstAddr(test.expectedAddr),
|
||||
checker.DstAddr(test.expectedRemoteAddr),
|
||||
checker.TTL(header.NDPHopLimit),
|
||||
checker.NDPNS(
|
||||
checker.NDPNSTargetAddress(lladdr0),
|
||||
|
||||
@@ -68,7 +68,7 @@ var _ NUDHandler = (*neighborCache)(nil)
|
||||
// reset to state incomplete, and returned. If no matching entry exists and the
|
||||
// cache is not full, a new entry with state incomplete is allocated and
|
||||
// returned.
|
||||
func (n *neighborCache) getOrCreateEntry(remoteAddr, localAddr tcpip.Address, linkRes LinkAddressResolver) *neighborEntry {
|
||||
func (n *neighborCache) getOrCreateEntry(remoteAddr tcpip.Address, linkRes LinkAddressResolver) *neighborEntry {
|
||||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
|
||||
@@ -84,7 +84,7 @@ func (n *neighborCache) getOrCreateEntry(remoteAddr, localAddr tcpip.Address, li
|
||||
|
||||
// The entry that needs to be created must be dynamic since all static
|
||||
// entries are directly added to the cache via addStaticEntry.
|
||||
entry := newNeighborEntry(n.nic, remoteAddr, localAddr, n.state, linkRes)
|
||||
entry := newNeighborEntry(n.nic, remoteAddr, n.state, linkRes)
|
||||
if n.dynamic.count == neighborCacheSize {
|
||||
e := n.dynamic.lru.Back()
|
||||
e.mu.Lock()
|
||||
@@ -111,6 +111,10 @@ func (n *neighborCache) getOrCreateEntry(remoteAddr, localAddr tcpip.Address, li
|
||||
// provided, it will be notified when address resolution is complete (success
|
||||
// or not).
|
||||
//
|
||||
// If specified, the local address must be an address local to the interface the
|
||||
// neighbor cache belongs to. The local address is the source address of a
|
||||
// packet prompting NUD/link address resolution.
|
||||
//
|
||||
// If address resolution is required, ErrNoLinkAddress and a notification
|
||||
// channel is returned for the top level caller to block. Channel is closed
|
||||
// once address resolution is complete (success or not).
|
||||
@@ -118,7 +122,6 @@ func (n *neighborCache) entry(remoteAddr, localAddr tcpip.Address, linkRes LinkA
|
||||
if linkAddr, ok := linkRes.ResolveStaticAddress(remoteAddr); ok {
|
||||
e := NeighborEntry{
|
||||
Addr: remoteAddr,
|
||||
LocalAddr: localAddr,
|
||||
LinkAddr: linkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: time.Now(),
|
||||
@@ -126,13 +129,13 @@ func (n *neighborCache) entry(remoteAddr, localAddr tcpip.Address, linkRes LinkA
|
||||
return e, nil, nil
|
||||
}
|
||||
|
||||
entry := n.getOrCreateEntry(remoteAddr, localAddr, linkRes)
|
||||
entry := n.getOrCreateEntry(remoteAddr, linkRes)
|
||||
entry.mu.Lock()
|
||||
defer entry.mu.Unlock()
|
||||
|
||||
switch s := entry.neigh.State; s {
|
||||
case Stale:
|
||||
entry.handlePacketQueuedLocked()
|
||||
entry.handlePacketQueuedLocked(localAddr)
|
||||
fallthrough
|
||||
case Reachable, Static, Delay, Probe:
|
||||
// As per RFC 4861 section 7.3.3:
|
||||
@@ -152,7 +155,7 @@ func (n *neighborCache) entry(remoteAddr, localAddr tcpip.Address, linkRes LinkA
|
||||
entry.done = make(chan struct{})
|
||||
}
|
||||
|
||||
entry.handlePacketQueuedLocked()
|
||||
entry.handlePacketQueuedLocked(localAddr)
|
||||
return entry.neigh, entry.done, tcpip.ErrWouldBlock
|
||||
case Failed:
|
||||
return entry.neigh, nil, tcpip.ErrNoLinkAddress
|
||||
@@ -292,8 +295,8 @@ func (n *neighborCache) setConfig(config NUDConfigurations) {
|
||||
// HandleProbe implements NUDHandler.HandleProbe by following the logic defined
|
||||
// in RFC 4861 section 7.2.3. Validation of the probe is expected to be handled
|
||||
// by the caller.
|
||||
func (n *neighborCache) HandleProbe(remoteAddr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, linkRes LinkAddressResolver) {
|
||||
entry := n.getOrCreateEntry(remoteAddr, localAddr, linkRes)
|
||||
func (n *neighborCache) HandleProbe(remoteAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, linkRes LinkAddressResolver) {
|
||||
entry := n.getOrCreateEntry(remoteAddr, linkRes)
|
||||
entry.mu.Lock()
|
||||
entry.handleProbeLocked(remoteLinkAddr)
|
||||
entry.mu.Unlock()
|
||||
|
||||
@@ -128,9 +128,8 @@ func newTestEntryStore() *testEntryStore {
|
||||
linkAddr := toLinkAddress(i)
|
||||
|
||||
store.entriesMap[addr] = NeighborEntry{
|
||||
Addr: addr,
|
||||
LocalAddr: testEntryLocalAddr,
|
||||
LinkAddr: linkAddr,
|
||||
Addr: addr,
|
||||
LinkAddr: linkAddr,
|
||||
}
|
||||
}
|
||||
return store
|
||||
@@ -294,9 +293,8 @@ func TestNeighborCacheEntry(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(0) not found")
|
||||
}
|
||||
_, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
|
||||
clock.Advance(typicalLatency)
|
||||
@@ -324,8 +322,8 @@ func TestNeighborCacheEntry(t *testing.T) {
|
||||
t.Fatalf("nud dispatcher events mismatch (-got, +want):\n%s", diff)
|
||||
}
|
||||
|
||||
if _, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil); err != nil {
|
||||
t.Fatalf("unexpected error from neigh.entry(%s, %s, _, nil): %s", entry.Addr, entry.LocalAddr, err)
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != nil {
|
||||
t.Fatalf("unexpected error from neigh.entry(%s, '', _, nil): %s", entry.Addr, err)
|
||||
}
|
||||
|
||||
// No more events should have been dispatched.
|
||||
@@ -354,9 +352,9 @@ func TestNeighborCacheRemoveEntry(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(0) not found")
|
||||
}
|
||||
_, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
|
||||
clock.Advance(typicalLatency)
|
||||
@@ -404,8 +402,8 @@ func TestNeighborCacheRemoveEntry(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if _, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,8 +450,8 @@ func (c *testContext) overflowCache(opts overflowOptions) error {
|
||||
if !ok {
|
||||
return fmt.Errorf("c.store.entry(%d) not found", i)
|
||||
}
|
||||
if _, _, err := c.neigh.entry(entry.Addr, entry.LocalAddr, c.linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
return fmt.Errorf("got c.neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := c.neigh.entry(entry.Addr, "", c.linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
return fmt.Errorf("got c.neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
c.clock.Advance(c.neigh.config().RetransmitTimer)
|
||||
|
||||
@@ -508,10 +506,9 @@ func (c *testContext) overflowCache(opts overflowOptions) error {
|
||||
return fmt.Errorf("c.store.entry(%d) not found", i)
|
||||
}
|
||||
wantEntry := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: entry.LocalAddr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
}
|
||||
wantUnsortedEntries = append(wantUnsortedEntries, wantEntry)
|
||||
}
|
||||
@@ -564,9 +561,8 @@ func TestNeighborCacheRemoveEntryThenOverflow(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("c.store.entry(0) not found")
|
||||
}
|
||||
_, _, err := c.neigh.entry(entry.Addr, entry.LocalAddr, c.linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got c.neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := c.neigh.entry(entry.Addr, "", c.linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got c.neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
c.clock.Advance(c.neigh.config().RetransmitTimer)
|
||||
wantEvents := []testEntryEventInfo{
|
||||
@@ -800,9 +796,8 @@ func TestNeighborCacheOverwriteWithStaticEntryThenOverflow(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("c.store.entry(0) not found")
|
||||
}
|
||||
_, _, err := c.neigh.entry(entry.Addr, entry.LocalAddr, c.linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got c.neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := c.neigh.entry(entry.Addr, "", c.linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got c.neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
c.clock.Advance(typicalLatency)
|
||||
wantEvents := []testEntryEventInfo{
|
||||
@@ -861,10 +856,9 @@ func TestNeighborCacheOverwriteWithStaticEntryThenOverflow(t *testing.T) {
|
||||
startAtEntryIndex: 1,
|
||||
wantStaticEntries: []NeighborEntry{
|
||||
{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: "", // static entries don't need a local address
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -896,12 +890,12 @@ func TestNeighborCacheNotifiesWaker(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(0) not found")
|
||||
}
|
||||
_, doneCh, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, &w)
|
||||
_, doneCh, err := neigh.entry(entry.Addr, "", linkRes, &w)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Fatalf("got neigh.entry(%s, %s, _, _ = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
t.Fatalf("got neigh.entry(%s, '', _, _ = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
if doneCh == nil {
|
||||
t.Fatalf("expected done channel from neigh.entry(%s, %s, _, _)", entry.Addr, entry.LocalAddr)
|
||||
t.Fatalf("expected done channel from neigh.entry(%s, '', _, _)", entry.Addr)
|
||||
}
|
||||
clock.Advance(typicalLatency)
|
||||
|
||||
@@ -913,7 +907,7 @@ func TestNeighborCacheNotifiesWaker(t *testing.T) {
|
||||
|
||||
id, ok := s.Fetch(false /* block */)
|
||||
if !ok {
|
||||
t.Errorf("expected waker to be notified after neigh.entry(%s, %s, _, _)", entry.Addr, entry.LocalAddr)
|
||||
t.Errorf("expected waker to be notified after neigh.entry(%s, '', _, _)", entry.Addr)
|
||||
}
|
||||
if id != wakerID {
|
||||
t.Errorf("got s.Fetch(false) = %d, want = %d", id, wakerID)
|
||||
@@ -964,12 +958,12 @@ func TestNeighborCacheRemoveWaker(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(0) not found")
|
||||
}
|
||||
_, doneCh, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, &w)
|
||||
_, doneCh, err := neigh.entry(entry.Addr, "", linkRes, &w)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Fatalf("got neigh.entry(%s, %s, _, _) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
t.Fatalf("got neigh.entry(%s, '', _, _) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
if doneCh == nil {
|
||||
t.Fatalf("expected done channel from neigh.entry(%s, %s, _, _)", entry.Addr, entry.LocalAddr)
|
||||
t.Fatalf("expected done channel from neigh.entry(%s, '', _, _)", entry.Addr)
|
||||
}
|
||||
|
||||
// Remove the waker before the neighbor cache has the opportunity to send a
|
||||
@@ -1028,10 +1022,9 @@ func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
|
||||
t.Errorf("unexpected error from c.neigh.entry(%s, \"\", _, nil): %s", entry.Addr, err)
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: "", // static entries don't need a local address
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
}
|
||||
if diff := cmp.Diff(e, want, entryDiffOpts()...); diff != "" {
|
||||
t.Errorf("c.neigh.entry(%s, \"\", _, nil) mismatch (-got, +want):\n%s", entry.Addr, diff)
|
||||
@@ -1058,10 +1051,9 @@ func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
|
||||
startAtEntryIndex: 1,
|
||||
wantStaticEntries: []NeighborEntry{
|
||||
{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: "", // static entries don't need a local address
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1089,9 +1081,8 @@ func TestNeighborCacheClear(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(0) not found")
|
||||
}
|
||||
_, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
clock.Advance(typicalLatency)
|
||||
|
||||
@@ -1185,9 +1176,8 @@ func TestNeighborCacheClearThenOverflow(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("c.store.entry(0) not found")
|
||||
}
|
||||
_, _, err := c.neigh.entry(entry.Addr, entry.LocalAddr, c.linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got c.neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := c.neigh.entry(entry.Addr, "", c.linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got c.neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
c.clock.Advance(typicalLatency)
|
||||
wantEvents := []testEntryEventInfo{
|
||||
@@ -1274,15 +1264,15 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(%d) not found", i)
|
||||
}
|
||||
_, doneCh, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
_, doneCh, err := neigh.entry(entry.Addr, "", linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
t.Errorf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
clock.Advance(typicalLatency)
|
||||
select {
|
||||
case <-doneCh:
|
||||
default:
|
||||
t.Fatalf("expected notification from done channel returned by neigh.entry(%s, %s, _, nil)", entry.Addr, entry.LocalAddr)
|
||||
t.Fatalf("expected notification from done channel returned by neigh.entry(%s, '', _, nil)", entry.Addr)
|
||||
}
|
||||
wantEvents := []testEntryEventInfo{
|
||||
{
|
||||
@@ -1312,9 +1302,8 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
|
||||
for i := neighborCacheSize; i < store.size(); i++ {
|
||||
// Periodically refresh the frequently used entry
|
||||
if i%(neighborCacheSize/2) == 0 {
|
||||
_, _, err := neigh.entry(frequentlyUsedEntry.Addr, frequentlyUsedEntry.LocalAddr, linkRes, nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error from neigh.entry(%s, %s, _, nil): %s", frequentlyUsedEntry.Addr, frequentlyUsedEntry.LocalAddr, err)
|
||||
if _, _, err := neigh.entry(frequentlyUsedEntry.Addr, "", linkRes, nil); err != nil {
|
||||
t.Errorf("unexpected error from neigh.entry(%s, '', _, nil): %s", frequentlyUsedEntry.Addr, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1322,15 +1311,15 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(%d) not found", i)
|
||||
}
|
||||
_, doneCh, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
_, doneCh, err := neigh.entry(entry.Addr, "", linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
t.Errorf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
clock.Advance(typicalLatency)
|
||||
select {
|
||||
case <-doneCh:
|
||||
default:
|
||||
t.Fatalf("expected notification from done channel returned by neigh.entry(%s, %s, _, nil)", entry.Addr, entry.LocalAddr)
|
||||
t.Fatalf("expected notification from done channel returned by neigh.entry(%s, '', _, nil)", entry.Addr)
|
||||
}
|
||||
|
||||
// An entry should have been removed, as per the LRU eviction strategy
|
||||
@@ -1374,10 +1363,9 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
|
||||
// have to be sorted before comparison.
|
||||
wantUnsortedEntries := []NeighborEntry{
|
||||
{
|
||||
Addr: frequentlyUsedEntry.Addr,
|
||||
LocalAddr: frequentlyUsedEntry.LocalAddr,
|
||||
LinkAddr: frequentlyUsedEntry.LinkAddr,
|
||||
State: Reachable,
|
||||
Addr: frequentlyUsedEntry.Addr,
|
||||
LinkAddr: frequentlyUsedEntry.LinkAddr,
|
||||
State: Reachable,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1387,10 +1375,9 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
|
||||
t.Fatalf("store.entry(%d) not found", i)
|
||||
}
|
||||
wantEntry := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: entry.LocalAddr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
}
|
||||
wantUnsortedEntries = append(wantUnsortedEntries, wantEntry)
|
||||
}
|
||||
@@ -1430,9 +1417,8 @@ func TestNeighborCacheConcurrent(t *testing.T) {
|
||||
wg.Add(1)
|
||||
go func(entry NeighborEntry) {
|
||||
defer wg.Done()
|
||||
e, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
if err != nil && err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, %s, _, nil) = (%+v, _, %s), want (_, _, nil) or (_, _, %s)", entry.Addr, entry.LocalAddr, e, err, tcpip.ErrWouldBlock)
|
||||
if e, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != nil && err != tcpip.ErrWouldBlock {
|
||||
t.Errorf("got neigh.entry(%s, '', _, nil) = (%+v, _, %s), want (_, _, nil) or (_, _, %s)", entry.Addr, e, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
}(entry)
|
||||
}
|
||||
@@ -1456,10 +1442,9 @@ func TestNeighborCacheConcurrent(t *testing.T) {
|
||||
t.Errorf("store.entry(%d) not found", i)
|
||||
}
|
||||
wantEntry := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: entry.LocalAddr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
}
|
||||
wantUnsortedEntries = append(wantUnsortedEntries, wantEntry)
|
||||
}
|
||||
@@ -1488,37 +1473,36 @@ func TestNeighborCacheReplace(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(0) not found")
|
||||
}
|
||||
_, doneCh, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
_, doneCh, err := neigh.entry(entry.Addr, "", linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
t.Fatalf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
t.Fatalf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
clock.Advance(typicalLatency)
|
||||
select {
|
||||
case <-doneCh:
|
||||
default:
|
||||
t.Fatalf("expected notification from done channel returned by neigh.entry(%s, %s, _, nil)", entry.Addr, entry.LocalAddr)
|
||||
t.Fatalf("expected notification from done channel returned by neigh.entry(%s, '', _, nil)", entry.Addr)
|
||||
}
|
||||
|
||||
// Verify the entry exists
|
||||
{
|
||||
e, doneCh, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
e, doneCh, err := neigh.entry(entry.Addr, "", linkRes, nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error from neigh.entry(%s, %s, _, nil): %s", entry.Addr, entry.LocalAddr, err)
|
||||
t.Errorf("unexpected error from neigh.entry(%s, '', _, nil): %s", entry.Addr, err)
|
||||
}
|
||||
if doneCh != nil {
|
||||
t.Errorf("unexpected done channel from neigh.entry(%s, %s, _, nil): %v", entry.Addr, entry.LocalAddr, doneCh)
|
||||
t.Errorf("unexpected done channel from neigh.entry(%s, '', _, nil): %v", entry.Addr, doneCh)
|
||||
}
|
||||
if t.Failed() {
|
||||
t.FailNow()
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: entry.LocalAddr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
}
|
||||
if diff := cmp.Diff(e, want, entryDiffOpts()...); diff != "" {
|
||||
t.Errorf("neigh.entry(%s, %s, _, nil) mismatch (-got, +want):\n%s", entry.Addr, entry.LinkAddr, diff)
|
||||
t.Errorf("neigh.entry(%s, '', _, nil) mismatch (-got, +want):\n%s", entry.Addr, diff)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1542,37 +1526,35 @@ func TestNeighborCacheReplace(t *testing.T) {
|
||||
//
|
||||
// Verify the entry's new link address and the new state.
|
||||
{
|
||||
e, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
e, _, err := neigh.entry(entry.Addr, "", linkRes, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("neigh.entry(%s, %s, _, nil): %s", entry.Addr, entry.LocalAddr, err)
|
||||
t.Fatalf("neigh.entry(%s, '', _, nil): %s", entry.Addr, err)
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: entry.LocalAddr,
|
||||
LinkAddr: updatedLinkAddr,
|
||||
State: Delay,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: updatedLinkAddr,
|
||||
State: Delay,
|
||||
}
|
||||
if diff := cmp.Diff(e, want, entryDiffOpts()...); diff != "" {
|
||||
t.Errorf("neigh.entry(%s, %s, _, nil) mismatch (-got, +want):\n%s", entry.Addr, entry.LocalAddr, diff)
|
||||
t.Errorf("neigh.entry(%s, '', _, nil) mismatch (-got, +want):\n%s", entry.Addr, diff)
|
||||
}
|
||||
clock.Advance(config.DelayFirstProbeTime + typicalLatency)
|
||||
}
|
||||
|
||||
// Verify that the neighbor is now reachable.
|
||||
{
|
||||
e, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
e, _, err := neigh.entry(entry.Addr, "", linkRes, nil)
|
||||
clock.Advance(typicalLatency)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error from neigh.entry(%s, %s, _, nil): %s", entry.Addr, entry.LocalAddr, err)
|
||||
t.Errorf("unexpected error from neigh.entry(%s, '', _, nil): %s", entry.Addr, err)
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: entry.LocalAddr,
|
||||
LinkAddr: updatedLinkAddr,
|
||||
State: Reachable,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: updatedLinkAddr,
|
||||
State: Reachable,
|
||||
}
|
||||
if diff := cmp.Diff(e, want, entryDiffOpts()...); diff != "" {
|
||||
t.Errorf("neigh.entry(%s, %s, _, nil) mismatch (-got, +want):\n%s", entry.Addr, entry.LocalAddr, diff)
|
||||
t.Errorf("neigh.entry(%s, '', _, nil) mismatch (-got, +want):\n%s", entry.Addr, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1601,35 +1583,34 @@ func TestNeighborCacheResolutionFailed(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(0) not found")
|
||||
}
|
||||
if _, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Fatalf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Fatalf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
clock.Advance(typicalLatency)
|
||||
got, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
got, _, err := neigh.entry(entry.Addr, "", linkRes, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error from neigh.entry(%s, %s, _, nil): %s", entry.Addr, entry.LocalAddr, err)
|
||||
t.Fatalf("unexpected error from neigh.entry(%s, '', _, nil): %s", entry.Addr, err)
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LocalAddr: entry.LocalAddr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
}
|
||||
if diff := cmp.Diff(got, want, entryDiffOpts()...); diff != "" {
|
||||
t.Errorf("neigh.entry(%s, %s, _, nil) mismatch (-got, +want):\n%s", entry.Addr, entry.LocalAddr, diff)
|
||||
t.Errorf("neigh.entry(%s, '', _, nil) mismatch (-got, +want):\n%s", entry.Addr, diff)
|
||||
}
|
||||
|
||||
// Verify that address resolution for an unknown address returns ErrNoLinkAddress
|
||||
before := atomic.LoadUint32(&requestCount)
|
||||
|
||||
entry.Addr += "2"
|
||||
if _, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Fatalf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Fatalf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
waitFor := config.DelayFirstProbeTime + typicalLatency*time.Duration(config.MaxMulticastProbes)
|
||||
clock.Advance(waitFor)
|
||||
if _, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil); err != tcpip.ErrNoLinkAddress {
|
||||
t.Fatalf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrNoLinkAddress)
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != tcpip.ErrNoLinkAddress {
|
||||
t.Fatalf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrNoLinkAddress)
|
||||
}
|
||||
|
||||
maxAttempts := neigh.config().MaxUnicastProbes
|
||||
@@ -1659,13 +1640,13 @@ func TestNeighborCacheResolutionTimeout(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("store.entry(0) not found")
|
||||
}
|
||||
if _, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Fatalf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != tcpip.ErrWouldBlock {
|
||||
t.Fatalf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
waitFor := config.RetransmitTimer * time.Duration(config.MaxMulticastProbes)
|
||||
clock.Advance(waitFor)
|
||||
if _, _, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil); err != tcpip.ErrNoLinkAddress {
|
||||
t.Fatalf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrNoLinkAddress)
|
||||
if _, _, err := neigh.entry(entry.Addr, "", linkRes, nil); err != tcpip.ErrNoLinkAddress {
|
||||
t.Fatalf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrNoLinkAddress)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1683,18 +1664,17 @@ func TestNeighborCacheStaticResolution(t *testing.T) {
|
||||
delay: typicalLatency,
|
||||
}
|
||||
|
||||
got, _, err := neigh.entry(testEntryBroadcastAddr, testEntryLocalAddr, linkRes, nil)
|
||||
got, _, err := neigh.entry(testEntryBroadcastAddr, "", linkRes, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error from neigh.entry(%s, %s, _, nil): %s", testEntryBroadcastAddr, testEntryLocalAddr, err)
|
||||
t.Fatalf("unexpected error from neigh.entry(%s, '', _, nil): %s", testEntryBroadcastAddr, err)
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: testEntryBroadcastAddr,
|
||||
LocalAddr: testEntryLocalAddr,
|
||||
LinkAddr: testEntryBroadcastLinkAddr,
|
||||
State: Static,
|
||||
Addr: testEntryBroadcastAddr,
|
||||
LinkAddr: testEntryBroadcastLinkAddr,
|
||||
State: Static,
|
||||
}
|
||||
if diff := cmp.Diff(got, want, entryDiffOpts()...); diff != "" {
|
||||
t.Errorf("neigh.entry(%s, %s, _, nil) mismatch (-got, +want):\n%s", testEntryBroadcastAddr, testEntryLocalAddr, diff)
|
||||
t.Errorf("neigh.entry(%s, '', _, nil) mismatch (-got, +want):\n%s", testEntryBroadcastAddr, diff)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1719,9 +1699,9 @@ func BenchmarkCacheClear(b *testing.B) {
|
||||
if !ok {
|
||||
b.Fatalf("store.entry(%d) not found", i)
|
||||
}
|
||||
_, doneCh, err := neigh.entry(entry.Addr, entry.LocalAddr, linkRes, nil)
|
||||
_, doneCh, err := neigh.entry(entry.Addr, "", linkRes, nil)
|
||||
if err != tcpip.ErrWouldBlock {
|
||||
b.Fatalf("got neigh.entry(%s, %s, _, nil) = %v, want = %s", entry.Addr, entry.LocalAddr, err, tcpip.ErrWouldBlock)
|
||||
b.Fatalf("got neigh.entry(%s, '', _, nil) = %v, want = %s", entry.Addr, err, tcpip.ErrWouldBlock)
|
||||
}
|
||||
if doneCh != nil {
|
||||
<-doneCh
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
// NeighborEntry describes a neighboring device in the local network.
|
||||
type NeighborEntry struct {
|
||||
Addr tcpip.Address
|
||||
LocalAddr tcpip.Address
|
||||
LinkAddr tcpip.LinkAddress
|
||||
State NeighborState
|
||||
UpdatedAt time.Time
|
||||
@@ -106,15 +105,14 @@ type neighborEntry struct {
|
||||
// state, Unknown. Transition out of Unknown by calling either
|
||||
// `handlePacketQueuedLocked` or `handleProbeLocked` on the newly created
|
||||
// neighborEntry.
|
||||
func newNeighborEntry(nic *NIC, remoteAddr tcpip.Address, localAddr tcpip.Address, nudState *NUDState, linkRes LinkAddressResolver) *neighborEntry {
|
||||
func newNeighborEntry(nic *NIC, remoteAddr tcpip.Address, nudState *NUDState, linkRes LinkAddressResolver) *neighborEntry {
|
||||
return &neighborEntry{
|
||||
nic: nic,
|
||||
linkRes: linkRes,
|
||||
nudState: nudState,
|
||||
neigh: NeighborEntry{
|
||||
Addr: remoteAddr,
|
||||
LocalAddr: localAddr,
|
||||
State: Unknown,
|
||||
Addr: remoteAddr,
|
||||
State: Unknown,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -206,51 +204,7 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
|
||||
|
||||
switch next {
|
||||
case Incomplete:
|
||||
var retryCounter uint32
|
||||
var sendMulticastProbe func()
|
||||
|
||||
sendMulticastProbe = func() {
|
||||
if retryCounter == config.MaxMulticastProbes {
|
||||
// "If no Neighbor Advertisement is received after
|
||||
// MAX_MULTICAST_SOLICIT solicitations, address resolution has failed.
|
||||
// The sender MUST return ICMP destination unreachable indications with
|
||||
// code 3 (Address Unreachable) for each packet queued awaiting address
|
||||
// resolution." - RFC 4861 section 7.2.2
|
||||
//
|
||||
// There is no need to send an ICMP destination unreachable indication
|
||||
// since the failure to resolve the address is expected to only occur
|
||||
// on this node. Thus, redirecting traffic is currently not supported.
|
||||
//
|
||||
// "If the error occurs on a node other than the node originating the
|
||||
// packet, an ICMP error message is generated. If the error occurs on
|
||||
// the originating node, an implementation is not required to actually
|
||||
// create and send an ICMP error packet to the source, as long as the
|
||||
// upper-layer sender is notified through an appropriate mechanism
|
||||
// (e.g. return value from a procedure call). Note, however, that an
|
||||
// implementation may find it convenient in some cases to return errors
|
||||
// to the sender by taking the offending packet, generating an ICMP
|
||||
// error message, and then delivering it (locally) through the generic
|
||||
// error-handling routines.' - RFC 4861 section 2.1
|
||||
e.dispatchRemoveEventLocked()
|
||||
e.setStateLocked(Failed)
|
||||
return
|
||||
}
|
||||
|
||||
if err := e.linkRes.LinkAddressRequest(e.neigh.Addr, e.neigh.LocalAddr, "", e.nic); err != nil {
|
||||
// There is no need to log the error here; the NUD implementation may
|
||||
// assume a working link. A valid link should be the responsibility of
|
||||
// the NIC/stack.LinkEndpoint.
|
||||
e.dispatchRemoveEventLocked()
|
||||
e.setStateLocked(Failed)
|
||||
return
|
||||
}
|
||||
|
||||
retryCounter++
|
||||
e.job = e.nic.stack.newJob(&e.mu, sendMulticastProbe)
|
||||
e.job.Schedule(config.RetransmitTimer)
|
||||
}
|
||||
|
||||
sendMulticastProbe()
|
||||
panic(fmt.Sprintf("should never transition to Incomplete with setStateLocked; neigh = %#v, prev state = %s", e.neigh, prev))
|
||||
|
||||
case Reachable:
|
||||
e.job = e.nic.stack.newJob(&e.mu, func() {
|
||||
@@ -277,7 +231,7 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := e.linkRes.LinkAddressRequest(e.neigh.Addr, e.neigh.LocalAddr, e.neigh.LinkAddr, e.nic); err != nil {
|
||||
if err := e.linkRes.LinkAddressRequest(e.neigh.Addr, "" /* localAddr */, e.neigh.LinkAddr, e.nic); err != nil {
|
||||
e.dispatchRemoveEventLocked()
|
||||
e.setStateLocked(Failed)
|
||||
return
|
||||
@@ -315,11 +269,67 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
|
||||
// being queued for outgoing transmission.
|
||||
//
|
||||
// Follows the logic defined in RFC 4861 section 7.3.3.
|
||||
func (e *neighborEntry) handlePacketQueuedLocked() {
|
||||
func (e *neighborEntry) handlePacketQueuedLocked(localAddr tcpip.Address) {
|
||||
switch e.neigh.State {
|
||||
case Unknown:
|
||||
e.dispatchAddEventLocked(Incomplete)
|
||||
e.setStateLocked(Incomplete)
|
||||
|
||||
e.neigh.State = Incomplete
|
||||
e.neigh.UpdatedAt = time.Now()
|
||||
config := e.nudState.Config()
|
||||
|
||||
var retryCounter uint32
|
||||
var sendMulticastProbe func()
|
||||
|
||||
sendMulticastProbe = func() {
|
||||
if retryCounter == config.MaxMulticastProbes {
|
||||
// "If no Neighbor Advertisement is received after
|
||||
// MAX_MULTICAST_SOLICIT solicitations, address resolution has failed.
|
||||
// The sender MUST return ICMP destination unreachable indications with
|
||||
// code 3 (Address Unreachable) for each packet queued awaiting address
|
||||
// resolution." - RFC 4861 section 7.2.2
|
||||
//
|
||||
// There is no need to send an ICMP destination unreachable indication
|
||||
// since the failure to resolve the address is expected to only occur
|
||||
// on this node. Thus, redirecting traffic is currently not supported.
|
||||
//
|
||||
// "If the error occurs on a node other than the node originating the
|
||||
// packet, an ICMP error message is generated. If the error occurs on
|
||||
// the originating node, an implementation is not required to actually
|
||||
// create and send an ICMP error packet to the source, as long as the
|
||||
// upper-layer sender is notified through an appropriate mechanism
|
||||
// (e.g. return value from a procedure call). Note, however, that an
|
||||
// implementation may find it convenient in some cases to return errors
|
||||
// to the sender by taking the offending packet, generating an ICMP
|
||||
// error message, and then delivering it (locally) through the generic
|
||||
// error-handling routines.' - RFC 4861 section 2.1
|
||||
e.dispatchRemoveEventLocked()
|
||||
e.setStateLocked(Failed)
|
||||
return
|
||||
}
|
||||
|
||||
// As per RFC 4861 section 7.2.2:
|
||||
//
|
||||
// If the source address of the packet prompting the solicitation is the
|
||||
// same as one of the addresses assigned to the outgoing interface, that
|
||||
// address SHOULD be placed in the IP Source Address of the outgoing
|
||||
// solicitation.
|
||||
//
|
||||
if err := e.linkRes.LinkAddressRequest(e.neigh.Addr, localAddr, "", e.nic); err != nil {
|
||||
// There is no need to log the error here; the NUD implementation may
|
||||
// assume a working link. A valid link should be the responsibility of
|
||||
// the NIC/stack.LinkEndpoint.
|
||||
e.dispatchRemoveEventLocked()
|
||||
e.setStateLocked(Failed)
|
||||
return
|
||||
}
|
||||
|
||||
retryCounter++
|
||||
e.job = e.nic.stack.newJob(&e.mu, sendMulticastProbe)
|
||||
e.job.Schedule(config.RetransmitTimer)
|
||||
}
|
||||
|
||||
sendMulticastProbe()
|
||||
|
||||
case Stale:
|
||||
e.dispatchChangeEventLocked(Delay)
|
||||
|
||||
@@ -245,7 +245,7 @@ func entryTestSetup(c NUDConfigurations) (*neighborEntry, *testNUDDispatcher, *e
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
nudState := NewNUDState(c, rng)
|
||||
linkRes := entryTestLinkResolver{}
|
||||
entry := newNeighborEntry(&nic, entryTestAddr1 /* remoteAddr */, entryTestAddr2 /* localAddr */, nudState, &linkRes)
|
||||
entry := newNeighborEntry(&nic, entryTestAddr1 /* remoteAddr */, nudState, &linkRes)
|
||||
|
||||
// Stub out the neighbor cache to verify deletion from the cache.
|
||||
nic.neigh = &neighborCache{
|
||||
@@ -326,7 +326,7 @@ func TestEntryUnknownToIncomplete(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Incomplete; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -406,7 +406,7 @@ func TestEntryIncompleteToIncompleteDoesNotChangeUpdatedAt(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Incomplete; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -498,7 +498,7 @@ func TestEntryIncompleteToReachable(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Incomplete; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -563,7 +563,7 @@ func TestEntryAddsAndClearsWakers(t *testing.T) {
|
||||
defer s.Done()
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got := e.wakers; got != nil {
|
||||
t.Errorf("got e.wakers = %v, want = nil", got)
|
||||
}
|
||||
@@ -629,7 +629,7 @@ func TestEntryIncompleteToReachableWithRouterFlag(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Incomplete; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -687,7 +687,7 @@ func TestEntryIncompleteToStale(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Incomplete; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -744,7 +744,7 @@ func TestEntryIncompleteToFailed(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Incomplete; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -822,7 +822,7 @@ func TestEntryStaysReachableWhenConfirmationWithRouterFlag(t *testing.T) {
|
||||
ipv6EP := e.nic.networkEndpoints[header.IPv6ProtocolNumber].(*testIPv6Endpoint)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: true,
|
||||
Override: false,
|
||||
@@ -896,7 +896,7 @@ func TestEntryStaysReachableWhenProbeWithSameAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: true,
|
||||
Override: false,
|
||||
@@ -961,7 +961,7 @@ func TestEntryReachableToStaleWhenTimeout(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: true,
|
||||
Override: false,
|
||||
@@ -1029,7 +1029,7 @@ func TestEntryReachableToStaleWhenProbeWithDifferentAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: true,
|
||||
Override: false,
|
||||
@@ -1099,7 +1099,7 @@ func TestEntryReachableToStaleWhenConfirmationWithDifferentAddress(t *testing.T)
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: true,
|
||||
Override: false,
|
||||
@@ -1173,7 +1173,7 @@ func TestEntryReachableToStaleWhenConfirmationWithDifferentAddressAndOverride(t
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: true,
|
||||
Override: false,
|
||||
@@ -1247,7 +1247,7 @@ func TestEntryStaysStaleWhenProbeWithSameAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
@@ -1307,7 +1307,7 @@ func TestEntryStaleToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
@@ -1378,7 +1378,7 @@ func TestEntryStaleToReachableWhenSolicitedConfirmationWithoutAddress(t *testing
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
@@ -1449,7 +1449,7 @@ func TestEntryStaleToStaleWhenOverrideConfirmation(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
@@ -1520,7 +1520,7 @@ func TestEntryStaleToStaleWhenProbeUpdateAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
@@ -1587,7 +1587,7 @@ func TestEntryStaleToDelay(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
@@ -1596,7 +1596,7 @@ func TestEntryStaleToDelay(t *testing.T) {
|
||||
if got, want := e.neigh.State, Stale; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Delay; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -1656,13 +1656,13 @@ func TestEntryDelayToReachableWhenUpperLevelConfirmation(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Delay; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -1743,13 +1743,13 @@ func TestEntryDelayToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Delay; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -1837,13 +1837,13 @@ func TestEntryDelayToReachableWhenSolicitedConfirmationWithoutAddress(t *testing
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if e.neigh.State != Delay {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", e.neigh.State, Delay)
|
||||
}
|
||||
@@ -1925,13 +1925,13 @@ func TestEntryStaysDelayWhenOverrideConfirmationWithSameAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Delay; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -1997,13 +1997,13 @@ func TestEntryDelayToStaleWhenProbeWithDifferentAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Delay; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -2069,13 +2069,13 @@ func TestEntryDelayToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, _ := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Delay; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -2145,13 +2145,13 @@ func TestEntryDelayToProbe(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
if got, want := e.neigh.State, Delay; got != want {
|
||||
t.Errorf("got e.neigh.State = %q, want = %q", got, want)
|
||||
}
|
||||
@@ -2170,7 +2170,6 @@ func TestEntryDelayToProbe(t *testing.T) {
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
@@ -2228,13 +2227,13 @@ func TestEntryProbeToStaleWhenProbeWithDifferentAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.mu.Unlock()
|
||||
|
||||
clock.Advance(c.DelayFirstProbeTime)
|
||||
@@ -2250,7 +2249,6 @@ func TestEntryProbeToStaleWhenProbeWithDifferentAddress(t *testing.T) {
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
@@ -2325,13 +2323,13 @@ func TestEntryProbeToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.mu.Unlock()
|
||||
|
||||
clock.Advance(c.DelayFirstProbeTime)
|
||||
@@ -2347,7 +2345,6 @@ func TestEntryProbeToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
@@ -2426,13 +2423,13 @@ func TestEntryStaysProbeWhenOverrideConfirmationWithSameAddress(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.mu.Unlock()
|
||||
|
||||
clock.Advance(c.DelayFirstProbeTime)
|
||||
@@ -2448,7 +2445,6 @@ func TestEntryStaysProbeWhenOverrideConfirmationWithSameAddress(t *testing.T) {
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
@@ -2529,7 +2525,7 @@ func TestEntryUnknownToStaleToProbeToReachable(t *testing.T) {
|
||||
|
||||
e.mu.Lock()
|
||||
e.handleProbeLocked(entryTestLinkAddr1)
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.mu.Unlock()
|
||||
|
||||
clock.Advance(c.DelayFirstProbeTime)
|
||||
@@ -2539,7 +2535,6 @@ func TestEntryUnknownToStaleToProbeToReachable(t *testing.T) {
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
@@ -2622,13 +2617,13 @@ func TestEntryProbeToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.mu.Unlock()
|
||||
|
||||
clock.Advance(c.DelayFirstProbeTime)
|
||||
@@ -2644,7 +2639,6 @@ func TestEntryProbeToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
@@ -2734,13 +2728,13 @@ func TestEntryProbeToReachableWhenSolicitedConfirmationWithSameAddress(t *testin
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.mu.Unlock()
|
||||
|
||||
clock.Advance(c.DelayFirstProbeTime)
|
||||
@@ -2756,7 +2750,6 @@ func TestEntryProbeToReachableWhenSolicitedConfirmationWithSameAddress(t *testin
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
@@ -2843,13 +2836,13 @@ func TestEntryProbeToReachableWhenSolicitedConfirmationWithoutAddress(t *testing
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.mu.Unlock()
|
||||
|
||||
clock.Advance(c.DelayFirstProbeTime)
|
||||
@@ -2865,7 +2858,6 @@ func TestEntryProbeToReachableWhenSolicitedConfirmationWithoutAddress(t *testing
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
@@ -2949,13 +2941,13 @@ func TestEntryProbeToFailed(t *testing.T) {
|
||||
e, nudDisp, linkRes, clock := entryTestSetup(c)
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.mu.Unlock()
|
||||
|
||||
waitFor := c.DelayFirstProbeTime + c.RetransmitTimer*time.Duration(c.MaxUnicastProbes)
|
||||
@@ -2972,17 +2964,14 @@ func TestEntryProbeToFailed(t *testing.T) {
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
@@ -3054,13 +3043,13 @@ func TestEntryFailedGetsDeleted(t *testing.T) {
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
|
||||
Solicited: false,
|
||||
Override: false,
|
||||
IsRouter: false,
|
||||
})
|
||||
e.handlePacketQueuedLocked()
|
||||
e.handlePacketQueuedLocked(entryTestAddr2)
|
||||
e.mu.Unlock()
|
||||
|
||||
waitFor := c.DelayFirstProbeTime + c.RetransmitTimer*time.Duration(c.MaxUnicastProbes) + c.UnreachableTime
|
||||
@@ -3077,17 +3066,14 @@ func TestEntryFailedGetsDeleted(t *testing.T) {
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
{
|
||||
RemoteAddress: entryTestAddr1,
|
||||
RemoteLinkAddress: entryTestLinkAddr1,
|
||||
LocalAddress: entryTestAddr2,
|
||||
},
|
||||
}
|
||||
linkRes.mu.Lock()
|
||||
|
||||
@@ -177,7 +177,7 @@ type NUDHandler interface {
|
||||
// Neighbor Solicitation for ARP or NDP, respectively). Validation of the
|
||||
// probe needs to be performed before calling this function since the
|
||||
// Neighbor Cache doesn't have access to view the NIC's assigned addresses.
|
||||
HandleProbe(remoteAddr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, linkRes LinkAddressResolver)
|
||||
HandleProbe(remoteAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, linkRes LinkAddressResolver)
|
||||
|
||||
// HandleConfirmation processes an incoming neighbor confirmation (e.g. ARP
|
||||
// reply or Neighbor Advertisement for ARP or NDP, respectively).
|
||||
|
||||
Reference in New Issue
Block a user