inet.af/netstack@v0.0.0-20220214151720-7585b01ddccf/tcpip/stack/addressable_endpoint_state.go (about)

     1  // Copyright 2020 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package stack
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"inet.af/netstack/sync"
    21  	"inet.af/netstack/tcpip"
    22  )
    23  
    24  var _ AddressableEndpoint = (*AddressableEndpointState)(nil)
    25  
    26  // AddressableEndpointState is an implementation of an AddressableEndpoint.
    27  type AddressableEndpointState struct {
    28  	networkEndpoint NetworkEndpoint
    29  
    30  	// Lock ordering (from outer to inner lock ordering):
    31  	//
    32  	// AddressableEndpointState.mu
    33  	//   addressState.mu
    34  	mu struct {
    35  		sync.RWMutex
    36  
    37  		endpoints map[tcpip.Address]*addressState
    38  		primary   []*addressState
    39  	}
    40  }
    41  
    42  // Init initializes the AddressableEndpointState with networkEndpoint.
    43  //
    44  // Must be called before calling any other function on m.
    45  func (a *AddressableEndpointState) Init(networkEndpoint NetworkEndpoint) {
    46  	a.networkEndpoint = networkEndpoint
    47  
    48  	a.mu.Lock()
    49  	defer a.mu.Unlock()
    50  	a.mu.endpoints = make(map[tcpip.Address]*addressState)
    51  }
    52  
    53  // GetAddress returns the AddressEndpoint for the passed address.
    54  //
    55  // GetAddress does not increment the address's reference count or check if the
    56  // address is considered bound to the endpoint.
    57  //
    58  // Returns nil if the passed address is not associated with the endpoint.
    59  func (a *AddressableEndpointState) GetAddress(addr tcpip.Address) AddressEndpoint {
    60  	a.mu.RLock()
    61  	defer a.mu.RUnlock()
    62  
    63  	ep, ok := a.mu.endpoints[addr]
    64  	if !ok {
    65  		return nil
    66  	}
    67  	return ep
    68  }
    69  
    70  // ForEachEndpoint calls f for each address.
    71  //
    72  // Once f returns false, f will no longer be called.
    73  func (a *AddressableEndpointState) ForEachEndpoint(f func(AddressEndpoint) bool) {
    74  	a.mu.RLock()
    75  	defer a.mu.RUnlock()
    76  
    77  	for _, ep := range a.mu.endpoints {
    78  		if !f(ep) {
    79  			return
    80  		}
    81  	}
    82  }
    83  
    84  // ForEachPrimaryEndpoint calls f for each primary address.
    85  //
    86  // Once f returns false, f will no longer be called.
    87  func (a *AddressableEndpointState) ForEachPrimaryEndpoint(f func(AddressEndpoint) bool) {
    88  	a.mu.RLock()
    89  	defer a.mu.RUnlock()
    90  
    91  	for _, ep := range a.mu.primary {
    92  		if !f(ep) {
    93  			return
    94  		}
    95  	}
    96  }
    97  
    98  func (a *AddressableEndpointState) releaseAddressState(addrState *addressState) {
    99  	a.mu.Lock()
   100  	defer a.mu.Unlock()
   101  	a.releaseAddressStateLocked(addrState)
   102  }
   103  
   104  // releaseAddressState removes addrState from s's address state (primary and endpoints list).
   105  //
   106  // Preconditions: a.mu must be write locked.
   107  func (a *AddressableEndpointState) releaseAddressStateLocked(addrState *addressState) {
   108  	oldPrimary := a.mu.primary
   109  	for i, s := range a.mu.primary {
   110  		if s == addrState {
   111  			a.mu.primary = append(a.mu.primary[:i], a.mu.primary[i+1:]...)
   112  			oldPrimary[len(oldPrimary)-1] = nil
   113  			break
   114  		}
   115  	}
   116  	delete(a.mu.endpoints, addrState.addr.Address)
   117  }
   118  
   119  // AddAndAcquirePermanentAddress implements AddressableEndpoint.
   120  func (a *AddressableEndpointState) AddAndAcquirePermanentAddress(addr tcpip.AddressWithPrefix, properties AddressProperties) (AddressEndpoint, tcpip.Error) {
   121  	a.mu.Lock()
   122  	defer a.mu.Unlock()
   123  	ep, err := a.addAndAcquireAddressLocked(addr, properties, true /* permanent */)
   124  	// From https://golang.org/doc/faq#nil_error:
   125  	//
   126  	// Under the covers, interfaces are implemented as two elements, a type T and
   127  	// a value V.
   128  	//
   129  	// An interface value is nil only if the V and T are both unset, (T=nil, V is
   130  	// not set), In particular, a nil interface will always hold a nil type. If we
   131  	// store a nil pointer of type *int inside an interface value, the inner type
   132  	// will be *int regardless of the value of the pointer: (T=*int, V=nil). Such
   133  	// an interface value will therefore be non-nil even when the pointer value V
   134  	// inside is nil.
   135  	//
   136  	// Since addAndAcquireAddressLocked returns a nil value with a non-nil type,
   137  	// we need to explicitly return nil below if ep is (a typed) nil.
   138  	if ep == nil {
   139  		return nil, err
   140  	}
   141  	return ep, err
   142  }
   143  
   144  // AddAndAcquireTemporaryAddress adds a temporary address.
   145  //
   146  // Returns *tcpip.ErrDuplicateAddress if the address exists.
   147  //
   148  // The temporary address's endpoint is acquired and returned.
   149  func (a *AddressableEndpointState) AddAndAcquireTemporaryAddress(addr tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior) (AddressEndpoint, tcpip.Error) {
   150  	a.mu.Lock()
   151  	defer a.mu.Unlock()
   152  	ep, err := a.addAndAcquireAddressLocked(addr, AddressProperties{PEB: peb}, false /* permanent */)
   153  	// From https://golang.org/doc/faq#nil_error:
   154  	//
   155  	// Under the covers, interfaces are implemented as two elements, a type T and
   156  	// a value V.
   157  	//
   158  	// An interface value is nil only if the V and T are both unset, (T=nil, V is
   159  	// not set), In particular, a nil interface will always hold a nil type. If we
   160  	// store a nil pointer of type *int inside an interface value, the inner type
   161  	// will be *int regardless of the value of the pointer: (T=*int, V=nil). Such
   162  	// an interface value will therefore be non-nil even when the pointer value V
   163  	// inside is nil.
   164  	//
   165  	// Since addAndAcquireAddressLocked returns a nil value with a non-nil type,
   166  	// we need to explicitly return nil below if ep is (a typed) nil.
   167  	if ep == nil {
   168  		return nil, err
   169  	}
   170  	return ep, err
   171  }
   172  
   173  // addAndAcquireAddressLocked adds, acquires and returns a permanent or
   174  // temporary address.
   175  //
   176  // If the addressable endpoint already has the address in a non-permanent state,
   177  // and addAndAcquireAddressLocked is adding a permanent address, that address is
   178  // promoted in place and its properties set to the properties provided. If the
   179  // address already exists in any other state, then *tcpip.ErrDuplicateAddress is
   180  // returned, regardless the kind of address that is being added.
   181  //
   182  // Precondition: a.mu must be write locked.
   183  func (a *AddressableEndpointState) addAndAcquireAddressLocked(addr tcpip.AddressWithPrefix, properties AddressProperties, permanent bool) (*addressState, tcpip.Error) {
   184  	// attemptAddToPrimary is false when the address is already in the primary
   185  	// address list.
   186  	attemptAddToPrimary := true
   187  	addrState, ok := a.mu.endpoints[addr.Address]
   188  	if ok {
   189  		if !permanent {
   190  			// We are adding a non-permanent address but the address exists. No need
   191  			// to go any further since we can only promote existing temporary/expired
   192  			// addresses to permanent.
   193  			return nil, &tcpip.ErrDuplicateAddress{}
   194  		}
   195  
   196  		addrState.mu.Lock()
   197  		if addrState.mu.kind.IsPermanent() {
   198  			addrState.mu.Unlock()
   199  			// We are adding a permanent address but a permanent address already
   200  			// exists.
   201  			return nil, &tcpip.ErrDuplicateAddress{}
   202  		}
   203  
   204  		if addrState.mu.refs == 0 {
   205  			panic(fmt.Sprintf("found an address that should have been released (ref count == 0); address = %s", addrState.addr))
   206  		}
   207  
   208  		// We now promote the address.
   209  		for i, s := range a.mu.primary {
   210  			if s == addrState {
   211  				switch properties.PEB {
   212  				case CanBePrimaryEndpoint:
   213  					// The address is already in the primary address list.
   214  					attemptAddToPrimary = false
   215  				case FirstPrimaryEndpoint:
   216  					if i == 0 {
   217  						// The address is already first in the primary address list.
   218  						attemptAddToPrimary = false
   219  					} else {
   220  						a.mu.primary = append(a.mu.primary[:i], a.mu.primary[i+1:]...)
   221  					}
   222  				case NeverPrimaryEndpoint:
   223  					a.mu.primary = append(a.mu.primary[:i], a.mu.primary[i+1:]...)
   224  				default:
   225  					panic(fmt.Sprintf("unrecognized primary endpoint behaviour = %d", properties.PEB))
   226  				}
   227  				break
   228  			}
   229  		}
   230  	}
   231  
   232  	if addrState == nil {
   233  		addrState = &addressState{
   234  			addressableEndpointState: a,
   235  			addr:                     addr,
   236  			// Cache the subnet in addrState to avoid calls to addr.Subnet() as that
   237  			// results in allocations on every call.
   238  			subnet: addr.Subnet(),
   239  		}
   240  		a.mu.endpoints[addr.Address] = addrState
   241  		addrState.mu.Lock()
   242  		// We never promote an address to temporary - it can only be added as such.
   243  		// If we are actaully adding a permanent address, it is promoted below.
   244  		addrState.mu.kind = Temporary
   245  	}
   246  
   247  	// At this point we have an address we are either promoting from an expired or
   248  	// temporary address to permanent, promoting an expired address to temporary,
   249  	// or we are adding a new temporary or permanent address.
   250  	//
   251  	// The address MUST be write locked at this point.
   252  	defer addrState.mu.Unlock() // +checklocksforce
   253  
   254  	if permanent {
   255  		if addrState.mu.kind.IsPermanent() {
   256  			panic(fmt.Sprintf("only non-permanent addresses should be promoted to permanent; address = %s", addrState.addr))
   257  		}
   258  
   259  		// Primary addresses are biased by 1.
   260  		addrState.mu.refs++
   261  		addrState.mu.kind = Permanent
   262  	}
   263  	// Acquire the address before returning it.
   264  	addrState.mu.refs++
   265  	addrState.mu.deprecated = properties.Deprecated
   266  	addrState.mu.configType = properties.ConfigType
   267  
   268  	if attemptAddToPrimary {
   269  		switch properties.PEB {
   270  		case NeverPrimaryEndpoint:
   271  		case CanBePrimaryEndpoint:
   272  			a.mu.primary = append(a.mu.primary, addrState)
   273  		case FirstPrimaryEndpoint:
   274  			if cap(a.mu.primary) == len(a.mu.primary) {
   275  				a.mu.primary = append([]*addressState{addrState}, a.mu.primary...)
   276  			} else {
   277  				// Shift all the endpoints by 1 to make room for the new address at the
   278  				// front. We could have just created a new slice but this saves
   279  				// allocations when the slice has capacity for the new address.
   280  				primaryCount := len(a.mu.primary)
   281  				a.mu.primary = append(a.mu.primary, nil)
   282  				if n := copy(a.mu.primary[1:], a.mu.primary); n != primaryCount {
   283  					panic(fmt.Sprintf("copied %d elements; expected = %d elements", n, primaryCount))
   284  				}
   285  				a.mu.primary[0] = addrState
   286  			}
   287  		default:
   288  			panic(fmt.Sprintf("unrecognized primary endpoint behaviour = %d", properties.PEB))
   289  		}
   290  	}
   291  
   292  	return addrState, nil
   293  }
   294  
   295  // RemovePermanentAddress implements AddressableEndpoint.
   296  func (a *AddressableEndpointState) RemovePermanentAddress(addr tcpip.Address) tcpip.Error {
   297  	a.mu.Lock()
   298  	defer a.mu.Unlock()
   299  	return a.removePermanentAddressLocked(addr)
   300  }
   301  
   302  // removePermanentAddressLocked is like RemovePermanentAddress but with locking
   303  // requirements.
   304  //
   305  // Precondition: a.mu must be write locked.
   306  func (a *AddressableEndpointState) removePermanentAddressLocked(addr tcpip.Address) tcpip.Error {
   307  	addrState, ok := a.mu.endpoints[addr]
   308  	if !ok {
   309  		return &tcpip.ErrBadLocalAddress{}
   310  	}
   311  
   312  	return a.removePermanentEndpointLocked(addrState)
   313  }
   314  
   315  // RemovePermanentEndpoint removes the passed endpoint if it is associated with
   316  // a and permanent.
   317  func (a *AddressableEndpointState) RemovePermanentEndpoint(ep AddressEndpoint) tcpip.Error {
   318  	addrState, ok := ep.(*addressState)
   319  	if !ok || addrState.addressableEndpointState != a {
   320  		return &tcpip.ErrInvalidEndpointState{}
   321  	}
   322  
   323  	a.mu.Lock()
   324  	defer a.mu.Unlock()
   325  	return a.removePermanentEndpointLocked(addrState)
   326  }
   327  
   328  // removePermanentAddressLocked is like RemovePermanentAddress but with locking
   329  // requirements.
   330  //
   331  // Precondition: a.mu must be write locked.
   332  func (a *AddressableEndpointState) removePermanentEndpointLocked(addrState *addressState) tcpip.Error {
   333  	if !addrState.GetKind().IsPermanent() {
   334  		return &tcpip.ErrBadLocalAddress{}
   335  	}
   336  
   337  	addrState.SetKind(PermanentExpired)
   338  	a.decAddressRefLocked(addrState)
   339  	return nil
   340  }
   341  
   342  // decAddressRef decrements the address's reference count and releases it once
   343  // the reference count hits 0.
   344  func (a *AddressableEndpointState) decAddressRef(addrState *addressState) {
   345  	a.mu.Lock()
   346  	defer a.mu.Unlock()
   347  	a.decAddressRefLocked(addrState)
   348  }
   349  
   350  // decAddressRefLocked is like decAddressRef but with locking requirements.
   351  //
   352  // Precondition: a.mu must be write locked.
   353  func (a *AddressableEndpointState) decAddressRefLocked(addrState *addressState) {
   354  	addrState.mu.Lock()
   355  	defer addrState.mu.Unlock()
   356  
   357  	if addrState.mu.refs == 0 {
   358  		panic(fmt.Sprintf("attempted to decrease ref count for AddressEndpoint w/ addr = %s when it is already released", addrState.addr))
   359  	}
   360  
   361  	addrState.mu.refs--
   362  
   363  	if addrState.mu.refs != 0 {
   364  		return
   365  	}
   366  
   367  	// A non-expired permanent address must not have its reference count dropped
   368  	// to 0.
   369  	if addrState.mu.kind.IsPermanent() {
   370  		panic(fmt.Sprintf("permanent addresses should be removed through the AddressableEndpoint: addr = %s, kind = %d", addrState.addr, addrState.mu.kind))
   371  	}
   372  
   373  	a.releaseAddressStateLocked(addrState)
   374  }
   375  
   376  // MainAddress implements AddressableEndpoint.
   377  func (a *AddressableEndpointState) MainAddress() tcpip.AddressWithPrefix {
   378  	a.mu.RLock()
   379  	defer a.mu.RUnlock()
   380  
   381  	ep := a.acquirePrimaryAddressRLocked(func(ep *addressState) bool {
   382  		return ep.GetKind() == Permanent
   383  	})
   384  	if ep == nil {
   385  		return tcpip.AddressWithPrefix{}
   386  	}
   387  
   388  	addr := ep.AddressWithPrefix()
   389  	a.decAddressRefLocked(ep)
   390  	return addr
   391  }
   392  
   393  // acquirePrimaryAddressRLocked returns an acquired primary address that is
   394  // valid according to isValid.
   395  //
   396  // Precondition: e.mu must be read locked
   397  func (a *AddressableEndpointState) acquirePrimaryAddressRLocked(isValid func(*addressState) bool) *addressState {
   398  	var deprecatedEndpoint *addressState
   399  	for _, ep := range a.mu.primary {
   400  		if !isValid(ep) {
   401  			continue
   402  		}
   403  
   404  		if !ep.Deprecated() {
   405  			if ep.IncRef() {
   406  				// ep is not deprecated, so return it immediately.
   407  				//
   408  				// If we kept track of a deprecated endpoint, decrement its reference
   409  				// count since it was incremented when we decided to keep track of it.
   410  				if deprecatedEndpoint != nil {
   411  					a.decAddressRefLocked(deprecatedEndpoint)
   412  					deprecatedEndpoint = nil
   413  				}
   414  
   415  				return ep
   416  			}
   417  		} else if deprecatedEndpoint == nil && ep.IncRef() {
   418  			// We prefer an endpoint that is not deprecated, but we keep track of
   419  			// ep in case a doesn't have any non-deprecated endpoints.
   420  			//
   421  			// If we end up finding a more preferred endpoint, ep's reference count
   422  			// will be decremented.
   423  			deprecatedEndpoint = ep
   424  		}
   425  	}
   426  
   427  	return deprecatedEndpoint
   428  }
   429  
   430  // AcquireAssignedAddressOrMatching returns an address endpoint that is
   431  // considered assigned to the addressable endpoint.
   432  //
   433  // If the address is an exact match with an existing address, that address is
   434  // returned. Otherwise, if f is provided, f is called with each address and
   435  // the address that f returns true for is returned.
   436  //
   437  // If there is no matching address, a temporary address will be returned if
   438  // allowTemp is true.
   439  //
   440  // Regardless how the address was obtained, it will be acquired before it is
   441  // returned.
   442  func (a *AddressableEndpointState) AcquireAssignedAddressOrMatching(localAddr tcpip.Address, f func(AddressEndpoint) bool, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint {
   443  	lookup := func() *addressState {
   444  		if addrState, ok := a.mu.endpoints[localAddr]; ok {
   445  			if !addrState.IsAssigned(allowTemp) {
   446  				return nil
   447  			}
   448  
   449  			if !addrState.IncRef() {
   450  				panic(fmt.Sprintf("failed to increase the reference count for address = %s", addrState.addr))
   451  			}
   452  
   453  			return addrState
   454  		}
   455  
   456  		if f != nil {
   457  			for _, addrState := range a.mu.endpoints {
   458  				if addrState.IsAssigned(allowTemp) && f(addrState) && addrState.IncRef() {
   459  					return addrState
   460  				}
   461  			}
   462  		}
   463  		return nil
   464  	}
   465  	// Avoid exclusive lock on mu unless we need to add a new address.
   466  	a.mu.RLock()
   467  	ep := lookup()
   468  	a.mu.RUnlock()
   469  
   470  	if ep != nil {
   471  		return ep
   472  	}
   473  
   474  	if !allowTemp {
   475  		return nil
   476  	}
   477  
   478  	// Acquire state lock in exclusive mode as we need to add a new temporary
   479  	// endpoint.
   480  	a.mu.Lock()
   481  	defer a.mu.Unlock()
   482  
   483  	// Do the lookup again in case another goroutine added the address in the time
   484  	// we released and acquired the lock.
   485  	ep = lookup()
   486  	if ep != nil {
   487  		return ep
   488  	}
   489  
   490  	// Proceed to add a new temporary endpoint.
   491  	addr := localAddr.WithPrefix()
   492  	ep, err := a.addAndAcquireAddressLocked(addr, AddressProperties{PEB: tempPEB}, false /* permanent */)
   493  	if err != nil {
   494  		// addAndAcquireAddressLocked only returns an error if the address is
   495  		// already assigned but we just checked above if the address exists so we
   496  		// expect no error.
   497  		panic(fmt.Sprintf("a.addAndAcquireAddressLocked(%s, AddressProperties{PEB: %s}, false): %s", addr, tempPEB, err))
   498  	}
   499  
   500  	// From https://golang.org/doc/faq#nil_error:
   501  	//
   502  	// Under the covers, interfaces are implemented as two elements, a type T and
   503  	// a value V.
   504  	//
   505  	// An interface value is nil only if the V and T are both unset, (T=nil, V is
   506  	// not set), In particular, a nil interface will always hold a nil type. If we
   507  	// store a nil pointer of type *int inside an interface value, the inner type
   508  	// will be *int regardless of the value of the pointer: (T=*int, V=nil). Such
   509  	// an interface value will therefore be non-nil even when the pointer value V
   510  	// inside is nil.
   511  	//
   512  	// Since addAndAcquireAddressLocked returns a nil value with a non-nil type,
   513  	// we need to explicitly return nil below if ep is (a typed) nil.
   514  	if ep == nil {
   515  		return nil
   516  	}
   517  	return ep
   518  }
   519  
   520  // AcquireAssignedAddress implements AddressableEndpoint.
   521  func (a *AddressableEndpointState) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint {
   522  	return a.AcquireAssignedAddressOrMatching(localAddr, nil, allowTemp, tempPEB)
   523  }
   524  
   525  // AcquireOutgoingPrimaryAddress implements AddressableEndpoint.
   526  func (a *AddressableEndpointState) AcquireOutgoingPrimaryAddress(remoteAddr tcpip.Address, allowExpired bool) AddressEndpoint {
   527  	a.mu.RLock()
   528  	defer a.mu.RUnlock()
   529  
   530  	ep := a.acquirePrimaryAddressRLocked(func(ep *addressState) bool {
   531  		return ep.IsAssigned(allowExpired)
   532  	})
   533  
   534  	// From https://golang.org/doc/faq#nil_error:
   535  	//
   536  	// Under the covers, interfaces are implemented as two elements, a type T and
   537  	// a value V.
   538  	//
   539  	// An interface value is nil only if the V and T are both unset, (T=nil, V is
   540  	// not set), In particular, a nil interface will always hold a nil type. If we
   541  	// store a nil pointer of type *int inside an interface value, the inner type
   542  	// will be *int regardless of the value of the pointer: (T=*int, V=nil). Such
   543  	// an interface value will therefore be non-nil even when the pointer value V
   544  	// inside is nil.
   545  	//
   546  	// Since acquirePrimaryAddressRLocked returns a nil value with a non-nil type,
   547  	// we need to explicitly return nil below if ep is (a typed) nil.
   548  	if ep == nil {
   549  		return nil
   550  	}
   551  
   552  	return ep
   553  }
   554  
   555  // PrimaryAddresses implements AddressableEndpoint.
   556  func (a *AddressableEndpointState) PrimaryAddresses() []tcpip.AddressWithPrefix {
   557  	a.mu.RLock()
   558  	defer a.mu.RUnlock()
   559  
   560  	var addrs []tcpip.AddressWithPrefix
   561  	for _, ep := range a.mu.primary {
   562  		// Don't include tentative, expired or temporary endpoints
   563  		// to avoid confusion and prevent the caller from using
   564  		// those.
   565  		switch ep.GetKind() {
   566  		case PermanentTentative, PermanentExpired, Temporary:
   567  			continue
   568  		}
   569  
   570  		addrs = append(addrs, ep.AddressWithPrefix())
   571  	}
   572  
   573  	return addrs
   574  }
   575  
   576  // PermanentAddresses implements AddressableEndpoint.
   577  func (a *AddressableEndpointState) PermanentAddresses() []tcpip.AddressWithPrefix {
   578  	a.mu.RLock()
   579  	defer a.mu.RUnlock()
   580  
   581  	var addrs []tcpip.AddressWithPrefix
   582  	for _, ep := range a.mu.endpoints {
   583  		if !ep.GetKind().IsPermanent() {
   584  			continue
   585  		}
   586  
   587  		addrs = append(addrs, ep.AddressWithPrefix())
   588  	}
   589  
   590  	return addrs
   591  }
   592  
   593  // Cleanup forcefully leaves all groups and removes all permanent addresses.
   594  func (a *AddressableEndpointState) Cleanup() {
   595  	a.mu.Lock()
   596  	defer a.mu.Unlock()
   597  
   598  	for _, ep := range a.mu.endpoints {
   599  		// removePermanentEndpointLocked returns *tcpip.ErrBadLocalAddress if ep is
   600  		// not a permanent address.
   601  		switch err := a.removePermanentEndpointLocked(ep); err.(type) {
   602  		case nil, *tcpip.ErrBadLocalAddress:
   603  		default:
   604  			panic(fmt.Sprintf("unexpected error from removePermanentEndpointLocked(%s): %s", ep.addr, err))
   605  		}
   606  	}
   607  }
   608  
   609  var _ AddressEndpoint = (*addressState)(nil)
   610  
   611  // addressState holds state for an address.
   612  type addressState struct {
   613  	addressableEndpointState *AddressableEndpointState
   614  	addr                     tcpip.AddressWithPrefix
   615  	subnet                   tcpip.Subnet
   616  	// Lock ordering (from outer to inner lock ordering):
   617  	//
   618  	// AddressableEndpointState.mu
   619  	//   addressState.mu
   620  	mu struct {
   621  		sync.RWMutex
   622  
   623  		refs       uint32
   624  		kind       AddressKind
   625  		configType AddressConfigType
   626  		deprecated bool
   627  	}
   628  }
   629  
   630  // AddressWithPrefix implements AddressEndpoint.
   631  func (a *addressState) AddressWithPrefix() tcpip.AddressWithPrefix {
   632  	return a.addr
   633  }
   634  
   635  // Subnet implements AddressEndpoint.
   636  func (a *addressState) Subnet() tcpip.Subnet {
   637  	return a.subnet
   638  }
   639  
   640  // GetKind implements AddressEndpoint.
   641  func (a *addressState) GetKind() AddressKind {
   642  	a.mu.RLock()
   643  	defer a.mu.RUnlock()
   644  	return a.mu.kind
   645  }
   646  
   647  // SetKind implements AddressEndpoint.
   648  func (a *addressState) SetKind(kind AddressKind) {
   649  	a.mu.Lock()
   650  	defer a.mu.Unlock()
   651  	a.mu.kind = kind
   652  }
   653  
   654  // IsAssigned implements AddressEndpoint.
   655  func (a *addressState) IsAssigned(allowExpired bool) bool {
   656  	if !a.addressableEndpointState.networkEndpoint.Enabled() {
   657  		return false
   658  	}
   659  
   660  	switch a.GetKind() {
   661  	case PermanentTentative:
   662  		return false
   663  	case PermanentExpired:
   664  		return allowExpired
   665  	default:
   666  		return true
   667  	}
   668  }
   669  
   670  // IncRef implements AddressEndpoint.
   671  func (a *addressState) IncRef() bool {
   672  	a.mu.Lock()
   673  	defer a.mu.Unlock()
   674  	if a.mu.refs == 0 {
   675  		return false
   676  	}
   677  
   678  	a.mu.refs++
   679  	return true
   680  }
   681  
   682  // DecRef implements AddressEndpoint.
   683  func (a *addressState) DecRef() {
   684  	a.addressableEndpointState.decAddressRef(a)
   685  }
   686  
   687  // ConfigType implements AddressEndpoint.
   688  func (a *addressState) ConfigType() AddressConfigType {
   689  	a.mu.RLock()
   690  	defer a.mu.RUnlock()
   691  	return a.mu.configType
   692  }
   693  
   694  // SetDeprecated implements AddressEndpoint.
   695  func (a *addressState) SetDeprecated(d bool) {
   696  	a.mu.Lock()
   697  	defer a.mu.Unlock()
   698  	a.mu.deprecated = d
   699  }
   700  
   701  // Deprecated implements AddressEndpoint.
   702  func (a *addressState) Deprecated() bool {
   703  	a.mu.RLock()
   704  	defer a.mu.RUnlock()
   705  	return a.mu.deprecated
   706  }