diff --git a/plugins/meta/bandwidth/bandwidth_linux_test.go b/plugins/meta/bandwidth/bandwidth_linux_test.go index 2a973c57..c3d9cb01 100644 --- a/plugins/meta/bandwidth/bandwidth_linux_test.go +++ b/plugins/meta/bandwidth/bandwidth_linux_test.go @@ -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() { It("Should work with multiple host veth interfaces", func() { conf := `{ @@ -874,8 +889,8 @@ var _ = Describe("bandwidth test", func() { Context("when chaining bandwidth plugin with PTP using 0.3.0 config", func() { var ptpConf string - var rateInBits int - var burstInBits int + var rateInBits uint64 + var burstInBits uint64 var packetInBytes int var containerWithoutTbfNS ns.NetNS var containerWithTbfNS ns.NetNS @@ -889,7 +904,7 @@ var _ = Describe("bandwidth test", func() { BeforeEach(func() { rateInBytes := 1000 - rateInBits = rateInBytes * 8 + rateInBits = uint64(rateInBytes * 8) burstInBits = rateInBits * 2 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() { var ptpConf string - var rateInBits int - var burstInBits int + var rateInBits uint64 + var burstInBits uint64 var packetInBytes int var containerWithoutTbfNS ns.NetNS var containerWithTbfNS ns.NetNS @@ -1034,7 +1049,7 @@ var _ = Describe("bandwidth test", func() { BeforeEach(func() { rateInBytes := 1000 - rateInBits = rateInBytes * 8 + rateInBits = uint64(rateInBytes * 8) burstInBits = rateInBits * 2 packetInBytes = rateInBytes * 25 diff --git a/plugins/meta/bandwidth/ifb_creator.go b/plugins/meta/bandwidth/ifb_creator.go index c7f90cd0..205b40a0 100644 --- a/plugins/meta/bandwidth/ifb_creator.go +++ b/plugins/meta/bandwidth/ifb_creator.go @@ -50,7 +50,7 @@ func TeardownIfb(deviceName string) error { return err } -func CreateIngressQdisc(rateInBits, burstInBits int, hostDeviceName string) error { +func CreateIngressQdisc(rateInBits, burstInBits uint64, hostDeviceName string) error { hostDevice, err := netlink.LinkByName(hostDeviceName) if err != nil { 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) } -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) if err != nil { return fmt.Errorf("get ifb device: %s", err) @@ -113,7 +113,7 @@ func CreateEgressQdisc(rateInBits, burstInBits int, hostDeviceName string, ifbDe return nil } -func createTBF(rateInBits, burstInBits, linkIndex int) error { +func createTBF(rateInBits, burstInBits uint64, linkIndex int) error { // Equivalent to // tc qdisc add dev link root tbf // rate netConf.BandwidthLimits.Rate diff --git a/plugins/meta/bandwidth/main.go b/plugins/meta/bandwidth/main.go index bedb1bad..f113d363 100644 --- a/plugins/meta/bandwidth/main.go +++ b/plugins/meta/bandwidth/main.go @@ -17,6 +17,7 @@ package main import ( "encoding/json" "fmt" + "math" "github.com/vishvananda/netlink" @@ -37,11 +38,11 @@ const ifbDevicePrefix = "bwp" // BandwidthEntry corresponds to a single entry in the bandwidth argument, // see CONVENTIONS.md 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 - 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 + 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 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 - 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 + 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 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 { @@ -101,7 +102,7 @@ func getBandwidth(conf *PluginConf) *BandwidthEntry { return conf.BandwidthEntry } -func validateRateAndBurst(rate int, burst int) error { +func validateRateAndBurst(rate, burst uint64) error { switch { case burst < 0 || rate < 0: 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") case rate == 0 && burst != 0: 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