Merge release-20210208.0-107-g6bc27946a (automated)
This commit is contained in:
commit
2083ef0f25
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue