Remove stack.ReadOnlyAddressableEndpointState

Startblock:
  has LGTM from asfez
  and then
  add reviewer tamird
PiperOrigin-RevId: 345815146
This commit is contained in:
Ghanan Gowripalan 2020-12-04 22:02:09 -08:00 committed by gVisor bot
parent b80021afd2
commit df2dbe3e38
3 changed files with 51 additions and 80 deletions

View File

@ -799,28 +799,12 @@ func (e *endpoint) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp boo
defer e.mu.Unlock()
loopback := e.nic.IsLoopback()
addressEndpoint := e.mu.addressableEndpointState.ReadOnly().AddrOrMatching(localAddr, allowTemp, func(addressEndpoint stack.AddressEndpoint) bool {
return e.mu.addressableEndpointState.AcquireAssignedAddressOrMatching(localAddr, func(addressEndpoint stack.AddressEndpoint) bool {
subnet := addressEndpoint.Subnet()
// IPv4 has a notion of a subnet broadcast address and considers the
// loopback interface bound to an address's whole subnet (on linux).
return subnet.IsBroadcast(localAddr) || (loopback && subnet.Contains(localAddr))
})
if addressEndpoint != nil {
return addressEndpoint
}
if !allowTemp {
return nil
}
addr := localAddr.WithPrefix()
addressEndpoint, err := e.mu.addressableEndpointState.AddAndAcquireTemporaryAddress(addr, tempPEB)
if err != nil {
// AddAddress only returns an error if the address is already assigned,
// but we just checked above if the address exists so we expect no error.
panic(fmt.Sprintf("e.mu.addressableEndpointState.AddAndAcquireTemporaryAddress(%s, %d): %s", addr, tempPEB, err))
}
return addressEndpoint
}, allowTemp, tempPEB)
}
// AcquireOutgoingPrimaryAddress implements stack.AddressableEndpoint.

View File

