diff --git a/src/runtime/virtcontainers/fc.go b/src/runtime/virtcontainers/fc.go index 91885f49ba..60df0f2520 100644 --- a/src/runtime/virtcontainers/fc.go +++ b/src/runtime/virtcontainers/fc.go @@ -908,11 +908,52 @@ func (fc *firecracker) fcAddNetDevice(endpoint Endpoint) { defer span.Finish() ifaceID := endpoint.Name() + + // The implementation of rate limiter is based on TBF. + // Rate Limiter defines a token bucket with a maximum capacity (size) to store tokens, and an interval for refilling purposes (refill_time). + // The refill-rate is derived from size and refill_time, and it is the constant rate at which the tokens replenish. + refillTime := uint64(1000) + var rxRateLimiter models.RateLimiter + rxSize := fc.config.RxRateLimiterMaxRate + if rxSize > 0 { + fc.Logger().Info("Add rx rate limiter") + + // kata-defined rxSize is in bits with scaling factors of 1000, but firecracker-defined + // rxSize is in bytes with scaling factors of 1024, need reversion. + rxSize = revertBytes(rxSize / 8) + rxTokenBucket := models.TokenBucket{ + RefillTime: &refillTime, + Size: &rxSize, + } + rxRateLimiter = models.RateLimiter{ + Bandwidth: &rxTokenBucket, + } + } + + var txRateLimiter models.RateLimiter + txSize := fc.config.TxRateLimiterMaxRate + if txSize > 0 { + fc.Logger().Info("Add tx rate limiter") + + // kata-defined txSize is in bits with scaling factors of 1000, but firecracker-defined + // txSize is in bytes with scaling factors of 1024, need reversion. + txSize = revertBytes(txSize / 8) + txTokenBucket := models.TokenBucket{ + RefillTime: &refillTime, + Size: &txSize, + } + txRateLimiter = models.RateLimiter{ + Bandwidth: &txTokenBucket, + } + } + ifaceCfg := &models.NetworkInterface{ AllowMmdsRequests: false, GuestMac: endpoint.HardwareAddr(), IfaceID: &ifaceID, HostDevName: &endpoint.NetworkPair().TapInterface.TAPIface.Name, + RxRateLimiter: &rxRateLimiter, + TxRateLimiter: &txRateLimiter, } fc.fcConfig.NetworkInterfaces = append(fc.fcConfig.NetworkInterfaces, ifaceCfg) @@ -1216,3 +1257,16 @@ func (fc *firecracker) watchConsole() (*os.File, error) { func (fc *firecracker) isRateLimiterBuiltin() bool { return true } + +// In firecracker, it accepts the size of rate limiter in scaling factors of 2^10(1024) +// But in kata-defined rate limiter, for better Human-readability, we prefer scaling factors of 10^3(1000). +// func revertByte reverts num from scaling factors of 1000 to 1024, e.g. 10000000(10MB) to 10485760. +func revertBytes(num uint64) uint64 { + a := num / 1000 + b := num % 1000 + if a == 0 { + return num + } else { + return 1024*revertBytes(a) + b + } +} diff --git a/src/runtime/virtcontainers/fc_test.go b/src/runtime/virtcontainers/fc_test.go index 656ece5cff..96e730caad 100644 --- a/src/runtime/virtcontainers/fc_test.go +++ b/src/runtime/virtcontainers/fc_test.go @@ -45,3 +45,14 @@ func TestFCTruncateID(t *testing.T) { id = fc.truncateID(testShortID) assert.Equal(expectedID, id) } + +func TestRevertBytes(t *testing.T) { + assert := assert.New(t) + + //10MB + testNum := uint64(10000000) + expectedNum := uint64(10485760) + + num := revertBytes(testNum) + assert.Equal(expectedNum, num) +} diff --git a/src/runtime/virtcontainers/pkg/firecracker/client/models/token_bucket.go b/src/runtime/virtcontainers/pkg/firecracker/client/models/token_bucket.go index 52e616eb6d..cba2b41d2a 100644 --- a/src/runtime/virtcontainers/pkg/firecracker/client/models/token_bucket.go +++ b/src/runtime/virtcontainers/pkg/firecracker/client/models/token_bucket.go @@ -19,17 +19,17 @@ type TokenBucket struct { // The initial size of a token bucket. // Minimum: 0 - OneTimeBurst *int64 `json:"one_time_burst,omitempty"` + OneTimeBurst *uint64 `json:"one_time_burst,omitempty"` // The amount of milliseconds it takes for the bucket to refill. // Required: true // Minimum: 0 - RefillTime *int64 `json:"refill_time"` + RefillTime *uint64 `json:"refill_time"` // The total number of tokens this bucket can hold. // Required: true // Minimum: 0 - Size *int64 `json:"size"` + Size *uint64 `json:"size"` } // Validate validates this token bucket diff --git a/src/runtime/virtcontainers/pkg/firecracker/firecracker.yaml b/src/runtime/virtcontainers/pkg/firecracker/firecracker.yaml index 376da21808..fbd5b8d794 100644 --- a/src/runtime/virtcontainers/pkg/firecracker/firecracker.yaml +++ b/src/runtime/virtcontainers/pkg/firecracker/firecracker.yaml @@ -615,17 +615,17 @@ definitions: properties: size: type: integer - format: int64 + format: uint64 description: The total number of tokens this bucket can hold. minimum: 0 one_time_burst: type: integer - format: int64 + format: uint64 description: The initial size of a token bucket. minimum: 0 refill_time: type: integer - format: int64 + format: uint64 description: The amount of milliseconds it takes for the bucket to refill. minimum: 0