github.com/cilium/cilium@v1.16.2/pkg/endpointmanager/allocator.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package endpointmanager
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/cilium/cilium/pkg/idpool"
    10  )
    11  
    12  const (
    13  	minID = idpool.ID(1)
    14  	maxID = idpool.ID(4095)
    15  )
    16  
    17  type epIDAllocator struct {
    18  	pool *idpool.IDPool
    19  }
    20  
    21  func newEPIDAllocator() *epIDAllocator {
    22  	return &epIDAllocator{
    23  		pool: idpool.NewIDPool(minID, maxID),
    24  	}
    25  }
    26  
    27  // allocate returns a new random ID from the pool
    28  func (a *epIDAllocator) allocate() uint16 {
    29  	id := a.pool.AllocateID()
    30  
    31  	// Out of endpoint IDs
    32  	if id == idpool.NoID {
    33  		return uint16(0)
    34  	}
    35  
    36  	return uint16(id)
    37  }
    38  
    39  // reuse grabs a specific endpoint ID for reuse. This can be used when
    40  // restoring endpoints.
    41  func (a *epIDAllocator) reuse(id uint16) error {
    42  	if idpool.ID(id) < minID {
    43  		return fmt.Errorf("unable to reuse endpoint: %d < %d", id, minID)
    44  	}
    45  
    46  	// When restoring endpoints, the existing endpoint ID can be outside of
    47  	// the range. This is fine (tm) and we can just skip to reserve the ID
    48  	// from the pool as the pool will not cover it.
    49  	if idpool.ID(id) > maxID {
    50  		return nil
    51  	}
    52  
    53  	if !a.pool.Remove(idpool.ID(id)) {
    54  		return fmt.Errorf("endpoint ID %d is already in use", id)
    55  	}
    56  
    57  	return nil
    58  }
    59  
    60  // release releases an endpoint ID that was previously allocated or reused
    61  func (a *epIDAllocator) release(id uint16) error {
    62  	if !a.pool.Insert(idpool.ID(id)) {
    63  		return fmt.Errorf("Unable to release endpoint ID %d", id)
    64  	}
    65  
    66  	return nil
    67  }