github.com/cilium/cilium@v1.16.2/pkg/maps/bwmap/table.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package bwmap
     5  
     6  import (
     7  	"encoding"
     8  	"strconv"
     9  
    10  	"github.com/cilium/statedb"
    11  	"github.com/cilium/statedb/index"
    12  	"github.com/cilium/statedb/reconciler"
    13  	"k8s.io/apimachinery/pkg/api/resource"
    14  
    15  	"github.com/cilium/cilium/pkg/bpf"
    16  )
    17  
    18  const EdtTableName = "bandwidth-edts"
    19  
    20  // Edt is defines the "earliest departure time" pacing for a specific
    21  // Cilium endpoint. This structure is stored in Table[Edt] and reconciled
    22  // to the cilium_throttle BPF map.
    23  //
    24  // Edt is stored by value as it's relatively tiny.
    25  type Edt struct {
    26  	// EndpointID is the identity of the endpoint being throttled.
    27  	EndpointID uint16
    28  
    29  	// BytesPerSecond is the bandwidth limit for the endpoint.
    30  	BytesPerSecond uint64
    31  
    32  	// TimeHorizonDrop is the maximum allowed departure time nanoseconds
    33  	// delta in future.
    34  	TimeHorizonDrop uint64
    35  
    36  	// Status is the BPF map reconciliation status of this throttle entry.
    37  	Status reconciler.Status
    38  }
    39  
    40  var EdtIDIndex = statedb.Index[Edt, uint16]{
    41  	Name: "endpoint-id",
    42  	FromObject: func(t Edt) index.KeySet {
    43  		return index.NewKeySet(index.Uint16(t.EndpointID))
    44  	},
    45  	FromKey: index.Uint16,
    46  	Unique:  true,
    47  }
    48  
    49  func NewEdt(endpointID uint16, bytesPerSecond uint64) Edt {
    50  	return Edt{
    51  		EndpointID:      endpointID,
    52  		BytesPerSecond:  bytesPerSecond,
    53  		TimeHorizonDrop: uint64(DefaultDropHorizon),
    54  		Status:          reconciler.StatusPending(),
    55  	}
    56  }
    57  
    58  func NewEdtTable() (statedb.RWTable[Edt], error) {
    59  	return statedb.NewTable(
    60  		EdtTableName,
    61  		EdtIDIndex,
    62  	)
    63  }
    64  
    65  func (e Edt) BinaryKey() encoding.BinaryMarshaler {
    66  	k := EdtId{uint64(e.EndpointID)}
    67  	return bpf.StructBinaryMarshaler{Target: &k}
    68  }
    69  
    70  func (e Edt) BinaryValue() encoding.BinaryMarshaler {
    71  	v := EdtInfo{
    72  		Bps:             e.BytesPerSecond,
    73  		TimeLast:        0, // Used on the BPF-side
    74  		TimeHorizonDrop: e.TimeHorizonDrop,
    75  	}
    76  	return bpf.StructBinaryMarshaler{Target: &v}
    77  }
    78  
    79  func (e Edt) TableHeader() []string {
    80  	return []string{
    81  		"EndpointID",
    82  		"BitsPerSecond",
    83  		"TimeHorizonDrop",
    84  		"Status",
    85  	}
    86  }
    87  
    88  func (e Edt) TableRow() []string {
    89  	// Show the limit as bits per second as that's how it is configured via
    90  	// the annotation.
    91  	quantity := resource.NewQuantity(int64(e.BytesPerSecond*8), resource.DecimalSI)
    92  	return []string{
    93  		strconv.FormatUint(uint64(e.EndpointID), 10),
    94  		quantity.String(),
    95  		strconv.FormatUint(e.TimeHorizonDrop, 10),
    96  		e.Status.String(),
    97  	}
    98  }