mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Support deprecating SLAAC addresses after the preferred lifetime
Support deprecating network endpoints on a NIC. If an endpoint is deprecated, it should not be used for new connections unless a more preferred endpoint is not available, or unless the deprecated endpoint was explicitly requested. Test: Test that deprecated endpoints are only returned when more preferred endpoints are not available and SLAAC addresses are deprecated after its preferred lifetime PiperOrigin-RevId: 288562705
This commit is contained in:
committed by
gVisor bot
parent
2031cc4701
commit
4e19d165cc
+196
-93
@@ -169,6 +169,15 @@ type NDPDispatcher interface {
|
||||
// call functions on the stack itself.
|
||||
OnAutoGenAddress(tcpip.NICID, tcpip.AddressWithPrefix) bool
|
||||
|
||||
// OnAutoGenAddressDeprecated will be called when an auto-generated
|
||||
// address (as part of SLAAC) has been deprecated, but is still
|
||||
// considered valid. Note, if an address is invalidated at the same
|
||||
// time it is deprecated, the deprecation event MAY be omitted.
|
||||
//
|
||||
// This function is not permitted to block indefinitely. It must not
|
||||
// call functions on the stack itself.
|
||||
OnAutoGenAddressDeprecated(tcpip.NICID, tcpip.AddressWithPrefix)
|
||||
|
||||
// OnAutoGenAddressInvalidated will be called when an auto-generated
|
||||
// address (as part of SLAAC) has been invalidated.
|
||||
//
|
||||
@@ -335,6 +344,17 @@ type onLinkPrefixState struct {
|
||||
// autoGenAddressState holds data associated with an address generated via
|
||||
// SLAAC.
|
||||
type autoGenAddressState struct {
|
||||
// A reference to the referencedNetworkEndpoint that this autoGenAddressState
|
||||
// is holding state for.
|
||||
ref *referencedNetworkEndpoint
|
||||
|
||||
deprecationTimer *time.Timer
|
||||
|
||||
// Used to signal the timer not to deprecate the SLAAC address in a race
|
||||
// condition. Used for the same reason as doNotInvalidate, but for deprecating
|
||||
// an address.
|
||||
doNotDeprecate *bool
|
||||
|
||||
invalidationTimer *time.Timer
|
||||
|
||||
// Used to signal the timer not to invalidate the SLAAC address (A) in
|
||||
@@ -912,103 +932,30 @@ func (ndp *ndpState) handleAutonomousPrefixInformation(pi header.NDPPrefixInform
|
||||
prefix := pi.Subnet()
|
||||
|
||||
// Check if we already have an auto-generated address for prefix.
|
||||
for _, ref := range ndp.nic.endpoints {
|
||||
if ref.protocol != header.IPv6ProtocolNumber {
|
||||
continue
|
||||
}
|
||||
|
||||
if ref.configType != slaac {
|
||||
continue
|
||||
}
|
||||
|
||||
addr := ref.ep.ID().LocalAddress
|
||||
refAddrWithPrefix := tcpip.AddressWithPrefix{Address: addr, PrefixLen: ref.ep.PrefixLen()}
|
||||
for addr, addrState := range ndp.autoGenAddresses {
|
||||
refAddrWithPrefix := tcpip.AddressWithPrefix{Address: addr, PrefixLen: addrState.ref.ep.PrefixLen()}
|
||||
if refAddrWithPrefix.Subnet() != prefix {
|
||||
continue
|
||||
}
|
||||
|
||||
//
|
||||
// At this point, we know we are refreshing a SLAAC generated
|
||||
// IPv6 address with the prefix, prefix. Do the work as outlined
|
||||
// by RFC 4862 section 5.5.3.e.
|
||||
//
|
||||
|
||||
addrState, ok := ndp.autoGenAddresses[addr]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("must have an autoGenAddressess entry for the SLAAC generated IPv6 address %s", addr))
|
||||
}
|
||||
|
||||
// TODO(b/143713887): Handle deprecating auto-generated address
|
||||
// after the preferred lifetime.
|
||||
|
||||
// As per RFC 4862 section 5.5.3.e, the valid lifetime of the
|
||||
// address generated by SLAAC is as follows:
|
||||
//
|
||||
// 1) If the received Valid Lifetime is greater than 2 hours or
|
||||
// greater than RemainingLifetime, set the valid lifetime of
|
||||
// the address to the advertised Valid Lifetime.
|
||||
//
|
||||
// 2) If RemainingLifetime is less than or equal to 2 hours,
|
||||
// ignore the advertised Valid Lifetime.
|
||||
//
|
||||
// 3) Otherwise, reset the valid lifetime of the address to 2
|
||||
// hours.
|
||||
|
||||
// Handle the infinite valid lifetime separately as we do not
|
||||
// keep a timer in this case.
|
||||
if vl >= header.NDPInfiniteLifetime {
|
||||
if addrState.invalidationTimer != nil {
|
||||
// Valid lifetime was finite before, but now it
|
||||
// is valid forever.
|
||||
if !addrState.invalidationTimer.Stop() {
|
||||
*addrState.doNotInvalidate = true
|
||||
}
|
||||
addrState.invalidationTimer = nil
|
||||
addrState.validUntil = time.Time{}
|
||||
ndp.autoGenAddresses[addr] = addrState
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var effectiveVl time.Duration
|
||||
var rl time.Duration
|
||||
|
||||
// If the address was originally set to be valid forever,
|
||||
// assume the remaining time to be the maximum possible value.
|
||||
if addrState.invalidationTimer == nil {
|
||||
rl = header.NDPInfiniteLifetime
|
||||
} else {
|
||||
rl = time.Until(addrState.validUntil)
|
||||
}
|
||||
|
||||
if vl > MinPrefixInformationValidLifetimeForUpdate || vl > rl {
|
||||
effectiveVl = vl
|
||||
} else if rl <= MinPrefixInformationValidLifetimeForUpdate {
|
||||
ndp.autoGenAddresses[addr] = addrState
|
||||
return
|
||||
} else {
|
||||
effectiveVl = MinPrefixInformationValidLifetimeForUpdate
|
||||
}
|
||||
|
||||
if addrState.invalidationTimer == nil {
|
||||
addrState.invalidationTimer = ndp.autoGenAddrInvalidationTimer(addr, effectiveVl, addrState.doNotInvalidate)
|
||||
} else {
|
||||
if !addrState.invalidationTimer.Stop() {
|
||||
*addrState.doNotInvalidate = true
|
||||
}
|
||||
addrState.invalidationTimer.Reset(effectiveVl)
|
||||
}
|
||||
|
||||
addrState.validUntil = time.Now().Add(effectiveVl)
|
||||
ndp.autoGenAddresses[addr] = addrState
|
||||
// At this point, we know we are refreshing a SLAAC generated IPv6 address
|
||||
// with the prefix prefix. Do the work as outlined by RFC 4862 section
|
||||
// 5.5.3.e.
|
||||
ndp.refreshAutoGenAddressLifetimes(addr, pl, vl)
|
||||
return
|
||||
}
|
||||
|
||||
// We do not already have an address within the prefix, prefix. Do the
|
||||
// work as outlined by RFC 4862 section 5.5.3.d if n is configured
|
||||
// to auto-generated global addresses by SLAAC.
|
||||
ndp.newAutoGenAddress(prefix, pl, vl)
|
||||
}
|
||||
|
||||
// newAutoGenAddress generates a new SLAAC address with the provided lifetimes
|
||||
// for prefix.
|
||||
//
|
||||
// pl is the new preferred lifetime. vl is the new valid lifetime.
|
||||
func (ndp *ndpState) newAutoGenAddress(prefix tcpip.Subnet, pl, vl time.Duration) {
|
||||
// Are we configured to auto-generate new global addresses?
|
||||
if !ndp.configs.AutoGenGlobalAddresses {
|
||||
return
|
||||
@@ -1067,18 +1014,25 @@ func (ndp *ndpState) handleAutonomousPrefixInformation(pi header.NDPPrefixInform
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := ndp.nic.addAddressLocked(tcpip.ProtocolAddress{
|
||||
protocolAddr := tcpip.ProtocolAddress{
|
||||
Protocol: header.IPv6ProtocolNumber,
|
||||
AddressWithPrefix: addrWithPrefix,
|
||||
}, FirstPrimaryEndpoint, permanent, slaac); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// If the preferred lifetime is zero, then the address should be considered
|
||||
// deprecated.
|
||||
deprecated := pl == 0
|
||||
ref, err := ndp.nic.addAddressLocked(protocolAddr, FirstPrimaryEndpoint, permanent, slaac, deprecated)
|
||||
if err != nil {
|
||||
log.Fatalf("ndp: error when adding address %s: %s", protocolAddr, err)
|
||||
}
|
||||
|
||||
// Setup the timers to deprecate and invalidate this newly generated
|
||||
// address.
|
||||
// Setup the timers to deprecate and invalidate this newly generated address.
|
||||
|
||||
// TODO(b/143713887): Handle deprecating auto-generated addresses
|
||||
// after the preferred lifetime.
|
||||
var doNotDeprecate bool
|
||||
var pTimer *time.Timer
|
||||
if !deprecated && pl < header.NDPInfiniteLifetime {
|
||||
pTimer = ndp.autoGenAddrDeprecationTimer(addr, pl, &doNotDeprecate)
|
||||
}
|
||||
|
||||
var doNotInvalidate bool
|
||||
var vTimer *time.Timer
|
||||
@@ -1087,12 +1041,126 @@ func (ndp *ndpState) handleAutonomousPrefixInformation(pi header.NDPPrefixInform
|
||||
}
|
||||
|
||||
ndp.autoGenAddresses[addr] = autoGenAddressState{
|
||||
ref: ref,
|
||||
deprecationTimer: pTimer,
|
||||
doNotDeprecate: &doNotDeprecate,
|
||||
invalidationTimer: vTimer,
|
||||
doNotInvalidate: &doNotInvalidate,
|
||||
validUntil: time.Now().Add(vl),
|
||||
}
|
||||
}
|
||||
|
||||
// refreshAutoGenAddressLifetimes refreshes the lifetime of a SLAAC generated
|
||||
// address addr.
|
||||
//
|
||||
// pl is the new preferred lifetime. vl is the new valid lifetime.
|
||||
func (ndp *ndpState) refreshAutoGenAddressLifetimes(addr tcpip.Address, pl, vl time.Duration) {
|
||||
addrState, ok := ndp.autoGenAddresses[addr]
|
||||
if !ok {
|
||||
log.Fatalf("ndp: SLAAC state not found to refresh lifetimes for %s", addr)
|
||||
}
|
||||
defer func() { ndp.autoGenAddresses[addr] = addrState }()
|
||||
|
||||
// If the preferred lifetime is zero, then the address should be considered
|
||||
// deprecated.
|
||||
deprecated := pl == 0
|
||||
wasDeprecated := addrState.ref.deprecated
|
||||
addrState.ref.deprecated = deprecated
|
||||
|
||||
// Only send the deprecation event if the deprecated status for addr just
|
||||
// changed from non-deprecated to deprecated.
|
||||
if !wasDeprecated && deprecated {
|
||||
ndp.notifyAutoGenAddressDeprecated(addr)
|
||||
}
|
||||
|
||||
// If addr was preferred for some finite lifetime before, stop the deprecation
|
||||
// timer so it can be reset.
|
||||
if t := addrState.deprecationTimer; t != nil && !t.Stop() {
|
||||
*addrState.doNotDeprecate = true
|
||||
}
|
||||
|
||||
// Reset the deprecation timer.
|
||||
if pl >= header.NDPInfiniteLifetime || deprecated {
|
||||
// If addr is preferred forever or it has been deprecated already, there is
|
||||
// no need for a deprecation timer.
|
||||
addrState.deprecationTimer = nil
|
||||
} else if addrState.deprecationTimer == nil {
|
||||
// addr is now preferred for a finite lifetime.
|
||||
addrState.deprecationTimer = ndp.autoGenAddrDeprecationTimer(addr, pl, addrState.doNotDeprecate)
|
||||
} else {
|
||||
// addr continues to be preferred for a finite lifetime.
|
||||
addrState.deprecationTimer.Reset(pl)
|
||||
}
|
||||
|
||||
// As per RFC 4862 section 5.5.3.e, the valid lifetime of the address
|
||||
//
|
||||
//
|
||||
// 1) If the received Valid Lifetime is greater than 2 hours or greater than
|
||||
// RemainingLifetime, set the valid lifetime of the address to the
|
||||
// advertised Valid Lifetime.
|
||||
//
|
||||
// 2) If RemainingLifetime is less than or equal to 2 hours, ignore the
|
||||
// advertised Valid Lifetime.
|
||||
//
|
||||
// 3) Otherwise, reset the valid lifetime of the address to 2 hours.
|
||||
|
||||
// Handle the infinite valid lifetime separately as we do not keep a timer in
|
||||
// this case.
|
||||
if vl >= header.NDPInfiniteLifetime {
|
||||
if addrState.invalidationTimer != nil {
|
||||
// Valid lifetime was finite before, but now it is valid forever.
|
||||
if !addrState.invalidationTimer.Stop() {
|
||||
*addrState.doNotInvalidate = true
|
||||
}
|
||||
addrState.invalidationTimer = nil
|
||||
addrState.validUntil = time.Time{}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var effectiveVl time.Duration
|
||||
var rl time.Duration
|
||||
|
||||
// If the address was originally set to be valid forever, assume the remaining
|
||||
// time to be the maximum possible value.
|
||||
if addrState.invalidationTimer == nil {
|
||||
rl = header.NDPInfiniteLifetime
|
||||
} else {
|
||||
rl = time.Until(addrState.validUntil)
|
||||
}
|
||||
|
||||
if vl > MinPrefixInformationValidLifetimeForUpdate || vl > rl {
|
||||
effectiveVl = vl
|
||||
} else if rl <= MinPrefixInformationValidLifetimeForUpdate {
|
||||
return
|
||||
} else {
|
||||
effectiveVl = MinPrefixInformationValidLifetimeForUpdate
|
||||
}
|
||||
|
||||
if addrState.invalidationTimer == nil {
|
||||
addrState.invalidationTimer = ndp.autoGenAddrInvalidationTimer(addr, effectiveVl, addrState.doNotInvalidate)
|
||||
} else {
|
||||
if !addrState.invalidationTimer.Stop() {
|
||||
*addrState.doNotInvalidate = true
|
||||
}
|
||||
addrState.invalidationTimer.Reset(effectiveVl)
|
||||
}
|
||||
|
||||
addrState.validUntil = time.Now().Add(effectiveVl)
|
||||
}
|
||||
|
||||
// notifyAutoGenAddressDeprecated notifies the stack's NDP dispatcher that addr
|
||||
// has been deprecated.
|
||||
func (ndp *ndpState) notifyAutoGenAddressDeprecated(addr tcpip.Address) {
|
||||
if ndpDisp := ndp.nic.stack.ndpDisp; ndpDisp != nil {
|
||||
ndpDisp.OnAutoGenAddressDeprecated(ndp.nic.ID(), tcpip.AddressWithPrefix{
|
||||
Address: addr,
|
||||
PrefixLen: validPrefixLenForAutoGen,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// invalidateAutoGenAddress invalidates an auto-generated address.
|
||||
//
|
||||
// The NIC that ndp belongs to MUST be locked.
|
||||
@@ -1118,6 +1186,14 @@ func (ndp *ndpState) cleanupAutoGenAddrResourcesAndNotify(addr tcpip.Address) bo
|
||||
return false
|
||||
}
|
||||
|
||||
if state.deprecationTimer != nil {
|
||||
state.deprecationTimer.Stop()
|
||||
state.deprecationTimer = nil
|
||||
*state.doNotDeprecate = true
|
||||
}
|
||||
|
||||
state.doNotDeprecate = nil
|
||||
|
||||
if state.invalidationTimer != nil {
|
||||
state.invalidationTimer.Stop()
|
||||
state.invalidationTimer = nil
|
||||
@@ -1138,6 +1214,33 @@ func (ndp *ndpState) cleanupAutoGenAddrResourcesAndNotify(addr tcpip.Address) bo
|
||||
return true
|
||||
}
|
||||
|
||||
// autoGenAddrDeprecationTimer returns a new deprecation timer for an
|
||||
// auto-generated address that fires after pl.
|
||||
//
|
||||
// doNotDeprecate is used to inform the timer when it fires at the same time
|
||||
// that an auto-generated address's preferred lifetime gets refreshed. See
|
||||
// autoGenAddrState.doNotDeprecate for more details.
|
||||
func (ndp *ndpState) autoGenAddrDeprecationTimer(addr tcpip.Address, pl time.Duration, doNotDeprecate *bool) *time.Timer {
|
||||
return time.AfterFunc(pl, func() {
|
||||
ndp.nic.mu.Lock()
|
||||
defer ndp.nic.mu.Unlock()
|
||||
|
||||
if *doNotDeprecate {
|
||||
*doNotDeprecate = false
|
||||
return
|
||||
}
|
||||
|
||||
addrState, ok := ndp.autoGenAddresses[addr]
|
||||
if !ok {
|
||||
log.Fatalf("ndp: must have an autoGenAddressess entry for the SLAAC generated IPv6 address %s", addr)
|
||||
}
|
||||
addrState.ref.deprecated = true
|
||||
ndp.notifyAutoGenAddressDeprecated(addr)
|
||||
addrState.deprecationTimer = nil
|
||||
ndp.autoGenAddresses[addr] = addrState
|
||||
})
|
||||
}
|
||||
|
||||
// autoGenAddrInvalidationTimer returns a new invalidation timer for an
|
||||
// auto-generated address that fires after vl.
|
||||
//
|
||||
|
||||
+538
-1
File diff suppressed because it is too large
Load Diff
+87
-6
@@ -249,17 +249,47 @@ func (n *NIC) setSpoofing(enable bool) {
|
||||
|
||||
// primaryEndpoint returns the primary endpoint of n for the given network
|
||||
// protocol.
|
||||
//
|
||||
// primaryEndpoint will return the first non-deprecated endpoint if such an
|
||||
// endpoint exists. If no non-deprecated endpoint exists, the first deprecated
|
||||
// endpoint will be returned.
|
||||
func (n *NIC) primaryEndpoint(protocol tcpip.NetworkProtocolNumber) *referencedNetworkEndpoint {
|
||||
n.mu.RLock()
|
||||
defer n.mu.RUnlock()
|
||||
|
||||
var deprecatedEndpoint *referencedNetworkEndpoint
|
||||
for _, r := range n.primary[protocol] {
|
||||
if r.isValidForOutgoing() && r.tryIncRef() {
|
||||
return r
|
||||
if !r.isValidForOutgoing() {
|
||||
continue
|
||||
}
|
||||
|
||||
if !r.deprecated {
|
||||
if r.tryIncRef() {
|
||||
// r is not deprecated, so return it immediately.
|
||||
//
|
||||
// If we kept track of a deprecated endpoint, decrement its reference
|
||||
// count since it was incremented when we decided to keep track of it.
|
||||
if deprecatedEndpoint != nil {
|
||||
deprecatedEndpoint.decRefLocked()
|
||||
deprecatedEndpoint = nil
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
} else if deprecatedEndpoint == nil && r.tryIncRef() {
|
||||
// We prefer an endpoint that is not deprecated, but we keep track of r in
|
||||
// case n doesn't have any non-deprecated endpoints.
|
||||
//
|
||||
// If we end up finding a more preferred endpoint, r's reference count
|
||||
// will be decremented when such an endpoint is found.
|
||||
deprecatedEndpoint = r
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
// n doesn't have any valid non-deprecated endpoints, so return
|
||||
// deprecatedEndpoint (which may be nil if n doesn't have any valid deprecated
|
||||
// endpoints either).
|
||||
return deprecatedEndpoint
|
||||
}
|
||||
|
||||
// hasPermanentAddrLocked returns true if n has a permanent (including currently
|
||||
@@ -367,7 +397,7 @@ func (n *NIC) getRefOrCreateTemp(protocol tcpip.NetworkProtocolNumber, address t
|
||||
Address: address,
|
||||
PrefixLen: netProto.DefaultPrefixLen(),
|
||||
},
|
||||
}, peb, temporary, static)
|
||||
}, peb, temporary, static, false)
|
||||
|
||||
n.mu.Unlock()
|
||||
return ref
|
||||
@@ -416,10 +446,10 @@ func (n *NIC) addPermanentAddressLocked(protocolAddress tcpip.ProtocolAddress, p
|
||||
}
|
||||
}
|
||||
|
||||
return n.addAddressLocked(protocolAddress, peb, permanent, static)
|
||||
return n.addAddressLocked(protocolAddress, peb, permanent, static, false)
|
||||
}
|
||||
|
||||
func (n *NIC) addAddressLocked(protocolAddress tcpip.ProtocolAddress, peb PrimaryEndpointBehavior, kind networkEndpointKind, configType networkEndpointConfigType) (*referencedNetworkEndpoint, *tcpip.Error) {
|
||||
func (n *NIC) addAddressLocked(protocolAddress tcpip.ProtocolAddress, peb PrimaryEndpointBehavior, kind networkEndpointKind, configType networkEndpointConfigType, deprecated bool) (*referencedNetworkEndpoint, *tcpip.Error) {
|
||||
// TODO(b/141022673): Validate IP address before adding them.
|
||||
|
||||
// Sanity check.
|
||||
@@ -455,6 +485,7 @@ func (n *NIC) addAddressLocked(protocolAddress tcpip.ProtocolAddress, peb Primar
|
||||
protocol: protocolAddress.Protocol,
|
||||
kind: kind,
|
||||
configType: configType,
|
||||
deprecated: deprecated,
|
||||
}
|
||||
|
||||
// Set up cache if link address resolution exists for this protocol.
|
||||
@@ -553,6 +584,51 @@ func (n *NIC) PrimaryAddresses() []tcpip.ProtocolAddress {
|
||||
return addrs
|
||||
}
|
||||
|
||||
// primaryAddress returns the primary address associated with this NIC.
|
||||
//
|
||||
// primaryAddress will return the first non-deprecated address if such an
|
||||
// address exists. If no non-deprecated address exists, the first deprecated
|
||||
// address will be returned.
|
||||
func (n *NIC) primaryAddress(proto tcpip.NetworkProtocolNumber) tcpip.AddressWithPrefix {
|
||||
n.mu.RLock()
|
||||
defer n.mu.RUnlock()
|
||||
|
||||
list, ok := n.primary[proto]
|
||||
if !ok {
|
||||
return tcpip.AddressWithPrefix{}
|
||||
}
|
||||
|
||||
var deprecatedEndpoint *referencedNetworkEndpoint
|
||||
for _, ref := range list {
|
||||
// Don't include tentative, expired or tempory endpoints to avoid confusion
|
||||
// and prevent the caller from using those.
|
||||
switch ref.getKind() {
|
||||
case permanentTentative, permanentExpired, temporary:
|
||||
continue
|
||||
}
|
||||
|
||||
if !ref.deprecated {
|
||||
return tcpip.AddressWithPrefix{
|
||||
Address: ref.ep.ID().LocalAddress,
|
||||
PrefixLen: ref.ep.PrefixLen(),
|
||||
}
|
||||
}
|
||||
|
||||
if deprecatedEndpoint == nil {
|
||||
deprecatedEndpoint = ref
|
||||
}
|
||||
}
|
||||
|
||||
if deprecatedEndpoint != nil {
|
||||
return tcpip.AddressWithPrefix{
|
||||
Address: deprecatedEndpoint.ep.ID().LocalAddress,
|
||||
PrefixLen: deprecatedEndpoint.ep.PrefixLen(),
|
||||
}
|
||||
}
|
||||
|
||||
return tcpip.AddressWithPrefix{}
|
||||
}
|
||||
|
||||
// AddAddressRange adds a range of addresses to n, so that it starts accepting
|
||||
// packets targeted at the given addresses and network protocol. The range is
|
||||
// given by a subnet address, and all addresses contained in the subnet are
|
||||
@@ -1109,6 +1185,11 @@ type referencedNetworkEndpoint struct {
|
||||
// configType is the method that was used to configure this endpoint.
|
||||
// This must never change after the endpoint is added to a NIC.
|
||||
configType networkEndpointConfigType
|
||||
|
||||
// deprecated indicates whether or not the endpoint should be considered
|
||||
// deprecated. That is, when deprecated is true, other endpoints that are not
|
||||
// deprecated should be preferred.
|
||||
deprecated bool
|
||||
}
|
||||
|
||||
func (r *referencedNetworkEndpoint) getKind() networkEndpointKind {
|
||||
|
||||
@@ -1036,9 +1036,11 @@ func (s *Stack) AllAddresses() map[tcpip.NICID][]tcpip.ProtocolAddress {
|
||||
return nics
|
||||
}
|
||||
|
||||
// GetMainNICAddress returns the first primary address and prefix for the given
|
||||
// NIC and protocol. Returns an error if the NIC doesn't exist and an empty
|
||||
// value if the NIC doesn't have a primary address for the given protocol.
|
||||
// GetMainNICAddress returns the first non-deprecated primary address and prefix
|
||||
// for the given NIC and protocol. If no non-deprecated primary address exists,
|
||||
// a deprecated primary address and prefix will be returned. Returns an error if
|
||||
// the NIC doesn't exist and an empty value if the NIC doesn't have a primary
|
||||
// address for the given protocol.
|
||||
func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber) (tcpip.AddressWithPrefix, *tcpip.Error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
@@ -1048,12 +1050,7 @@ func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocol
|
||||
return tcpip.AddressWithPrefix{}, tcpip.ErrUnknownNICID
|
||||
}
|
||||
|
||||
for _, a := range nic.PrimaryAddresses() {
|
||||
if a.Protocol == protocol {
|
||||
return a.AddressWithPrefix, nil
|
||||
}
|
||||
}
|
||||
return tcpip.AddressWithPrefix{}, nil
|
||||
return nic.primaryAddress(protocol), nil
|
||||
}
|
||||
|
||||
func (s *Stack) getRefEP(nic *NIC, localAddr tcpip.Address, netProto tcpip.NetworkProtocolNumber) (ref *referencedNetworkEndpoint) {
|
||||
|
||||
Reference in New Issue
Block a user