summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTamir Duberstein <tamird@google.com>2021-03-02 11:55:45 -0800
committergVisor bot <gvisor-bot@google.com>2021-03-02 11:58:12 -0800
commit6bc27946a6cb159ecbe049acff888d0041d4a432 (patch)
tree6d0c7922e82cc9a8818132ab3b3fb902696a18d9
parent865ca64ee8c0af9eba88a4a04e0730630fae6d8b (diff)
Plumb link address request errors up to requester
Prevent the situation where callers to (*stack).GetLinkAddress provide incorrect arguments and are unable to observe this condition. Updates #5583. PiperOrigin-RevId: 360481557
-rw-r--r--pkg/tcpip/stack/neighbor_cache.go2
-rw-r--r--pkg/tcpip/stack/neighbor_cache_test.go18
-rw-r--r--pkg/tcpip/stack/neighbor_entry.go37
-rw-r--r--pkg/tcpip/stack/nic.go2
-rw-r--r--pkg/tcpip/stack/pending_packets.go12
-rw-r--r--pkg/tcpip/stack/route.go8
-rw-r--r--pkg/tcpip/stack/stack.go2
-rw-r--r--pkg/tcpip/stack/stack_test.go2
-rw-r--r--pkg/tcpip/tests/integration/link_resolution_test.go86
9 files changed, 94 insertions, 75 deletions
diff --git a/pkg/tcpip/stack/neighbor_cache.go b/pkg/tcpip/stack/neighbor_cache.go
index 6b1f8da86..509f5ce5c 100644
--- a/pkg/tcpip/stack/neighbor_cache.go
+++ b/pkg/tcpip/stack/neighbor_cache.go
@@ -140,7 +140,7 @@ func (n *neighborCache) entry(remoteAddr, localAddr tcpip.Address, onResolve fun
// a node continues sending packets to that neighbor using the cached
// link-layer address."
if onResolve != nil {
- onResolve(LinkResolutionResult{LinkAddress: entry.mu.neigh.LinkAddr, Success: true})
+ onResolve(LinkResolutionResult{LinkAddress: entry.mu.neigh.LinkAddr, Err: nil})
}
return entry.mu.neigh, nil, nil
case Unknown, Incomplete, Unreachable:
diff --git a/pkg/tcpip/stack/neighbor_cache_test.go b/pkg/tcpip/stack/neighbor_cache_test.go
index 38fe82fc1..afff1b434 100644
--- a/pkg/tcpip/stack/neighbor_cache_test.go
+++ b/pkg/tcpip/stack/neighbor_cache_test.go
@@ -1162,7 +1162,7 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
t.Fatalf("linkRes.entries.entry(%d) not found", i)
}
_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
- if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Success: true}, r); diff != "" {
+ if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Err: nil}, r); diff != "" {
t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
}
})
@@ -1218,7 +1218,7 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
}
_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
- if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Success: true}, r); diff != "" {
+ if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Err: nil}, r); diff != "" {
t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
}
})
@@ -1379,7 +1379,7 @@ func TestNeighborCacheReplace(t *testing.T) {
}
_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
- if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Success: true}, r); diff != "" {
+ if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Err: nil}, r); diff != "" {
t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
}
})
@@ -1485,7 +1485,7 @@ func TestNeighborCacheResolutionFailed(t *testing.T) {
// First, sanity check that resolution is working
{
_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
- if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Success: true}, r); diff != "" {
+ if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Err: nil}, r); diff != "" {
t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
}
})
@@ -1519,7 +1519,7 @@ func TestNeighborCacheResolutionFailed(t *testing.T) {
entry.Addr += "2"
{
_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
- if diff := cmp.Diff(LinkResolutionResult{Success: false}, r); diff != "" {
+ if diff := cmp.Diff(LinkResolutionResult{Err: &tcpip.ErrTimeout{}}, r); diff != "" {
t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
}
})
@@ -1559,7 +1559,7 @@ func TestNeighborCacheResolutionTimeout(t *testing.T) {
}
_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
- if diff := cmp.Diff(LinkResolutionResult{Success: false}, r); diff != "" {
+ if diff := cmp.Diff(LinkResolutionResult{Err: &tcpip.ErrTimeout{}}, r); diff != "" {
t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
}
})
@@ -1593,7 +1593,7 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
// Perform address resolution with a faulty link, which will fail.
{
_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
- if diff := cmp.Diff(LinkResolutionResult{Success: false}, r); diff != "" {
+ if diff := cmp.Diff(LinkResolutionResult{Err: &tcpip.ErrTimeout{}}, r); diff != "" {
t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
}
})
@@ -1625,7 +1625,7 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
linkRes.dropReplies = false
{
incompleteEntry, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
- if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Success: true}, r); diff != "" {
+ if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Err: nil}, r); diff != "" {
t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
}
})
@@ -1678,7 +1678,7 @@ func BenchmarkCacheClear(b *testing.B) {
}
_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
- if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Success: true}, r); diff != "" {
+ if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Err: nil}, r); diff != "" {
b.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
}
})
diff --git a/pkg/tcpip/stack/neighbor_entry.go b/pkg/tcpip/stack/neighbor_entry.go
index 36d3cad62..6d95e1664 100644
--- a/pkg/tcpip/stack/neighbor_entry.go
+++ b/pkg/tcpip/stack/neighbor_entry.go
@@ -157,8 +157,8 @@ func newStaticNeighborEntry(cache *neighborCache, addr tcpip.Address, linkAddr t
// the link address if resolution completed successfully.
//
// Precondition: e.mu MUST be locked.
-func (e *neighborEntry) notifyCompletionLocked(succeeded bool) {
- res := LinkResolutionResult{LinkAddress: e.mu.neigh.LinkAddr, Success: succeeded}
+func (e *neighborEntry) notifyCompletionLocked(err tcpip.Error) {
+ res := LinkResolutionResult{LinkAddress: e.mu.neigh.LinkAddr, Err: err}
for _, callback := range e.mu.onResolve {
callback(res)
}
@@ -173,7 +173,7 @@ func (e *neighborEntry) notifyCompletionLocked(succeeded bool) {
// is resolved (which ends up obtaining the entry's lock) while holding the
// link resolution queue's lock. Dequeuing packets in a new goroutine avoids
// a lock ordering violation.
- go e.cache.nic.linkResQueue.dequeue(ch, e.mu.neigh.LinkAddr, succeeded)
+ go e.cache.nic.linkResQueue.dequeue(ch, e.mu.neigh.LinkAddr, err)
}
}
@@ -227,7 +227,13 @@ func (e *neighborEntry) removeLocked() {
e.mu.neigh.UpdatedAtNanos = e.cache.nic.stack.clock.NowNanoseconds()
e.dispatchRemoveEventLocked()
e.cancelTimerLocked()
- e.notifyCompletionLocked(false /* succeeded */)
+ // TODO(https://gvisor.dev/issues/5583): test the case where this function is
+ // called during resolution; that can happen in at least these scenarios:
+ //
+ // - manual address removal during resolution
+ //
+ // - neighbor cache eviction during resolution
+ e.notifyCompletionLocked(&tcpip.ErrAborted{})
}
// setStateLocked transitions the entry to the specified state immediately.
@@ -302,9 +308,8 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
e.mu.timer = timer{
done: &done,
timer: e.cache.nic.stack.Clock().AfterFunc(0, func() {
- var err tcpip.Error
- timedoutResolution := remaining == 0
- if !timedoutResolution {
+ var err tcpip.Error = &tcpip.ErrTimeout{}
+ if remaining != 0 {
err = e.cache.linkRes.LinkAddressRequest(addr, "" /* localAddr */, linkAddr)
}
@@ -316,8 +321,9 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
return
}
- if timedoutResolution || err != nil {
+ if err != nil {
e.setStateLocked(Unreachable)
+ e.notifyCompletionLocked(err)
e.dispatchChangeEventLocked()
return
}
@@ -328,7 +334,6 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
}
case Unreachable:
- e.notifyCompletionLocked(false /* succeeded */)
case Unknown, Stale, Static:
// Do nothing
@@ -374,9 +379,8 @@ func (e *neighborEntry) handlePacketQueuedLocked(localAddr tcpip.Address) {
e.mu.timer = timer{
done: &done,
timer: e.cache.nic.stack.Clock().AfterFunc(0, func() {
- var err tcpip.Error
- timedoutResolution := remaining == 0
- if !timedoutResolution {
+ var err tcpip.Error = &tcpip.ErrTimeout{}
+ if remaining != 0 {
// As per RFC 4861 section 7.2.2:
//
// If the source address of the packet prompting the solicitation is
@@ -395,8 +399,9 @@ func (e *neighborEntry) handlePacketQueuedLocked(localAddr tcpip.Address) {
return
}
- if timedoutResolution || err != nil {
+ if err != nil {
e.setStateLocked(Unreachable)
+ e.notifyCompletionLocked(err)
e.dispatchChangeEventLocked()
return
}
@@ -442,7 +447,7 @@ func (e *neighborEntry) handleProbeLocked(remoteLinkAddr tcpip.LinkAddress) {
// - RFC 4861 section 7.2.3
e.mu.neigh.LinkAddr = remoteLinkAddr
e.setStateLocked(Stale)
- e.notifyCompletionLocked(true /* succeeded */)
+ e.notifyCompletionLocked(nil)
e.dispatchChangeEventLocked()
case Reachable, Delay, Probe:
@@ -504,7 +509,7 @@ func (e *neighborEntry) handleConfirmationLocked(linkAddr tcpip.LinkAddress, fla
}
e.dispatchChangeEventLocked()
e.mu.isRouter = flags.IsRouter
- e.notifyCompletionLocked(true /* succeeded */)
+ e.notifyCompletionLocked(nil)
// "Note that the Override flag is ignored if the entry is in the
// INCOMPLETE state." - RFC 4861 section 7.2.5
@@ -539,7 +544,7 @@ func (e *neighborEntry) handleConfirmationLocked(linkAddr tcpip.LinkAddress, fla
wasReachable := e.mu.neigh.State == Reachable
// Set state to Reachable again to refresh timers.
e.setStateLocked(Reachable)
- e.notifyCompletionLocked(true /* succeeded */)
+ e.notifyCompletionLocked(nil)
if !wasReachable {
e.dispatchChangeEventLocked()
}
diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go
index f66db16a7..f9323d545 100644
--- a/pkg/tcpip/stack/nic.go
+++ b/pkg/tcpip/stack/nic.go
@@ -613,7 +613,7 @@ func (n *nic) getLinkAddress(addr, localAddr tcpip.Address, protocol tcpip.Netwo
}
if linkAddr, ok := linkRes.resolver.ResolveStaticAddress(addr); ok {
- onResolve(LinkResolutionResult{LinkAddress: linkAddr, Success: true})
+ onResolve(LinkResolutionResult{LinkAddress: linkAddr, Err: nil})
return nil
}
diff --git a/pkg/tcpip/stack/pending_packets.go b/pkg/tcpip/stack/pending_packets.go
index dc139ebb2..e936aa728 100644
--- a/pkg/tcpip/stack/pending_packets.go
+++ b/pkg/tcpip/stack/pending_packets.go
@@ -91,9 +91,9 @@ func (f *packetsPendingLinkResolution) init(nic *nic) {
// dequeue any pending packets associated with ch.
//
-// If success is true, packets will be written and sent to the given remote link
+// If err is nil, packets will be written and sent to the given remote link
// address.
-func (f *packetsPendingLinkResolution) dequeue(ch <-chan struct{}, linkAddr tcpip.LinkAddress, success bool) {
+func (f *packetsPendingLinkResolution) dequeue(ch <-chan struct{}, linkAddr tcpip.LinkAddress, err tcpip.Error) {
f.mu.Lock()
packets, ok := f.mu.packets[ch]
delete(f.mu.packets, ch)
@@ -110,7 +110,7 @@ func (f *packetsPendingLinkResolution) dequeue(ch <-chan struct{}, linkAddr tcpi
f.mu.Unlock()
if ok {
- f.dequeuePackets(packets, linkAddr, success)
+ f.dequeuePackets(packets, linkAddr, err)
}
}
@@ -176,7 +176,7 @@ func (f *packetsPendingLinkResolution) enqueue(r *Route, gso *GSO, proto tcpip.N
if len(cancelledPackets) != 0 {
// Dequeue the pending packets in a new goroutine to not hold up the current
// goroutine as handing link resolution failures may be a costly operation.
- go f.dequeuePackets(cancelledPackets, "" /* linkAddr */, false /* success */)
+ go f.dequeuePackets(cancelledPackets, "" /* linkAddr */, &tcpip.ErrAborted{})
}
return pkt.len(), nil
@@ -207,9 +207,9 @@ func (f *packetsPendingLinkResolution) newCancelChannelLocked(newCH <-chan struc
return packets
}
-func (f *packetsPendingLinkResolution) dequeuePackets(packets []pendingPacket, linkAddr tcpip.LinkAddress, success bool) {
+func (f *packetsPendingLinkResolution) dequeuePackets(packets []pendingPacket, linkAddr tcpip.LinkAddress, err tcpip.Error) {
for _, p := range packets {
- if success {
+ if err == nil {
p.routeInfo.RemoteLinkAddress = linkAddr
_, _ = f.nic.writePacketBuffer(p.routeInfo, p.gso, p.proto, p.pkt)
} else {
diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go
index e946f9fe3..4ba6794a0 100644
--- a/pkg/tcpip/stack/route.go
+++ b/pkg/tcpip/stack/route.go
@@ -318,7 +318,7 @@ func (r *Route) ResolveWith(addr tcpip.LinkAddress) {
// ResolvedFieldsResult is the result of a route resolution attempt.
type ResolvedFieldsResult struct {
RouteInfo RouteInfo
- Success bool
+ Err tcpip.Error
}
// ResolvedFields attempts to resolve the remote link address if it is not
@@ -349,7 +349,7 @@ func (r *Route) resolvedFields(afterResolve func(ResolvedFieldsResult)) (RouteIn
r.mu.RUnlock()
if !resolutionRequired {
if afterResolve != nil {
- afterResolve(ResolvedFieldsResult{RouteInfo: fields, Success: true})
+ afterResolve(ResolvedFieldsResult{RouteInfo: fields, Err: nil})
}
return fields, nil, nil
}
@@ -364,11 +364,11 @@ func (r *Route) resolvedFields(afterResolve func(ResolvedFieldsResult)) (RouteIn
afterResolveFields := fields
linkAddr, ch, err := r.linkRes.getNeighborLinkAddress(r.nextHop(), linkAddressResolutionRequestLocalAddr, func(r LinkResolutionResult) {
if afterResolve != nil {
- if r.Success {
+ if r.Err == nil {
afterResolveFields.RemoteLinkAddress = r.LinkAddress
}
- afterResolve(ResolvedFieldsResult{RouteInfo: afterResolveFields, Success: r.Success})
+ afterResolve(ResolvedFieldsResult{RouteInfo: afterResolveFields, Err: r.Err})
}
})
if err == nil {
diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go
index 674c9a1ff..de94ddfda 100644
--- a/pkg/tcpip/stack/stack.go
+++ b/pkg/tcpip/stack/stack.go
@@ -1542,7 +1542,7 @@ func (s *Stack) SetSpoofing(nicID tcpip.NICID, enable bool) tcpip.Error {
// LinkResolutionResult is the result of a link address resolution attempt.
type LinkResolutionResult struct {
LinkAddress tcpip.LinkAddress
- Success bool
+ Err tcpip.Error
}
// GetLinkAddress finds the link address corresponding to a network address.
diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go
index 92a0cb401..8e39e828c 100644
--- a/pkg/tcpip/stack/stack_test.go
+++ b/pkg/tcpip/stack/stack_test.go
@@ -4455,7 +4455,7 @@ func TestStaticGetLinkAddress(t *testing.T) {
t.Fatalf("s.GetLinkAddress(%d, %s, '', %d, _): %s", nicID, test.addr, test.proto, err)
}
- if diff := cmp.Diff(stack.LinkResolutionResult{LinkAddress: test.expectedLinkAddr, Success: true}, <-ch); diff != "" {
+ if diff := cmp.Diff(stack.LinkResolutionResult{LinkAddress: test.expectedLinkAddr, Err: nil}, <-ch); diff != "" {
t.Fatalf("link resolution result mismatch (-want +got):\n%s", diff)
}
})
diff --git a/pkg/tcpip/tests/integration/link_resolution_test.go b/pkg/tcpip/tests/integration/link_resolution_test.go
index 18da67fb1..165f73f21 100644
--- a/pkg/tcpip/tests/integration/link_resolution_test.go
+++ b/pkg/tcpip/tests/integration/link_resolution_test.go
@@ -402,34 +402,48 @@ func TestGetLinkAddress(t *testing.T) {
)
tests := []struct {
- name string
- netProto tcpip.NetworkProtocolNumber
- remoteAddr tcpip.Address
- expectedOk bool
+ name string
+ netProto tcpip.NetworkProtocolNumber
+ remoteAddr, localAddr tcpip.Address
+ expectedErr tcpip.Error
}{
{
- name: "IPv4 resolvable",
- netProto: ipv4.ProtocolNumber,
- remoteAddr: utils.Ipv4Addr2.AddressWithPrefix.Address,
- expectedOk: true,
+ name: "IPv4 resolvable",
+ netProto: ipv4.ProtocolNumber,
+ remoteAddr: utils.Ipv4Addr2.AddressWithPrefix.Address,
+ expectedErr: nil,
},
{
- name: "IPv6 resolvable",
- netProto: ipv6.ProtocolNumber,
- remoteAddr: utils.Ipv6Addr2.AddressWithPrefix.Address,
- expectedOk: true,
+ name: "IPv6 resolvable",
+ netProto: ipv6.ProtocolNumber,
+ remoteAddr: utils.Ipv6Addr2.AddressWithPrefix.Address,
+ expectedErr: nil,
},
{
- name: "IPv4 not resolvable",
- netProto: ipv4.ProtocolNumber,
- remoteAddr: utils.Ipv4Addr3.AddressWithPrefix.Address,
- expectedOk: false,
+ name: "IPv4 not resolvable",
+ netProto: ipv4.ProtocolNumber,
+ remoteAddr: utils.Ipv4Addr3.AddressWithPrefix.Address,
+ expectedErr: &tcpip.ErrTimeout{},
},
{
- name: "IPv6 not resolvable",
- netProto: ipv6.ProtocolNumber,
- remoteAddr: utils.Ipv6Addr3.AddressWithPrefix.Address,
- expectedOk: false,
+ name: "IPv6 not resolvable",
+ netProto: ipv6.ProtocolNumber,
+ remoteAddr: utils.Ipv6Addr3.AddressWithPrefix.Address,
+ expectedErr: &tcpip.ErrTimeout{},
+ },
+ {
+ name: "IPv4 bad local address",
+ netProto: ipv4.ProtocolNumber,
+ remoteAddr: utils.Ipv4Addr2.AddressWithPrefix.Address,
+ localAddr: utils.Ipv4Addr2.AddressWithPrefix.Address,
+ expectedErr: &tcpip.ErrBadLocalAddress{},
+ },
+ {
+ name: "IPv6 bad local address",
+ netProto: ipv6.ProtocolNumber,
+ remoteAddr: utils.Ipv6Addr2.AddressWithPrefix.Address,
+ localAddr: utils.Ipv6Addr2.AddressWithPrefix.Address,
+ expectedErr: &tcpip.ErrBadLocalAddress{},
},
}
@@ -442,14 +456,14 @@ func TestGetLinkAddress(t *testing.T) {
host1Stack, _ := setupStack(t, stackOpts, host1NICID, host2NICID)
ch := make(chan stack.LinkResolutionResult, 1)
- err := host1Stack.GetLinkAddress(host1NICID, test.remoteAddr, "", test.netProto, func(r stack.LinkResolutionResult) {
+ err := host1Stack.GetLinkAddress(host1NICID, test.remoteAddr, test.localAddr, test.netProto, func(r stack.LinkResolutionResult) {
ch <- r
})
if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
t.Fatalf("got host1Stack.GetLinkAddress(%d, %s, '', %d, _) = %s, want = %s", host1NICID, test.remoteAddr, test.netProto, err, &tcpip.ErrWouldBlock{})
}
- wantRes := stack.LinkResolutionResult{Success: test.expectedOk}
- if test.expectedOk {
+ wantRes := stack.LinkResolutionResult{Err: test.expectedErr}
+ if test.expectedErr == nil {
wantRes.LinkAddress = utils.LinkAddr2
}
if diff := cmp.Diff(wantRes, <-ch); diff != "" {
@@ -471,7 +485,7 @@ func TestRouteResolvedFields(t *testing.T) {
localAddr tcpip.Address
remoteAddr tcpip.Address
immediatelyResolvable bool
- expectedSuccess bool
+ expectedErr tcpip.Error
expectedLinkAddr tcpip.LinkAddress
}{
{
@@ -480,7 +494,7 @@ func TestRouteResolvedFields(t *testing.T) {
localAddr: utils.Ipv4Addr1.AddressWithPrefix.Address,
remoteAddr: header.IPv4AllSystems,
immediatelyResolvable: true,
- expectedSuccess: true,
+ expectedErr: nil,
expectedLinkAddr: header.EthernetAddressFromMulticastIPv4Address(header.IPv4AllSystems),
},
{
@@ -489,7 +503,7 @@ func TestRouteResolvedFields(t *testing.T) {
localAddr: utils.Ipv6Addr1.AddressWithPrefix.Address,
remoteAddr: header.IPv6AllNodesMulticastAddress,
immediatelyResolvable: true,
- expectedSuccess: true,
+ expectedErr: nil,
expectedLinkAddr: header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllNodesMulticastAddress),
},
{
@@ -498,7 +512,7 @@ func TestRouteResolvedFields(t *testing.T) {
localAddr: utils.Ipv4Addr1.AddressWithPrefix.Address,
remoteAddr: utils.Ipv4Addr2.AddressWithPrefix.Address,
immediatelyResolvable: false,
- expectedSuccess: true,
+ expectedErr: nil,
expectedLinkAddr: utils.LinkAddr2,
},
{
@@ -507,7 +521,7 @@ func TestRouteResolvedFields(t *testing.T) {
localAddr: utils.Ipv6Addr1.AddressWithPrefix.Address,
remoteAddr: utils.Ipv6Addr2.AddressWithPrefix.Address,
immediatelyResolvable: false,
- expectedSuccess: true,
+ expectedErr: nil,
expectedLinkAddr: utils.LinkAddr2,
},
{
@@ -516,7 +530,7 @@ func TestRouteResolvedFields(t *testing.T) {
localAddr: utils.Ipv4Addr1.AddressWithPrefix.Address,
remoteAddr: utils.Ipv4Addr3.AddressWithPrefix.Address,
immediatelyResolvable: false,
- expectedSuccess: false,
+ expectedErr: &tcpip.ErrTimeout{},
},
{
name: "IPv6 not resolvable",
@@ -524,7 +538,7 @@ func TestRouteResolvedFields(t *testing.T) {
localAddr: utils.Ipv6Addr1.AddressWithPrefix.Address,
remoteAddr: utils.Ipv6Addr3.AddressWithPrefix.Address,
immediatelyResolvable: false,
- expectedSuccess: false,
+ expectedErr: &tcpip.ErrTimeout{},
},
}
@@ -535,9 +549,9 @@ func TestRouteResolvedFields(t *testing.T) {
}
host1Stack, _ := setupStack(t, stackOpts, host1NICID, host2NICID)
- r, err := host1Stack.FindRoute(host1NICID, "", test.remoteAddr, test.netProto, false /* multicastLoop */)
+ r, err := host1Stack.FindRoute(host1NICID, test.localAddr, test.remoteAddr, test.netProto, false /* multicastLoop */)
if err != nil {
- t.Fatalf("host1Stack.FindRoute(%d, '', %s, %d, false): %s", host1NICID, test.remoteAddr, test.netProto, err)
+ t.Fatalf("host1Stack.FindRoute(%d, %s, %s, %d, false): %s", host1NICID, test.localAddr, test.remoteAddr, test.netProto, err)
}
defer r.Release()
@@ -561,11 +575,11 @@ func TestRouteResolvedFields(t *testing.T) {
if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
t.Errorf("got r.ResolvedFields(_) = %s, want = %s", err, &tcpip.ErrWouldBlock{})
}
- if diff := cmp.Diff(stack.ResolvedFieldsResult{RouteInfo: wantRouteInfo, Success: test.expectedSuccess}, <-ch, cmp.AllowUnexported(stack.RouteInfo{})); diff != "" {
+ if diff := cmp.Diff(stack.ResolvedFieldsResult{RouteInfo: wantRouteInfo, Err: test.expectedErr}, <-ch, cmp.AllowUnexported(stack.RouteInfo{})); diff != "" {
t.Errorf("route resolve result mismatch (-want +got):\n%s", diff)
}
- if !test.expectedSuccess {
+ if test.expectedErr != nil {
return
}
@@ -580,7 +594,7 @@ func TestRouteResolvedFields(t *testing.T) {
}
select {
case routeResolveRes := <-ch:
- if diff := cmp.Diff(stack.ResolvedFieldsResult{RouteInfo: wantRouteInfo, Success: true}, routeResolveRes, cmp.AllowUnexported(stack.RouteInfo{})); diff != "" {
+ if diff := cmp.Diff(stack.ResolvedFieldsResult{RouteInfo: wantRouteInfo, Err: nil}, routeResolveRes, cmp.AllowUnexported(stack.RouteInfo{})); diff != "" {
t.Errorf("route resolve result from resolved route mismatch (-want +got):\n%s", diff)
}
default:
@@ -1021,7 +1035,7 @@ func TestTCPConfirmNeighborReachability(t *testing.T) {
if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
t.Fatalf("got host1Stack.GetLinkAddress(%d, %s, '', %d, _) = %s, want = %s", utils.Host1NICID, test.neighborAddr, test.netProto, err, &tcpip.ErrWouldBlock{})
}
- if diff := cmp.Diff(stack.LinkResolutionResult{LinkAddress: utils.LinkAddr2, Success: true}, <-ch); diff != "" {
+ if diff := cmp.Diff(stack.LinkResolutionResult{LinkAddress: utils.LinkAddr2, Err: nil}, <-ch); diff != "" {
t.Fatalf("link resolution mismatch (-want +got):\n%s", diff)
}
}