@ -263,7 +263,7 @@ func (e *endpoint) Enable() *tcpip.Error {
// Addresses may have aleady completed DAD but in the time since the endpoint
// was last enabled, other devices may have acquired the same addresses.
var err *tcpip.Error
e.mu.addressableEndpointState.ReadOnly().ForEach(func(addressEndpoint stack.AddressEndpoint) bool {
e.mu.addressableEndpointState.ForEachEndpoint(func(addressEndpoint stack.AddressEndpoint) bool {
addr := addressEndpoint.AddressWithPrefix().Address
if !header.IsV6UnicastAddress(addr) {
return true
@ -357,7 +357,7 @@ func (e *endpoint) disableLocked() {
// Precondition: e.mu must be write locked.
func (e *endpoint) stopDADForPermanentAddressesLocked() {
// Stop DAD for all the tentative unicast addresses.
e.mu.addressableEndpointState.ReadOnly().ForEach(func(addressEndpoint stack.AddressEndpoint) bool {
e.mu.addressableEndpointState.ForEachEndpoint(func(addressEndpoint stack.AddressEndpoint) bool {
if addressEndpoint.GetKind() != stack.PermanentTentative {
return true
}
@ -1261,7 +1261,7 @@ func (e *endpoint) hasPermanentAddressRLocked(addr tcpip.Address) bool {
//
// Precondition: e.mu must be read or write locked.
func (e *endpoint) getAddressRLocked(localAddr tcpip.Address) stack.AddressEndpoint {
return e.mu.addressableEndpointState.ReadOnly().Lookup(localAddr)
return e.mu.addressableEndpointState.GetAddress(localAddr)
}
// MainAddress implements stack.AddressableEndpoint.
@ -1312,7 +1312,7 @@ func (e *endpoint) acquireOutgoingPrimaryAddressRLocked(remoteAddr tcpip.Address
// Create a candidate set of available addresses we can potentially use as a
// source address.
var cs []addrCandidate
e.mu.addressableEndpointState.ReadOnly().ForEachPrimaryEndpoint(func(addressEndpoint stack.AddressEndpoint) {
e.mu.addressableEndpointState.ForEachPrimaryEndpoint(func(addressEndpoint stack.AddressEndpoint) {
// If r is not valid for outgoing connections, it is not a valid endpoint.
if !addressEndpoint.IsAssigned(allowExpired) {
return

View File

@ -50,62 +50,31 @@ func (a *AddressableEndpointState) Init(networkEndpoint NetworkEndpoint) {
a.mu.endpoints = make(map[tcpip.Address]*addressState)
}
// ReadOnlyAddressableEndpointState provides read-only access to an
// AddressableEndpointState.
type ReadOnlyAddressableEndpointState struct {
inner *AddressableEndpointState
}
// AddrOrMatching returns an endpoint for the passed address that is consisdered
// bound to the wrapped AddressableEndpointState.
// GetAddress returns the AddressEndpoint for the passed address.
//
// If addr is an exact match with an existing address, that address is returned.
// Otherwise, f is called with each address and the address that f returns true
// for is returned.
// GetAddress does not increment the address's reference count or check if the
// address is considered bound to the endpoint.
//
// Returns nil of no address matches.
func (m ReadOnlyAddressableEndpointState) AddrOrMatching(addr tcpip.Address, spoofingOrPrimiscuous bool, f func(AddressEndpoint) bool) AddressEndpoint {
m.inner.mu.RLock()
defer m.inner.mu.RUnlock()
// Returns nil if the passed address is not associated with the endpoint.
func (a *AddressableEndpointState) GetAddress(addr tcpip.Address) AddressEndpoint {
a.mu.RLock()
defer a.mu.RUnlock()
if ep, ok := m.inner.mu.endpoints[addr]; ok {
if ep.IsAssigned(spoofingOrPrimiscuous) && ep.IncRef() {
return ep
}
}
for _, ep := range m.inner.mu.endpoints {
if ep.IsAssigned(spoofingOrPrimiscuous) && f(ep) && ep.IncRef() {
return ep
}
}
return nil
}
// Lookup returns the AddressEndpoint for the passed address.
//
// Returns nil if the passed address is not associated with the
// AddressableEndpointState.
func (m ReadOnlyAddressableEndpointState) Lookup(addr tcpip.Address) AddressEndpoint {
m.inner.mu.RLock()
defer m.inner.mu.RUnlock()
ep, ok := m.inner.mu.endpoints[addr]
ep, ok := a.mu.endpoints[addr]
if !ok {
return nil
}
return ep
}
// ForEach calls f for each address pair.
// ForEachEndpoint calls f for each address.
//
// If f returns false, f is no longer be called.
func (m ReadOnlyAddressableEndpointState) ForEach(f func(AddressEndpoint) bool) {
m.inner.mu.RLock()
defer m.inner.mu.RUnlock()
// Once f returns false, f will no longer be called.
func (a *AddressableEndpointState) ForEachEndpoint(f func(AddressEndpoint) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for _, ep := range m.inner.mu.endpoints {
for _, ep := range a.mu.endpoints {
if !f(ep) {
return
}
@ -113,21 +82,15 @@ func (m ReadOnlyAddressableEndpointState) ForEach(f func(AddressEndpoint) bool)
}
// ForEachPrimaryEndpoint calls f for each primary address.
//
// If f returns false, f is no longer be called.
func (m ReadOnlyAddressableEndpointState) ForEachPrimaryEndpoint(f func(AddressEndpoint)) {
m.inner.mu.RLock()
defer m.inner.mu.RUnlock()
for _, ep := range m.inner.mu.primary {
func (a *AddressableEndpointState) ForEachPrimaryEndpoint(f func(AddressEndpoint)) {
a.mu.RLock()
defer a.mu.RUnlock()
for _, ep := range a.mu.primary {
f(ep)
}
}
// ReadOnly returns a readonly reference to a.
func (a *AddressableEndpointState) ReadOnly() ReadOnlyAddressableEndpointState {
return ReadOnlyAddressableEndpointState{inner: a}
}
func (a *AddressableEndpointState) releaseAddressState(addrState *addressState) {
a.mu.Lock()
defer a.mu.Unlock()
@ -460,8 +423,19 @@ func (a *AddressableEndpointState) acquirePrimaryAddressRLocked(isValid func(*ad
return deprecatedEndpoint
}
// AcquireAssignedAddress implements AddressableEndpoint.
func (a *AddressableEndpointState) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint {
// AcquireAssignedAddressOrMatching returns an address endpoint that is
// considered assigned to the addressable endpoint.
//
// If the address is an exact match with an existing address, that address is
// returned. Otherwise, if f is provided, f is called with each address and
// the address that f returns true for is returned.
//
// If there is no matching address, a temporary address will be returned if
// allowTemp is true.
//
// Regardless how the address was obtained, it will be acquired before it is
// returned.
func (a *AddressableEndpointState) AcquireAssignedAddressOrMatching(localAddr tcpip.Address, f func(AddressEndpoint) bool, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint {
a.mu.Lock()
defer a.mu.Unlock()
@ -477,6 +451,14 @@ func (a *AddressableEndpointState) AcquireAssignedAddress(localAddr tcpip.Addres
return addrState
}
if f != nil {
for _, addrState := range a.mu.endpoints {
if addrState.IsAssigned(allowTemp) && f(addrState) && addrState.IncRef() {
return addrState
}
}
}
if !allowTemp {
return nil
}
@ -509,6 +491,11 @@ func (a *AddressableEndpointState) AcquireAssignedAddress(localAddr tcpip.Addres
return ep
}
// AcquireAssignedAddress implements AddressableEndpoint.
func (a *AddressableEndpointState) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint {
return a.AcquireAssignedAddressOrMatching(localAddr, nil, allowTemp, tempPEB)
}
// AcquireOutgoingPrimaryAddress implements AddressableEndpoint.
func (a *AddressableEndpointState) AcquireOutgoingPrimaryAddress(remoteAddr tcpip.Address, allowExpired bool) AddressEndpoint {
a.mu.RLock()