github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/pkg/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  	"github.com/MerlinKodo/gvisor/pkg/tcpip"
    21  	"github.com/MerlinKodo/gvisor/pkg/tcpip/header"
    22  )
    23  
    24  func (lifetimes *AddressLifetimes) sanitize() {
    25  	if lifetimes.Deprecated {
    26  		lifetimes.PreferredUntil = tcpip.MonotonicTime{}
    27  	}
    28  }
    29  
    30  var _ AddressableEndpoint = (*AddressableEndpointState)(nil)
    31  
    32  // AddressableEndpointState is an implementation of an AddressableEndpoint.
    33  type AddressableEndpointState struct {
    34  	networkEndpoint NetworkEndpoint
    35  	options         AddressableEndpointStateOptions
    36  
    37  	// Lock ordering (from outer to inner lock ordering):
    38  	//
    39  	// AddressableEndpointState.mu
    40  	//   addressState.mu
    41  	mu addressableEndpointStateRWMutex
    42  	// +checklocks:mu
    43  	endpoints map[tcpip.Address]*addressState
    44  	// +checklocks:mu
    45  	primary []*addressState
    46  }
    47  
    48  // AddressableEndpointStateOptions contains options used to configure an
    49  // AddressableEndpointState.
    50  type AddressableEndpointStateOptions struct {
    51  	// HiddenWhileDisabled determines whether addresses should be returned to
    52  	// callers while the NetworkEndpoint this AddressableEndpointState belongs
    53  	// to is disabled.
    54  	HiddenWhileDisabled bool
    55  }
    56  
    57  // Init initializes the AddressableEndpointState with networkEndpoint.
    58  //
    59  // Must be called before calling any other function on m.
    60  func (a *AddressableEndpointState) Init(networkEndpoint NetworkEndpoint, options AddressableEndpointStateOptions) {
    61  	a.networkEndpoint = networkEndpoint
    62  	a.options = options
    63  
    64  	a.mu.Lock()
    65  	defer a.mu.Unlock()
    66  	a.endpoints = make(map[tcpip.Address]*addressState)
    67  }
    68  
    69  // OnNetworkEndpointEnabledChanged must be called every time the
    70  // NetworkEndpoint this AddressableEndpointState belongs to is enabled or
    71  // disabled so that any AddressDispatchers can be notified of the NIC enabled
    72  // change.
    73  func (a *AddressableEndpointState) OnNetworkEndpointEnabledChanged() {
    74  	a.mu.RLock()
    75  	defer a.mu.RUnlock()
    76  
    77  	for _, ep := range a.endpoints {
    78  		ep.mu.Lock()
    79  		ep.notifyChangedLocked()
    80  		ep.mu.Unlock()
    81  	}
    82  }
    83  
    84  // GetAddress returns the AddressEndpoint for the passed address.
    85  //
    86  // GetAddress does not increment the address's reference count or check if the
    87  // address is considered bound to the endpoint.
    88  //
    89  // Returns nil if the passed address is not associated with the endpoint.
    90  func (a *AddressableEndpointState) GetAddress(addr tcpip.Address) AddressEndpoint {
    91  	a.mu.RLock()
    92  	defer a.mu.RUnlock()
    93  
    94  	ep, ok := a.endpoints[addr]
    95  	if !ok {
    96  		return nil
    97  	}
    98  	return ep
    99  }
   100  
   101  // ForEachEndpoint calls f for each address.
   102  //
   103  // Once f returns false, f will no longer be called.
   104  func (a *AddressableEndpointState) ForEachEndpoint(f func(AddressEndpoint) bool) {
   105  	a.mu.RLock()
   106  	defer a.mu.RUnlock()
   107  
   108  	for _, ep := range a.endpoints {
   109  		if !f(ep) {
   110  			return
   111  		}
   112  	}
   113  }
   114  
   115  // ForEachPrimaryEndpoint calls f for each primary address.
   116  //
   117  // Once f returns false, f will no longer be called.
   118  func (a *AddressableEndpointState) ForEachPrimaryEndpoint(f func(AddressEndpoint) bool) {
   119  	a.mu.RLock()
   120  	defer a.mu.RUnlock()
   121  
   122  	for _, ep := range a.primary {
   123  		if !f(ep) {
   124  			return
   125  		}
   126  	}
   127  }
   128  
   129  func (a *AddressableEndpointState) releaseAddressState(addrState *addressState) {
   130  	a.mu.Lock()
   131  	defer a.mu.Unlock()
   132  	a.releaseAddressStateLocked(addrState)
   133  }
   134  
   135  // releaseAddressStateLocked removes addrState from a's address state
   136  // (primary and endpoints list).
   137  //
   138  // +checklocks:a.mu
   139  func (a *AddressableEndpointState) releaseAddressStateLocked(addrState *addressState) {
   140  	oldPrimary := a.primary
   141  	for i, s := range a.primary {
   142  		if s == addrState {
   143  			a.primary = append(a.primary[:i], a.primary[i+1:]...)
   144  			oldPrimary[len(oldPrimary)-1] = nil
   145  			break
   146  		}
   147  	}
   148  	delete(a.endpoints, addrState.addr.Address)
   149  }
   150  
   151  // AddAndAcquirePermanentAddress implements AddressableEndpoint.
   152  func (a *AddressableEndpointState) AddAndAcquirePermanentAddress(addr tcpip.AddressWithPrefix, properties AddressProperties) (AddressEndpoint, tcpip.Error) {
   153  	return a.AddAndAcquireAddress(addr, properties, Permanent)
   154  }
   155  
   156  // AddAndAcquireTemporaryAddress adds a temporary address.
   157  //
   158  // Returns *tcpip.ErrDuplicateAddress if the address exists.
   159  //
   160  // The temporary address's endpoint is acquired and returned.
   161  func (a *AddressableEndpointState) AddAndAcquireTemporaryAddress(addr tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior) (AddressEndpoint, tcpip.Error) {
   162  	return a.AddAndAcquireAddress(addr, AddressProperties{PEB: peb}, Temporary)
   163  }
   164  
   165  // AddAndAcquireAddress adds an address with the specified kind.
   166  //
   167  // Returns *tcpip.ErrDuplicateAddress if the address exists.
   168  func (a *AddressableEndpointState) AddAndAcquireAddress(addr tcpip.AddressWithPrefix, properties AddressProperties, kind AddressKind) (AddressEndpoint, tcpip.Error) {
   169  	a.mu.Lock()
   170  	defer a.mu.Unlock()
   171  	ep, err := a.addAndAcquireAddressLocked(addr, properties, kind)
   172  	// From https://golang.org/doc/faq#nil_error:
   173  	//
   174  	// Under the covers, interfaces are implemented as two elements, a type T and
   175  	// a value V.
   176  	//
   177  	// An interface value is nil only if the V and T are both unset, (T=nil, V is
   178  	// not set), In particular, a nil interface will always hold a nil type. If we
   179  	// store a nil pointer of type *int inside an interface value, the inner type
   180  	// will be *int regardless of the value of the pointer: (T=*int, V=nil). Such
   181  	// an interface value will therefore be non-nil even when the pointer value V
   182  	// inside is nil.
   183  	//
   184  	// Since addAndAcquireAddressLocked returns a nil value with a non-nil type,
   185  	// we need to explicitly return nil below if ep is (a typed) nil.
   186  	if ep == nil {
   187  		return nil, err
   188  	}
   189  	return ep, err
   190  }
   191  
   192  // addAndAcquireAddressLocked adds, acquires and returns a permanent or
   193  // temporary address.
   194  //
   195  // If the addressable endpoint already has the address in a non-permanent state,
   196  // and addAndAcquireAddressLocked is adding a permanent address, that address is
   197  // promoted in place and its properties set to the properties provided. If the
   198  // address already exists in any other state, then *tcpip.ErrDuplicateAddress is
   199  // returned, regardless the kind of address that is being added.
   200  //
   201  // +checklocks:a.mu
   202  func (a *AddressableEndpointState) addAndAcquireAddressLocked(addr tcpip.AddressWithPrefix, properties AddressProperties, kind AddressKind) (*addressState, tcpip.Error) {
   203  	var permanent bool
   204  	switch kind {
   205  	case PermanentExpired:
   206  		panic(fmt.Sprintf("cannot add address %s in PermanentExpired state", addr))
   207  	case Permanent, PermanentTentative:
   208  		permanent = true
   209  	case Temporary:
   210  	default:
   211  		panic(fmt.Sprintf("unknown address kind: %d", kind))
   212  	}
   213  	// attemptAddToPrimary is false when the address is already in the primary
   214  	// address list.
   215  	attemptAddToPrimary := true
   216  	addrState, ok := a.endpoints[addr.Address]
   217  	if ok {
   218  		if !permanent {
   219  			// We are adding a non-permanent address but the address exists. No need
   220  			// to go any further since we can only promote existing temporary/expired
   221  			// addresses to permanent.
   222  			return nil, &tcpip.ErrDuplicateAddress{}
   223  		}
   224  
   225  		addrState.mu.RLock()
   226  		if addrState.refs.ReadRefs() == 0 {
   227  			panic(fmt.Sprintf("found an address that should have been released (ref count == 0); address = %s", addrState.addr))
   228  		}
   229  		isPermanent := addrState.kind.IsPermanent()
   230  		addrState.mu.RUnlock()
   231  
   232  		if isPermanent {
   233  			// We are adding a permanent address but a permanent address already
   234  			// exists.
   235  			return nil, &tcpip.ErrDuplicateAddress{}
   236  		}
   237  
   238  		// We now promote the address.
   239  		for i, s := range a.primary {
   240  			if s == addrState {
   241  				switch properties.PEB {
   242  				case CanBePrimaryEndpoint:
   243  					// The address is already in the primary address list.
   244  					attemptAddToPrimary = false
   245  				case FirstPrimaryEndpoint:
   246  					if i == 0 {
   247  						// The address is already first in the primary address list.
   248  						attemptAddToPrimary = false
   249  					} else {
   250  						a.primary = append(a.primary[:i], a.primary[i+1:]...)
   251  					}
   252  				case NeverPrimaryEndpoint:
   253  					a.primary = append(a.primary[:i], a.primary[i+1:]...)
   254  				default:
   255  					panic(fmt.Sprintf("unrecognized primary endpoint behaviour = %d", properties.PEB))
   256  				}
   257  				break
   258  			}
   259  		}
   260  		addrState.refs.IncRef()
   261  	} else {
   262  		addrState = &addressState{
   263  			addressableEndpointState: a,
   264  			addr:                     addr,
   265  			temporary:                properties.Temporary,
   266  			// Cache the subnet in addrState to avoid calls to addr.Subnet() as that
   267  			// results in allocations on every call.
   268  			subnet: addr.Subnet(),
   269  		}
   270  		addrState.refs.InitRefs()
   271  		a.endpoints[addr.Address] = addrState
   272  		// We never promote an address to temporary - it can only be added as such.
   273  		// If we are actually adding a permanent address, it is promoted below.
   274  		addrState.kind = Temporary
   275  	}
   276  
   277  	// At this point we have an address we are either promoting from an expired or
   278  	// temporary address to permanent, promoting an expired address to temporary,
   279  	// or we are adding a new temporary or permanent address.
   280  	//
   281  	// The address MUST be write locked at this point.
   282  	addrState.mu.Lock()
   283  	defer addrState.mu.Unlock()
   284  
   285  	if permanent {
   286  		if addrState.kind.IsPermanent() {
   287  			panic(fmt.Sprintf("only non-permanent addresses should be promoted to permanent; address = %s", addrState.addr))
   288  		}
   289  
   290  		// Primary addresses are biased by 1.
   291  		addrState.refs.IncRef()
   292  		addrState.kind = kind
   293  	}
   294  	addrState.configType = properties.ConfigType
   295  	lifetimes := properties.Lifetimes
   296  	lifetimes.sanitize()
   297  	addrState.lifetimes = lifetimes
   298  	addrState.disp = properties.Disp
   299  
   300  	if attemptAddToPrimary {
   301  		switch properties.PEB {
   302  		case NeverPrimaryEndpoint:
   303  		case CanBePrimaryEndpoint:
   304  			a.primary = append(a.primary, addrState)
   305  		case FirstPrimaryEndpoint:
   306  			if cap(a.primary) == len(a.primary) {
   307  				a.primary = append([]*addressState{addrState}, a.primary...)
   308  			} else {
   309  				// Shift all the endpoints by 1 to make room for the new address at the
   310  				// front. We could have just created a new slice but this saves
   311  				// allocations when the slice has capacity for the new address.
   312  				primaryCount := len(a.primary)
   313  				a.primary = append(a.primary, nil)
   314  				if n := copy(a.primary[1:], a.primary); n != primaryCount {
   315  					panic(fmt.Sprintf("copied %d elements; expected = %d elements", n, primaryCount))
   316  				}
   317  				a.primary[0] = addrState
   318  			}
   319  		default:
   320  			panic(fmt.Sprintf("unrecognized primary endpoint behaviour = %d", properties.PEB))
   321  		}
   322  	}
   323  
   324  	addrState.notifyChangedLocked()
   325  	return addrState, nil
   326  }
   327  
   328  // RemovePermanentAddress implements AddressableEndpoint.
   329  func (a *AddressableEndpointState) RemovePermanentAddress(addr tcpip.Address) tcpip.Error {
   330  	a.mu.Lock()
   331  	defer a.mu.Unlock()
   332  	return a.removePermanentAddressLocked(addr)
   333  }
   334  
   335  // removePermanentAddressLocked is like RemovePermanentAddress but with locking
   336  // requirements.
   337  //
   338  // +checklocks:a.mu
   339  func (a *AddressableEndpointState) removePermanentAddressLocked(addr tcpip.Address) tcpip.Error {
   340  	addrState, ok := a.endpoints[addr]
   341  	if !ok {
   342  		return &tcpip.ErrBadLocalAddress{}
   343  	}
   344  
   345  	return a.removePermanentEndpointLocked(addrState, AddressRemovalManualAction)
   346  }
   347  
   348  // RemovePermanentEndpoint removes the passed endpoint if it is associated with
   349  // a and permanent.
   350  func (a *AddressableEndpointState) RemovePermanentEndpoint(ep AddressEndpoint, reason AddressRemovalReason) tcpip.Error {
   351  	addrState, ok := ep.(*addressState)
   352  	if !ok || addrState.addressableEndpointState != a {
   353  		return &tcpip.ErrInvalidEndpointState{}
   354  	}
   355  
   356  	a.mu.Lock()
   357  	defer a.mu.Unlock()
   358  	return a.removePermanentEndpointLocked(addrState, reason)
   359  }
   360  
   361  // removePermanentAddressLocked is like RemovePermanentAddress but with locking
   362  // requirements.
   363  //
   364  // +checklocks:a.mu
   365  func (a *AddressableEndpointState) removePermanentEndpointLocked(addrState *addressState, reason AddressRemovalReason) tcpip.Error {
   366  	if !addrState.GetKind().IsPermanent() {
   367  		return &tcpip.ErrBadLocalAddress{}
   368  	}
   369  
   370  	addrState.remove(reason)
   371  	a.decAddressRefLocked(addrState)
   372  	return nil
   373  }
   374  
   375  // decAddressRef decrements the address's reference count and releases it once
   376  // the reference count hits 0.
   377  func (a *AddressableEndpointState) decAddressRef(addrState *addressState) {
   378  	a.mu.Lock()
   379  	defer a.mu.Unlock()
   380  	a.decAddressRefLocked(addrState)
   381  }
   382  
   383  // decAddressRefLocked is like decAddressRef but with locking requirements.
   384  //
   385  // +checklocks:a.mu
   386  func (a *AddressableEndpointState) decAddressRefLocked(addrState *addressState) {
   387  	destroy := false
   388  	addrState.refs.DecRef(func() {
   389  		destroy = true
   390  	})
   391  
   392  	if !destroy {
   393  		return
   394  	}
   395  	addrState.mu.Lock()
   396  	defer addrState.mu.Unlock()
   397  	// A non-expired permanent address must not have its reference count dropped
   398  	// to 0.
   399  	if addrState.kind.IsPermanent() {
   400  		panic(fmt.Sprintf("permanent addresses should be removed through the AddressableEndpoint: addr = %s, kind = %d", addrState.addr, addrState.kind))
   401  	}
   402  
   403  	a.releaseAddressStateLocked(addrState)
   404  }
   405  
   406  // SetDeprecated implements stack.AddressableEndpoint.
   407  func (a *AddressableEndpointState) SetDeprecated(addr tcpip.Address, deprecated bool) tcpip.Error {
   408  	a.mu.RLock()
   409  	defer a.mu.RUnlock()
   410  
   411  	addrState, ok := a.endpoints[addr]
   412  	if !ok {
   413  		return &tcpip.ErrBadLocalAddress{}
   414  	}
   415  	addrState.SetDeprecated(deprecated)
   416  	return nil
   417  }
   418  
   419  // SetLifetimes implements stack.AddressableEndpoint.
   420  func (a *AddressableEndpointState) SetLifetimes(addr tcpip.Address, lifetimes AddressLifetimes) tcpip.Error {
   421  	a.mu.RLock()
   422  	defer a.mu.RUnlock()
   423  
   424  	addrState, ok := a.endpoints[addr]
   425  	if !ok {
   426  		return &tcpip.ErrBadLocalAddress{}
   427  	}
   428  	addrState.SetLifetimes(lifetimes)
   429  	return nil
   430  }
   431  
   432  // MainAddress implements AddressableEndpoint.
   433  func (a *AddressableEndpointState) MainAddress() tcpip.AddressWithPrefix {
   434  	a.mu.RLock()
   435  	defer a.mu.RUnlock()
   436  
   437  	ep := a.acquirePrimaryAddressRLocked(tcpip.Address{}, func(ep *addressState) bool {
   438  		switch kind := ep.GetKind(); kind {
   439  		case Permanent:
   440  			return a.networkEndpoint.Enabled() || !a.options.HiddenWhileDisabled
   441  		case PermanentTentative, PermanentExpired, Temporary:
   442  			return false
   443  		default:
   444  			panic(fmt.Sprintf("unknown address kind: %d", kind))
   445  		}
   446  	})
   447  	if ep == nil {
   448  		return tcpip.AddressWithPrefix{}
   449  	}
   450  	addr := ep.AddressWithPrefix()
   451  	// Note that when ep must have a ref count >=2, because its ref count
   452  	// must be >=1 in order to be found and the ref count was incremented
   453  	// when a reference was acquired. The only way for the ref count to
   454  	// drop below 2 is for the endpoint to be removed, which requires a
   455  	// write lock; so we're guaranteed to be able to decrement the ref
   456  	// count and not need to remove the endpoint from a.primary.
   457  	ep.decRefMustNotFree()
   458  	return addr
   459  }
   460  
   461  // acquirePrimaryAddressRLocked returns an acquired primary address that is
   462  // valid according to isValid.
   463  //
   464  // +checklocksread:a.mu
   465  func (a *AddressableEndpointState) acquirePrimaryAddressRLocked(remoteAddr tcpip.Address, isValid func(*addressState) bool) *addressState {
   466  	// TODO: Move this out into IPv4-specific code.
   467  	// IPv6 handles source IP selection elsewhere. We have to do source
   468  	// selection only for IPv4, in which case ep is never deprecated. Thus
   469  	// we don't have to worry about refcounts.
   470  	if remoteAddr.Len() == header.IPv4AddressSize && remoteAddr != (tcpip.Address{}) {
   471  		var best *addressState
   472  		var bestLen uint8
   473  		for _, state := range a.primary {
   474  			if !isValid(state) {
   475  				continue
   476  			}
   477  			stateLen := state.addr.Address.MatchingPrefix(remoteAddr)
   478  			if best == nil || bestLen < stateLen {
   479  				best = state
   480  				bestLen = stateLen
   481  			}
   482  		}
   483  		if best != nil {
   484  			best.IncRef()
   485  		}
   486  		return best
   487  	}
   488  
   489  	var deprecatedEndpoint *addressState
   490  	for _, ep := range a.primary {
   491  		if !isValid(ep) {
   492  			continue
   493  		}
   494  
   495  		if !ep.Deprecated() {
   496  			if ep.IncRef() {
   497  				// ep is not deprecated, so return it immediately.
   498  				//
   499  				// If we kept track of a deprecated endpoint, decrement its reference
   500  				// count since it was incremented when we decided to keep track of it.
   501  				if deprecatedEndpoint != nil {
   502  					// Note that when deprecatedEndpoint was found, its ref count
   503  					// must have necessarily been >=1, and after incrementing it
   504  					// must be >=2. The only way for the ref count to drop below 2 is
   505  					// for the endpoint to be removed, which requires a write lock;
   506  					// so we're guaranteed to be able to decrement the ref count
   507  					// and not need to remove the endpoint from a.primary.
   508  					deprecatedEndpoint.decRefMustNotFree()
   509  				}
   510  
   511  				return ep
   512  			}
   513  		} else if deprecatedEndpoint == nil && ep.IncRef() {
   514  			// We prefer an endpoint that is not deprecated, but we keep track of
   515  			// ep in case a doesn't have any non-deprecated endpoints.
   516  			//
   517  			// If we end up finding a more preferred endpoint, ep's reference count
   518  			// will be decremented.
   519  			deprecatedEndpoint = ep
   520  		}
   521  	}
   522  
   523  	return deprecatedEndpoint
   524  }
   525  
   526  // AcquireAssignedAddressOrMatching returns an address endpoint that is
   527  // considered assigned to the addressable endpoint.
   528  //
   529  // If the address is an exact match with an existing address, that address is
   530  // returned. Otherwise, if f is provided, f is called with each address and
   531  // the address that f returns true for is returned.
   532  //
   533  // If there is no matching address, a temporary address will be returned if
   534  // allowTemp is true.
   535  //
   536  // Regardless how the address was obtained, it will be acquired before it is
   537  // returned.
   538  func (a *AddressableEndpointState) AcquireAssignedAddressOrMatching(localAddr tcpip.Address, f func(AddressEndpoint) bool, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint {
   539  	lookup := func() *addressState {
   540  		if addrState, ok := a.endpoints[localAddr]; ok {
   541  			if !addrState.IsAssigned(allowTemp) {
   542  				return nil
   543  			}
   544  
   545  			if !addrState.IncRef() {
   546  				panic(fmt.Sprintf("failed to increase the reference count for address = %s", addrState.addr))
   547  			}
   548  
   549  			return addrState
   550  		}
   551  
   552  		if f != nil {
   553  			for _, addrState := range a.endpoints {
   554  				if addrState.IsAssigned(allowTemp) && f(addrState) && addrState.IncRef() {
   555  					return addrState
   556  				}
   557  			}
   558  		}
   559  		return nil
   560  	}
   561  	// Avoid exclusive lock on mu unless we need to add a new address.
   562  	a.mu.RLock()
   563  	ep := lookup()
   564  	a.mu.RUnlock()
   565  
   566  	if ep != nil {
   567  		return ep
   568  	}
   569  
   570  	if !allowTemp {
   571  		return nil
   572  	}
   573  
   574  	// Acquire state lock in exclusive mode as we need to add a new temporary
   575  	// endpoint.
   576  	a.mu.Lock()
   577  	defer a.mu.Unlock()
   578  
   579  	// Do the lookup again in case another goroutine added the address in the time
   580  	// we released and acquired the lock.
   581  	ep = lookup()
   582  	if ep != nil {
   583  		return ep
   584  	}
   585  
   586  	// Proceed to add a new temporary endpoint.
   587  	addr := localAddr.WithPrefix()
   588  	ep, err := a.addAndAcquireAddressLocked(addr, AddressProperties{PEB: tempPEB}, Temporary)
   589  	if err != nil {
   590  		// addAndAcquireAddressLocked only returns an error if the address is
   591  		// already assigned but we just checked above if the address exists so we
   592  		// expect no error.
   593  		panic(fmt.Sprintf("a.addAndAcquireAddressLocked(%s, AddressProperties{PEB: %s}, false): %s", addr, tempPEB, err))
   594  	}
   595  
   596  	// From https://golang.org/doc/faq#nil_error:
   597  	//
   598  	// Under the covers, interfaces are implemented as two elements, a type T and
   599  	// a value V.
   600  	//
   601  	// An interface value is nil only if the V and T are both unset, (T=nil, V is
   602  	// not set), In particular, a nil interface will always hold a nil type. If we
   603  	// store a nil pointer of type *int inside an interface value, the inner type
   604  	// will be *int regardless of the value of the pointer: (T=*int, V=nil). Such
   605  	// an interface value will therefore be non-nil even when the pointer value V
   606  	// inside is nil.
   607  	//
   608  	// Since addAndAcquireAddressLocked returns a nil value with a non-nil type,
   609  	// we need to explicitly return nil below if ep is (a typed) nil.
   610  	if ep == nil {
   611  		return nil
   612  	}
   613  	return ep
   614  }
   615  
   616  // AcquireAssignedAddress implements AddressableEndpoint.
   617  func (a *AddressableEndpointState) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint {
   618  	return a.AcquireAssignedAddressOrMatching(localAddr, nil, allowTemp, tempPEB)
   619  }
   620  
   621  // AcquireOutgoingPrimaryAddress implements AddressableEndpoint.
   622  func (a *AddressableEndpointState) AcquireOutgoingPrimaryAddress(remoteAddr tcpip.Address, allowExpired bool) AddressEndpoint {
   623  	a.mu.Lock()
   624  	defer a.mu.Unlock()
   625  
   626  	ep := a.acquirePrimaryAddressRLocked(remoteAddr, func(ep *addressState) bool {
   627  		return ep.IsAssigned(allowExpired)
   628  	})
   629  
   630  	// From https://golang.org/doc/faq#nil_error:
   631  	//
   632  	// Under the covers, interfaces are implemented as two elements, a type T and
   633  	// a value V.
   634  	//
   635  	// An interface value is nil only if the V and T are both unset, (T=nil, V is
   636  	// not set), In particular, a nil interface will always hold a nil type. If we
   637  	// store a nil pointer of type *int inside an interface value, the inner type
   638  	// will be *int regardless of the value of the pointer: (T=*int, V=nil). Such
   639  	// an interface value will therefore be non-nil even when the pointer value V
   640  	// inside is nil.
   641  	//
   642  	// Since acquirePrimaryAddressLocked returns a nil value with a non-nil type,
   643  	// we need to explicitly return nil below if ep is (a typed) nil.
   644  	if ep == nil {
   645  		return nil
   646  	}
   647  
   648  	return ep
   649  }
   650  
   651  // PrimaryAddresses implements AddressableEndpoint.
   652  func (a *AddressableEndpointState) PrimaryAddresses() []tcpip.AddressWithPrefix {
   653  	a.mu.RLock()
   654  	defer a.mu.RUnlock()
   655  
   656  	var addrs []tcpip.AddressWithPrefix
   657  	if a.options.HiddenWhileDisabled && !a.networkEndpoint.Enabled() {
   658  		return addrs
   659  	}
   660  	for _, ep := range a.primary {
   661  		switch kind := ep.GetKind(); kind {
   662  		// Don't include tentative, expired or temporary endpoints
   663  		// to avoid confusion and prevent the caller from using
   664  		// those.
   665  		case PermanentTentative, PermanentExpired, Temporary:
   666  			continue
   667  		case Permanent:
   668  		default:
   669  			panic(fmt.Sprintf("address %s has unknown kind %d", ep.AddressWithPrefix(), kind))
   670  		}
   671  
   672  		addrs = append(addrs, ep.AddressWithPrefix())
   673  	}
   674  
   675  	return addrs
   676  }
   677  
   678  // PermanentAddresses implements AddressableEndpoint.
   679  func (a *AddressableEndpointState) PermanentAddresses() []tcpip.AddressWithPrefix {
   680  	a.mu.RLock()
   681  	defer a.mu.RUnlock()
   682  
   683  	var addrs []tcpip.AddressWithPrefix
   684  	for _, ep := range a.endpoints {
   685  		if !ep.GetKind().IsPermanent() {
   686  			continue
   687  		}
   688  
   689  		addrs = append(addrs, ep.AddressWithPrefix())
   690  	}
   691  
   692  	return addrs
   693  }
   694  
   695  // Cleanup forcefully leaves all groups and removes all permanent addresses.
   696  func (a *AddressableEndpointState) Cleanup() {
   697  	a.mu.Lock()
   698  	defer a.mu.Unlock()
   699  
   700  	for _, ep := range a.endpoints {
   701  		// removePermanentEndpointLocked returns *tcpip.ErrBadLocalAddress if ep is
   702  		// not a permanent address.
   703  		switch err := a.removePermanentEndpointLocked(ep, AddressRemovalInterfaceRemoved); err.(type) {
   704  		case nil, *tcpip.ErrBadLocalAddress:
   705  		default:
   706  			panic(fmt.Sprintf("unexpected error from removePermanentEndpointLocked(%s): %s", ep.addr, err))
   707  		}
   708  	}
   709  }
   710  
   711  var _ AddressEndpoint = (*addressState)(nil)
   712  
   713  // addressState holds state for an address.
   714  type addressState struct {
   715  	addressableEndpointState *AddressableEndpointState
   716  	addr                     tcpip.AddressWithPrefix
   717  	subnet                   tcpip.Subnet
   718  	temporary                bool
   719  
   720  	// Lock ordering (from outer to inner lock ordering):
   721  	//
   722  	// AddressableEndpointState.mu
   723  	//   addressState.mu
   724  	mu   addressStateRWMutex
   725  	refs addressStateRefs
   726  	// checklocks:mu
   727  	kind AddressKind
   728  	// checklocks:mu
   729  	configType AddressConfigType
   730  	// lifetimes holds this address' lifetimes.
   731  	//
   732  	// Invariant: if lifetimes.deprecated is true, then lifetimes.PreferredUntil
   733  	// must be the zero value. Note that the converse does not need to be
   734  	// upheld!
   735  	//
   736  	// checklocks:mu
   737  	lifetimes AddressLifetimes
   738  	// The enclosing mutex must be write-locked before calling methods on the
   739  	// dispatcher.
   740  	//
   741  	// checklocks:mu
   742  	disp AddressDispatcher
   743  }
   744  
   745  // AddressWithPrefix implements AddressEndpoint.
   746  func (a *addressState) AddressWithPrefix() tcpip.AddressWithPrefix {
   747  	return a.addr
   748  }
   749  
   750  // Subnet implements AddressEndpoint.
   751  func (a *addressState) Subnet() tcpip.Subnet {
   752  	return a.subnet
   753  }
   754  
   755  // GetKind implements AddressEndpoint.
   756  func (a *addressState) GetKind() AddressKind {
   757  	a.mu.RLock()
   758  	defer a.mu.RUnlock()
   759  	return a.kind
   760  }
   761  
   762  // SetKind implements AddressEndpoint.
   763  func (a *addressState) SetKind(kind AddressKind) {
   764  	a.mu.Lock()
   765  	defer a.mu.Unlock()
   766  
   767  	prevKind := a.kind
   768  	a.kind = kind
   769  	if kind == PermanentExpired {
   770  		a.notifyRemovedLocked(AddressRemovalManualAction)
   771  	} else if prevKind != kind && a.addressableEndpointState.networkEndpoint.Enabled() {
   772  		a.notifyChangedLocked()
   773  	}
   774  }
   775  
   776  // notifyRemovedLocked notifies integrators of address removal.
   777  //
   778  // +checklocks:a.mu
   779  func (a *addressState) notifyRemovedLocked(reason AddressRemovalReason) {
   780  	if disp := a.disp; disp != nil {
   781  		a.disp.OnRemoved(reason)
   782  		a.disp = nil
   783  	}
   784  }
   785  
   786  func (a *addressState) remove(reason AddressRemovalReason) {
   787  	a.mu.Lock()
   788  	defer a.mu.Unlock()
   789  
   790  	a.kind = PermanentExpired
   791  	a.notifyRemovedLocked(reason)
   792  }
   793  
   794  // IsAssigned implements AddressEndpoint.
   795  func (a *addressState) IsAssigned(allowExpired bool) bool {
   796  	switch kind := a.GetKind(); kind {
   797  	case PermanentTentative:
   798  		return false
   799  	case PermanentExpired:
   800  		return allowExpired
   801  	case Permanent, Temporary:
   802  		return true
   803  	default:
   804  		panic(fmt.Sprintf("address %s has unknown kind %d", a.AddressWithPrefix(), kind))
   805  	}
   806  }
   807  
   808  // IncRef implements AddressEndpoint.
   809  func (a *addressState) IncRef() bool {
   810  	return a.refs.TryIncRef()
   811  }
   812  
   813  // DecRef implements AddressEndpoint.
   814  func (a *addressState) DecRef() {
   815  	a.addressableEndpointState.decAddressRef(a)
   816  }
   817  
   818  // decRefMustNotFree decreases the reference count with the guarantee that the
   819  // reference count will be greater than 0 after the decrement.
   820  //
   821  // Panics if the ref count is less than 2 after acquiring the lock in this
   822  // function.
   823  func (a *addressState) decRefMustNotFree() {
   824  	a.refs.DecRef(func() {
   825  		panic(fmt.Sprintf("cannot decrease addressState %s without freeing the endpoint", a.addr))
   826  	})
   827  }
   828  
   829  // ConfigType implements AddressEndpoint.
   830  func (a *addressState) ConfigType() AddressConfigType {
   831  	a.mu.RLock()
   832  	defer a.mu.RUnlock()
   833  	return a.configType
   834  }
   835  
   836  // notifyChangedLocked notifies integrators of address property changes.
   837  //
   838  // +checklocks:a.mu
   839  func (a *addressState) notifyChangedLocked() {
   840  	if a.disp == nil {
   841  		return
   842  	}
   843  
   844  	state := AddressDisabled
   845  	if a.addressableEndpointState.networkEndpoint.Enabled() {
   846  		switch a.kind {
   847  		case Permanent:
   848  			state = AddressAssigned
   849  		case PermanentTentative:
   850  			state = AddressTentative
   851  		case Temporary, PermanentExpired:
   852  			return
   853  		default:
   854  			panic(fmt.Sprintf("unrecognized address kind = %d", a.kind))
   855  		}
   856  	}
   857  
   858  	a.disp.OnChanged(a.lifetimes, state)
   859  }
   860  
   861  // SetDeprecated implements AddressEndpoint.
   862  func (a *addressState) SetDeprecated(d bool) {
   863  	a.mu.Lock()
   864  	defer a.mu.Unlock()
   865  
   866  	var changed bool
   867  	if a.lifetimes.Deprecated != d {
   868  		a.lifetimes.Deprecated = d
   869  		changed = true
   870  	}
   871  	if d {
   872  		a.lifetimes.PreferredUntil = tcpip.MonotonicTime{}
   873  	}
   874  	if changed {
   875  		a.notifyChangedLocked()
   876  	}
   877  }
   878  
   879  // Deprecated implements AddressEndpoint.
   880  func (a *addressState) Deprecated() bool {
   881  	a.mu.RLock()
   882  	defer a.mu.RUnlock()
   883  	return a.lifetimes.Deprecated
   884  }
   885  
   886  // SetLifetimes implements AddressEndpoint.
   887  func (a *addressState) SetLifetimes(lifetimes AddressLifetimes) {
   888  	a.mu.Lock()
   889  	defer a.mu.Unlock()
   890  
   891  	lifetimes.sanitize()
   892  
   893  	var changed bool
   894  	if a.lifetimes != lifetimes {
   895  		changed = true
   896  	}
   897  	a.lifetimes = lifetimes
   898  	if changed {
   899  		a.notifyChangedLocked()
   900  	}
   901  }
   902  
   903  // Lifetimes implements AddressEndpoint.
   904  func (a *addressState) Lifetimes() AddressLifetimes {
   905  	a.mu.RLock()
   906  	defer a.mu.RUnlock()
   907  	return a.lifetimes
   908  }
   909  
   910  // Temporary implements AddressEndpoint.
   911  func (a *addressState) Temporary() bool {
   912  	return a.temporary
   913  }
   914  
   915  // RegisterDispatcher implements AddressEndpoint.
   916  func (a *addressState) RegisterDispatcher(disp AddressDispatcher) {
   917  	a.mu.Lock()
   918  	defer a.mu.Unlock()
   919  	if disp != nil {
   920  		a.disp = disp
   921  		a.notifyChangedLocked()
   922  	}
   923  }