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 }