github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/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/metacubex/gvisor/pkg/tcpip"
    21  	"github.com/metacubex/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{}, tcpip.Address{} /* srcHint */, 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, srcHint 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  			// Source hint takes precedent over prefix matching.
   478  			if state.addr.Address == srcHint && srcHint != (tcpip.Address{}) {
   479  				best = state
   480  				break
   481  			}
   482  			stateLen := state.addr.Address.MatchingPrefix(remoteAddr)
   483  			if best == nil || bestLen < stateLen {
   484  				best = state
   485  				bestLen = stateLen
   486  			}
   487  		}
   488  		if best != nil && best.TryIncRef() {
   489  			return best
   490  		}
   491  	}
   492  
   493  	var deprecatedEndpoint *addressState
   494  	for _, ep := range a.primary {
   495  		if !isValid(ep) {
   496  			continue
   497  		}
   498  
   499  		if !ep.Deprecated() {
   500  			if ep.TryIncRef() {
   501  				// ep is not deprecated, so return it immediately.
   502  				//
   503  				// If we kept track of a deprecated endpoint, decrement its reference
   504  				// count since it was incremented when we decided to keep track of it.
   505  				if deprecatedEndpoint != nil {
   506  					// Note that when deprecatedEndpoint was found, its ref count
   507  					// must have necessarily been >=1, and after incrementing it
   508  					// must be >=2. The only way for the ref count to drop below 2 is
   509  					// for the endpoint to be removed, which requires a write lock;
   510  					// so we're guaranteed to be able to decrement the ref count
   511  					// and not need to remove the endpoint from a.primary.
   512  					deprecatedEndpoint.decRefMustNotFree()
   513  				}
   514  
   515  				return ep
   516  			}
   517  		} else if deprecatedEndpoint == nil && ep.TryIncRef() {
   518  			// We prefer an endpoint that is not deprecated, but we keep track of
   519  			// ep in case a doesn't have any non-deprecated endpoints.
   520  			//
   521  			// If we end up finding a more preferred endpoint, ep's reference count
   522  			// will be decremented.
   523  			deprecatedEndpoint = ep
   524  		}
   525  	}
   526  
   527  	return deprecatedEndpoint
   528  }
   529  
   530  // AcquireAssignedAddressOrMatching returns an address endpoint that is
   531  // considered assigned to the addressable endpoint.
   532  //
   533  // If the address is an exact match with an existing address, that address is
   534  // returned. Otherwise, if f is provided, f is called with each address and
   535  // the address that f returns true for is returned.
   536  //
   537  // If there is no matching address, a temporary address will be returned if
   538  // allowTemp is true.
   539  //
   540  // Regardless how the address was obtained, it will be acquired before it is
   541  // returned.
   542  func (a *AddressableEndpointState) AcquireAssignedAddressOrMatching(localAddr tcpip.Address, f func(AddressEndpoint) bool, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint {
   543  	lookup := func() *addressState {
   544  		if addrState, ok := a.endpoints[localAddr]; ok {
   545  			if !addrState.IsAssigned(allowTemp) {
   546  				return nil
   547  			}
   548  
   549  			if !addrState.TryIncRef() {
   550  				panic(fmt.Sprintf("failed to increase the reference count for address = %s", addrState.addr))
   551  			}
   552  
   553  			return addrState
   554  		}
   555  
   556  		if f != nil {
   557  			for _, addrState := range a.endpoints {
   558  				if addrState.IsAssigned(allowTemp) && f(addrState) && addrState.TryIncRef() {
   559  					return addrState
   560  				}
   561  			}
   562  		}
   563  		return nil
   564  	}
   565  	// Avoid exclusive lock on mu unless we need to add a new address.
   566  	a.mu.RLock()
   567  	ep := lookup()
   568  	a.mu.RUnlock()
   569  
   570  	if ep != nil {
   571  		return ep
   572  	}
   573  
   574  	if !allowTemp {
   575  		return nil
   576  	}
   577  
   578  	// Acquire state lock in exclusive mode as we need to add a new temporary
   579  	// endpoint.
   580  	a.mu.Lock()
   581  	defer a.mu.Unlock()
   582  
   583  	// Do the lookup again in case another goroutine added the address in the time
   584  	// we released and acquired the lock.
   585  	ep = lookup()
   586  	if ep != nil {
   587  		return ep
   588  	}
   589  
   590  	// Proceed to add a new temporary endpoint.
   591  	addr := localAddr.WithPrefix()
   592  	ep, err := a.addAndAcquireAddressLocked(addr, AddressProperties{PEB: tempPEB}, Temporary)
   593  	if err != nil {
   594  		// addAndAcquireAddressLocked only returns an error if the address is
   595  		// already assigned but we just checked above if the address exists so we
   596  		// expect no error.
   597  		panic(fmt.Sprintf("a.addAndAcquireAddressLocked(%s, AddressProperties{PEB: %s}, false): %s", addr, tempPEB, err))
   598  	}
   599  
   600  	// From https://golang.org/doc/faq#nil_error:
   601  	//
   602  	// Under the covers, interfaces are implemented as two elements, a type T and
   603  	// a value V.
   604  	//
   605  	// An interface value is nil only if the V and T are both unset, (T=nil, V is
   606  	// not set), In particular, a nil interface will always hold a nil type. If we
   607  	// store a nil pointer of type *int inside an interface value, the inner type
   608  	// will be *int regardless of the value of the pointer: (T=*int, V=nil). Such
   609  	// an interface value will therefore be non-nil even when the pointer value V
   610  	// inside is nil.
   611  	//
   612  	// Since addAndAcquireAddressLocked returns a nil value with a non-nil type,
   613  	// we need to explicitly return nil below if ep is (a typed) nil.
   614  	if ep == nil {
   615  		return nil
   616  	}
   617  	return ep
   618  }
   619  
   620  // AcquireAssignedAddress implements AddressableEndpoint.
   621  func (a *AddressableEndpointState) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint {
   622  	return a.AcquireAssignedAddressOrMatching(localAddr, nil, allowTemp, tempPEB)
   623  }
   624  
   625  // AcquireOutgoingPrimaryAddress implements AddressableEndpoint.
   626  func (a *AddressableEndpointState) AcquireOutgoingPrimaryAddress(remoteAddr tcpip.Address, srcHint tcpip.Address, allowExpired bool) AddressEndpoint {
   627  	a.mu.Lock()
   628  	defer a.mu.Unlock()
   629  
   630  	ep := a.acquirePrimaryAddressRLocked(remoteAddr, srcHint, func(ep *addressState) bool {
   631  		return ep.IsAssigned(allowExpired)
   632  	})
   633  
   634  	// From https://golang.org/doc/faq#nil_error:
   635  	//
   636  	// Under the covers, interfaces are implemented as two elements, a type T and
   637  	// a value V.
   638  	//
   639  	// An interface value is nil only if the V and T are both unset, (T=nil, V is
   640  	// not set), In particular, a nil interface will always hold a nil type. If we
   641  	// store a nil pointer of type *int inside an interface value, the inner type
   642  	// will be *int regardless of the value of the pointer: (T=*int, V=nil). Such
   643  	// an interface value will therefore be non-nil even when the pointer value V
   644  	// inside is nil.
   645  	//
   646  	// Since acquirePrimaryAddressLocked returns a nil value with a non-nil type,
   647  	// we need to explicitly return nil below if ep is (a typed) nil.
   648  	if ep == nil {
   649  		return nil
   650  	}
   651  
   652  	return ep
   653  }
   654  
   655  // PrimaryAddresses implements AddressableEndpoint.
   656  func (a *AddressableEndpointState) PrimaryAddresses() []tcpip.AddressWithPrefix {
   657  	a.mu.RLock()
   658  	defer a.mu.RUnlock()
   659  
   660  	var addrs []tcpip.AddressWithPrefix
   661  	if a.options.HiddenWhileDisabled && !a.networkEndpoint.Enabled() {
   662  		return addrs
   663  	}
   664  	for _, ep := range a.primary {
   665  		switch kind := ep.GetKind(); kind {
   666  		// Don't include tentative, expired or temporary endpoints
   667  		// to avoid confusion and prevent the caller from using
   668  		// those.
   669  		case PermanentTentative, PermanentExpired, Temporary:
   670  			continue
   671  		case Permanent:
   672  		default:
   673  			panic(fmt.Sprintf("address %s has unknown kind %d", ep.AddressWithPrefix(), kind))
   674  		}
   675  
   676  		addrs = append(addrs, ep.AddressWithPrefix())
   677  	}
   678  
   679  	return addrs
   680  }
   681  
   682  // PermanentAddresses implements AddressableEndpoint.
   683  func (a *AddressableEndpointState) PermanentAddresses() []tcpip.AddressWithPrefix {
   684  	a.mu.RLock()
   685  	defer a.mu.RUnlock()
   686  
   687  	var addrs []tcpip.AddressWithPrefix
   688  	for _, ep := range a.endpoints {
   689  		if !ep.GetKind().IsPermanent() {
   690  			continue
   691  		}
   692  
   693  		addrs = append(addrs, ep.AddressWithPrefix())
   694  	}
   695  
   696  	return addrs
   697  }
   698  
   699  // Cleanup forcefully leaves all groups and removes all permanent addresses.
   700  func (a *AddressableEndpointState) Cleanup() {
   701  	a.mu.Lock()
   702  	defer a.mu.Unlock()
   703  
   704  	for _, ep := range a.endpoints {
   705  		// removePermanentEndpointLocked returns *tcpip.ErrBadLocalAddress if ep is
   706  		// not a permanent address.
   707  		switch err := a.removePermanentEndpointLocked(ep, AddressRemovalInterfaceRemoved); err.(type) {
   708  		case nil, *tcpip.ErrBadLocalAddress:
   709  		default:
   710  			panic(fmt.Sprintf("unexpected error from removePermanentEndpointLocked(%s): %s", ep.addr, err))
   711  		}
   712  	}
   713  }
   714  
   715  var _ AddressEndpoint = (*addressState)(nil)
   716  
   717  // addressState holds state for an address.
   718  type addressState struct {
   719  	addressableEndpointState *AddressableEndpointState
   720  	addr                     tcpip.AddressWithPrefix
   721  	subnet                   tcpip.Subnet
   722  	temporary                bool
   723  
   724  	// Lock ordering (from outer to inner lock ordering):
   725  	//
   726  	// AddressableEndpointState.mu
   727  	//   addressState.mu
   728  	mu   addressStateRWMutex
   729  	refs addressStateRefs
   730  	// checklocks:mu
   731  	kind AddressKind
   732  	// checklocks:mu
   733  	configType AddressConfigType
   734  	// lifetimes holds this address' lifetimes.
   735  	//
   736  	// Invariant: if lifetimes.deprecated is true, then lifetimes.PreferredUntil
   737  	// must be the zero value. Note that the converse does not need to be
   738  	// upheld!
   739  	//
   740  	// checklocks:mu
   741  	lifetimes AddressLifetimes
   742  	// The enclosing mutex must be write-locked before calling methods on the
   743  	// dispatcher.
   744  	//
   745  	// checklocks:mu
   746  	disp AddressDispatcher
   747  }
   748  
   749  // AddressWithPrefix implements AddressEndpoint.
   750  func (a *addressState) AddressWithPrefix() tcpip.AddressWithPrefix {
   751  	return a.addr
   752  }
   753  
   754  // Subnet implements AddressEndpoint.
   755  func (a *addressState) Subnet() tcpip.Subnet {
   756  	return a.subnet
   757  }
   758  
   759  // GetKind implements AddressEndpoint.
   760  func (a *addressState) GetKind() AddressKind {
   761  	a.mu.RLock()
   762  	defer a.mu.RUnlock()
   763  	return a.kind
   764  }
   765  
   766  // SetKind implements AddressEndpoint.
   767  func (a *addressState) SetKind(kind AddressKind) {
   768  	a.mu.Lock()
   769  	defer a.mu.Unlock()
   770  
   771  	prevKind := a.kind
   772  	a.kind = kind
   773  	if kind == PermanentExpired {
   774  		a.notifyRemovedLocked(AddressRemovalManualAction)
   775  	} else if prevKind != kind && a.addressableEndpointState.networkEndpoint.Enabled() {
   776  		a.notifyChangedLocked()
   777  	}
   778  }
   779  
   780  // notifyRemovedLocked notifies integrators of address removal.
   781  //
   782  // +checklocks:a.mu
   783  func (a *addressState) notifyRemovedLocked(reason AddressRemovalReason) {
   784  	if disp := a.disp; disp != nil {
   785  		a.disp.OnRemoved(reason)
   786  		a.disp = nil
   787  	}
   788  }
   789  
   790  func (a *addressState) remove(reason AddressRemovalReason) {
   791  	a.mu.Lock()
   792  	defer a.mu.Unlock()
   793  
   794  	a.kind = PermanentExpired
   795  	a.notifyRemovedLocked(reason)
   796  }
   797  
   798  // IsAssigned implements AddressEndpoint.
   799  func (a *addressState) IsAssigned(allowExpired bool) bool {
   800  	switch kind := a.GetKind(); kind {
   801  	case PermanentTentative:
   802  		return false
   803  	case PermanentExpired:
   804  		return allowExpired
   805  	case Permanent, Temporary:
   806  		return true
   807  	default:
   808  		panic(fmt.Sprintf("address %s has unknown kind %d", a.AddressWithPrefix(), kind))
   809  	}
   810  }
   811  
   812  // IncRef implements AddressEndpoint.
   813  func (a *addressState) TryIncRef() bool {
   814  	return a.refs.TryIncRef()
   815  }
   816  
   817  // DecRef implements AddressEndpoint.
   818  func (a *addressState) DecRef() {
   819  	a.addressableEndpointState.decAddressRef(a)
   820  }
   821  
   822  // decRefMustNotFree decreases the reference count with the guarantee that the
   823  // reference count will be greater than 0 after the decrement.
   824  //
   825  // Panics if the ref count is less than 2 after acquiring the lock in this
   826  // function.
   827  func (a *addressState) decRefMustNotFree() {
   828  	a.refs.DecRef(func() {
   829  		panic(fmt.Sprintf("cannot decrease addressState %s without freeing the endpoint", a.addr))
   830  	})
   831  }
   832  
   833  // ConfigType implements AddressEndpoint.
   834  func (a *addressState) ConfigType() AddressConfigType {
   835  	a.mu.RLock()
   836  	defer a.mu.RUnlock()
   837  	return a.configType
   838  }
   839  
   840  // notifyChangedLocked notifies integrators of address property changes.
   841  //
   842  // +checklocks:a.mu
   843  func (a *addressState) notifyChangedLocked() {
   844  	if a.disp == nil {
   845  		return
   846  	}
   847  
   848  	state := AddressDisabled
   849  	if a.addressableEndpointState.networkEndpoint.Enabled() {
   850  		switch a.kind {
   851  		case Permanent:
   852  			state = AddressAssigned
   853  		case PermanentTentative:
   854  			state = AddressTentative
   855  		case Temporary, PermanentExpired:
   856  			return
   857  		default:
   858  			panic(fmt.Sprintf("unrecognized address kind = %d", a.kind))
   859  		}
   860  	}
   861  
   862  	a.disp.OnChanged(a.lifetimes, state)
   863  }
   864  
   865  // SetDeprecated implements AddressEndpoint.
   866  func (a *addressState) SetDeprecated(d bool) {
   867  	a.mu.Lock()
   868  	defer a.mu.Unlock()
   869  
   870  	var changed bool
   871  	if a.lifetimes.Deprecated != d {
   872  		a.lifetimes.Deprecated = d
   873  		changed = true
   874  	}
   875  	if d {
   876  		a.lifetimes.PreferredUntil = tcpip.MonotonicTime{}
   877  	}
   878  	if changed {
   879  		a.notifyChangedLocked()
   880  	}
   881  }
   882  
   883  // Deprecated implements AddressEndpoint.
   884  func (a *addressState) Deprecated() bool {
   885  	a.mu.RLock()
   886  	defer a.mu.RUnlock()
   887  	return a.lifetimes.Deprecated
   888  }
   889  
   890  // SetLifetimes implements AddressEndpoint.
   891  func (a *addressState) SetLifetimes(lifetimes AddressLifetimes) {
   892  	a.mu.Lock()
   893  	defer a.mu.Unlock()
   894  
   895  	lifetimes.sanitize()
   896  
   897  	var changed bool
   898  	if a.lifetimes != lifetimes {
   899  		changed = true
   900  	}
   901  	a.lifetimes = lifetimes
   902  	if changed {
   903  		a.notifyChangedLocked()
   904  	}
   905  }
   906  
   907  // Lifetimes implements AddressEndpoint.
   908  func (a *addressState) Lifetimes() AddressLifetimes {
   909  	a.mu.RLock()
   910  	defer a.mu.RUnlock()
   911  	return a.lifetimes
   912  }
   913  
   914  // Temporary implements AddressEndpoint.
   915  func (a *addressState) Temporary() bool {
   916  	return a.temporary
   917  }
   918  
   919  // RegisterDispatcher implements AddressEndpoint.
   920  func (a *addressState) RegisterDispatcher(disp AddressDispatcher) {
   921  	a.mu.Lock()
   922  	defer a.mu.Unlock()
   923  	if disp != nil {
   924  		a.disp = disp
   925  		a.notifyChangedLocked()
   926  	}
   927  }