diff --git a/pkg/util/bandwidth/linux.go b/pkg/util/bandwidth/linux.go index 539e0588f9..b8936a34f0 100644 --- a/pkg/util/bandwidth/linux.go +++ b/pkg/util/bandwidth/linux.go @@ -128,15 +128,15 @@ func asciiCIDR(cidr string) (string, error) { return fmt.Sprintf("%s/%d", ip.String(), size), nil } -func (t *tcShaper) findCIDRClass(cidr string) (class, handle string, found bool, err error) { +func (t *tcShaper) findCIDRClass(cidr string) (classAndHandleList [][]string, found bool, err error) { data, err := t.e.Command("tc", "filter", "show", "dev", t.iface).CombinedOutput() if err != nil { - return "", "", false, err + return classAndHandleList, false, err } hex, err := hexCIDR(cidr) if err != nil { - return "", "", false, err + return classAndHandleList, false, err } spec := fmt.Sprintf("match %s", hex) @@ -156,12 +156,17 @@ func (t *tcShaper) findCIDRClass(cidr string) (class, handle string, found bool, // expected tc line: // filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 if len(parts) != 19 { - return "", "", false, fmt.Errorf("unexpected output from tc: %s %d (%v)", filter, len(parts), parts) + return classAndHandleList, false, fmt.Errorf("unexpected output from tc: %s %d (%v)", filter, len(parts), parts) + } else { + resultTmp := []string{parts[18], parts[9]} + classAndHandleList = append(classAndHandleList, resultTmp) } - return parts[18], parts[9], true, nil } } - return "", "", false, nil + if len(classAndHandleList) > 0 { + return classAndHandleList, true, nil + } + return classAndHandleList, false, nil } func makeKBitString(rsrc *resource.Quantity) string { @@ -237,7 +242,7 @@ func (t *tcShaper) interfaceExists() (bool, string, error) { } func (t *tcShaper) ReconcileCIDR(cidr string, upload, download *resource.Quantity) error { - _, _, found, err := t.findCIDRClass(cidr) + _, found, err := t.findCIDRClass(cidr) if err != nil { return err } @@ -272,22 +277,31 @@ func (t *tcShaper) initializeInterface() error { } func (t *tcShaper) Reset(cidr string) error { - class, handle, found, err := t.findCIDRClass(cidr) + classAndHandle, found, err := t.findCIDRClass(cidr) if err != nil { return err } if !found { return fmt.Errorf("Failed to find cidr: %s on interface: %s", cidr, t.iface) } - if err := t.execAndLog("tc", "filter", "del", - "dev", t.iface, - "parent", "1:", - "proto", "ip", - "prio", "1", - "handle", handle, "u32"); err != nil { - return err + for i := 0; i < len(classAndHandle); i++ { + if err := t.execAndLog("tc", "filter", "del", + "dev", t.iface, + "parent", "1:", + "proto", "ip", + "prio", "1", + "handle", classAndHandle[i][1], "u32"); err != nil { + return err + } + if err := t.execAndLog("tc", "class", "del", + "dev", t.iface, + "parent", "1:", + "classid", classAndHandle[i][0]); err != nil { + return err + } } - return t.execAndLog("tc", "class", "del", "dev", t.iface, "parent", "1:", "classid", class) + return nil + } func (t *tcShaper) deleteInterface(class string) error { diff --git a/pkg/util/bandwidth/linux_test.go b/pkg/util/bandwidth/linux_test.go index 61bfc13de3..07aeac73b0 100644 --- a/pkg/util/bandwidth/linux_test.go +++ b/pkg/util/bandwidth/linux_test.go @@ -259,7 +259,7 @@ func TestFindCIDRClass(t *testing.T) { }, } shaper := &tcShaper{e: &fexec} - class, handle, found, err := shaper.findCIDRClass(test.cidr) + classAndHandle, found, err := shaper.findCIDRClass(test.cidr) if test.expectErr { if err == nil { t.Errorf("unexpected non-error") @@ -270,14 +270,14 @@ func TestFindCIDRClass(t *testing.T) { } if test.expectNotFound { if found { - t.Errorf("unexpectedly found an interface: %s %s", class, handle) + t.Errorf("unexpectedly found an interface: %s", classAndHandle) } } else { - if class != test.expectedClass { - t.Errorf("expected: %s, found %s", test.expectedClass, class) + if classAndHandle[0][0] != test.expectedClass { + t.Errorf("expected class: %s, found %s", test.expectedClass, classAndHandle) } - if handle != test.expectedHandle { - t.Errorf("expected: %s, found %s", test.expectedHandle, handle) + if classAndHandle[0][1] != test.expectedHandle { + t.Errorf("expected handle: %s, found %s", test.expectedHandle, classAndHandle) } } }