Merge pull request #389 from CallMeFoxie/bw-units

Use uint64 for Bandwidth plugin
This commit is contained in:
Bryan Boreham 2019-10-09 16:25:06 +01:00 committed by GitHub
commit 411d060b81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 14 deletions

View File

@ -621,6 +621,21 @@ var _ = Describe("bandwidth test", func() {
}) })
}) })
Describe("Validating input", func() {
It("Should allow only 4GB burst rate", func() {
err := validateRateAndBurst(5000, 4*1024*1024*1024*8-16) // 2 bytes less than the max should pass
Expect(err).NotTo(HaveOccurred())
err = validateRateAndBurst(5000, 4*1024*1024*1024*8) // we're 1 bit above MaxUint32
Expect(err).To(HaveOccurred())
err = validateRateAndBurst(0, 1)
Expect(err).To(HaveOccurred())
err = validateRateAndBurst(1, 0)
Expect(err).To(HaveOccurred())
err = validateRateAndBurst(0, 0)
Expect(err).NotTo(HaveOccurred())
})
})
Describe("Getting the host interface which plugin should work on from veth peer of container interface", func() { Describe("Getting the host interface which plugin should work on from veth peer of container interface", func() {
It("Should work with multiple host veth interfaces", func() { It("Should work with multiple host veth interfaces", func() {
conf := `{ conf := `{
@ -874,8 +889,8 @@ var _ = Describe("bandwidth test", func() {
Context("when chaining bandwidth plugin with PTP using 0.3.0 config", func() { Context("when chaining bandwidth plugin with PTP using 0.3.0 config", func() {
var ptpConf string var ptpConf string
var rateInBits int var rateInBits uint64
var burstInBits int var burstInBits uint64
var packetInBytes int var packetInBytes int
var containerWithoutTbfNS ns.NetNS var containerWithoutTbfNS ns.NetNS
var containerWithTbfNS ns.NetNS var containerWithTbfNS ns.NetNS
@ -889,7 +904,7 @@ var _ = Describe("bandwidth test", func() {
BeforeEach(func() { BeforeEach(func() {
rateInBytes := 1000 rateInBytes := 1000
rateInBits = rateInBytes * 8 rateInBits = uint64(rateInBytes * 8)
burstInBits = rateInBits * 2 burstInBits = rateInBits * 2
packetInBytes = rateInBytes * 25 packetInBytes = rateInBytes * 25
@ -1019,8 +1034,8 @@ var _ = Describe("bandwidth test", func() {
Context("when chaining bandwidth plugin with PTP using 0.4.0 config", func() { Context("when chaining bandwidth plugin with PTP using 0.4.0 config", func() {
var ptpConf string var ptpConf string
var rateInBits int var rateInBits uint64
var burstInBits int var burstInBits uint64
var packetInBytes int var packetInBytes int
var containerWithoutTbfNS ns.NetNS var containerWithoutTbfNS ns.NetNS
var containerWithTbfNS ns.NetNS var containerWithTbfNS ns.NetNS
@ -1034,7 +1049,7 @@ var _ = Describe("bandwidth test", func() {
BeforeEach(func() { BeforeEach(func() {
rateInBytes := 1000 rateInBytes := 1000
rateInBits = rateInBytes * 8 rateInBits = uint64(rateInBytes * 8)
burstInBits = rateInBits * 2 burstInBits = rateInBits * 2
packetInBytes = rateInBytes * 25 packetInBytes = rateInBytes * 25

View File

@ -50,7 +50,7 @@ func TeardownIfb(deviceName string) error {
return err return err
} }
func CreateIngressQdisc(rateInBits, burstInBits int, hostDeviceName string) error { func CreateIngressQdisc(rateInBits, burstInBits uint64, hostDeviceName string) error {
hostDevice, err := netlink.LinkByName(hostDeviceName) hostDevice, err := netlink.LinkByName(hostDeviceName)
if err != nil { if err != nil {
return fmt.Errorf("get host device: %s", err) return fmt.Errorf("get host device: %s", err)
@ -58,7 +58,7 @@ func CreateIngressQdisc(rateInBits, burstInBits int, hostDeviceName string) erro
return createTBF(rateInBits, burstInBits, hostDevice.Attrs().Index) return createTBF(rateInBits, burstInBits, hostDevice.Attrs().Index)
} }
func CreateEgressQdisc(rateInBits, burstInBits int, hostDeviceName string, ifbDeviceName string) error { func CreateEgressQdisc(rateInBits, burstInBits uint64, hostDeviceName string, ifbDeviceName string) error {
ifbDevice, err := netlink.LinkByName(ifbDeviceName) ifbDevice, err := netlink.LinkByName(ifbDeviceName)
if err != nil { if err != nil {
return fmt.Errorf("get ifb device: %s", err) return fmt.Errorf("get ifb device: %s", err)
@ -113,7 +113,7 @@ func CreateEgressQdisc(rateInBits, burstInBits int, hostDeviceName string, ifbDe
return nil return nil
} }
func createTBF(rateInBits, burstInBits, linkIndex int) error { func createTBF(rateInBits, burstInBits uint64, linkIndex int) error {
// Equivalent to // Equivalent to
// tc qdisc add dev link root tbf // tc qdisc add dev link root tbf
// rate netConf.BandwidthLimits.Rate // rate netConf.BandwidthLimits.Rate

View File

@ -17,6 +17,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
@ -37,11 +38,11 @@ const ifbDevicePrefix = "bwp"
// BandwidthEntry corresponds to a single entry in the bandwidth argument, // BandwidthEntry corresponds to a single entry in the bandwidth argument,
// see CONVENTIONS.md // see CONVENTIONS.md
type BandwidthEntry struct { type BandwidthEntry struct {
IngressRate int `json:"ingressRate"` //Bandwidth rate in bps for traffic through container. 0 for no limit. If ingressRate is set, ingressBurst must also be set IngressRate uint64 `json:"ingressRate"` //Bandwidth rate in bps for traffic through container. 0 for no limit. If ingressRate is set, ingressBurst must also be set
IngressBurst int `json:"ingressBurst"` //Bandwidth burst in bits for traffic through container. 0 for no limit. If ingressBurst is set, ingressRate must also be set IngressBurst uint64 `json:"ingressBurst"` //Bandwidth burst in bits for traffic through container. 0 for no limit. If ingressBurst is set, ingressRate must also be set
EgressRate int `json:"egressRate"` //Bandwidth rate in bps for traffic through container. 0 for no limit. If egressRate is set, egressBurst must also be set EgressRate uint64 `json:"egressRate"` //Bandwidth rate in bps for traffic through container. 0 for no limit. If egressRate is set, egressBurst must also be set
EgressBurst int `json:"egressBurst"` //Bandwidth burst in bits for traffic through container. 0 for no limit. If egressBurst is set, egressRate must also be set EgressBurst uint64 `json:"egressBurst"` //Bandwidth burst in bits for traffic through container. 0 for no limit. If egressBurst is set, egressRate must also be set
} }
func (bw *BandwidthEntry) isZero() bool { func (bw *BandwidthEntry) isZero() bool {
@ -101,7 +102,7 @@ func getBandwidth(conf *PluginConf) *BandwidthEntry {
return conf.BandwidthEntry return conf.BandwidthEntry
} }
func validateRateAndBurst(rate int, burst int) error { func validateRateAndBurst(rate, burst uint64) error {
switch { switch {
case burst < 0 || rate < 0: case burst < 0 || rate < 0:
return fmt.Errorf("rate and burst must be a positive integer") return fmt.Errorf("rate and burst must be a positive integer")
@ -109,6 +110,8 @@ func validateRateAndBurst(rate int, burst int) error {
return fmt.Errorf("if rate is set, burst must also be set") return fmt.Errorf("if rate is set, burst must also be set")
case rate == 0 && burst != 0: case rate == 0 && burst != 0:
return fmt.Errorf("if burst is set, rate must also be set") return fmt.Errorf("if burst is set, rate must also be set")
case burst/8 >= math.MaxUint32:
return fmt.Errorf("burst cannot be more than 4GB")
} }
return nil return nil