Skip to content

Commit

Permalink
Merge pull request kubernetes#83572 from chendotjs/tc-fix
Browse files Browse the repository at this point in the history
bandwidth: use regexp to handle tc output and add IPv6 support
  • Loading branch information
k8s-ci-robot authored Mar 4, 2020
2 parents d682c83 + ef5c920 commit e4e3d72
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
26 changes: 16 additions & 10 deletions pkg/util/bandwidth/linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"encoding/hex"
"fmt"
"net"
"regexp"
"strings"

"k8s.io/apimachinery/pkg/api/resource"
Expand All @@ -33,6 +34,11 @@ import (
"k8s.io/klog"
)

var (
classShowMatcher = regexp.MustCompile(`class htb (1:\d+)`)
classAndHandleMatcher = regexp.MustCompile(`filter parent 1:.*fh (\d+::\d+).*flowid (\d+:\d+)`)
)

// tcShaper provides an implementation of the Shaper interface on Linux using the 'tc' tool.
// In general, using this requires that the caller posses the NET_CAP_ADMIN capability, though if you
// do this within an container, it only requires the NS_CAPABLE capability for manipulations to that
Expand Down Expand Up @@ -75,13 +81,13 @@ func (t *tcShaper) nextClassID() (int, error) {
if len(line) == 0 {
continue
}
parts := strings.Split(line, " ")
// expected tc line:
// class htb 1:1 root prio 0 rate 1000Kbit ceil 1000Kbit burst 1600b cburst 1600b
if len(parts) != 14 {
return -1, fmt.Errorf("unexpected output from tc: %s (%v)", scanner.Text(), parts)
matches := classShowMatcher.FindStringSubmatch(line)
if len(matches) != 2 {
return -1, fmt.Errorf("unexpected output from tc: %s (%v)", scanner.Text(), matches)
}
classes.Insert(parts[2])
classes.Insert(matches[1])
}

// Make sure it doesn't go forever
Expand Down Expand Up @@ -153,13 +159,14 @@ func (t *tcShaper) findCIDRClass(cidr string) (classAndHandleList [][]string, fo
continue
}
if strings.Contains(line, spec) {
parts := strings.Split(filter, " ")
// 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 classAndHandleList, false, fmt.Errorf("unexpected output from tc: %s %d (%v)", filter, len(parts), parts)
// `filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1` (old version) or
// `filter parent 1: protocol ip pref 1 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 not_in_hw` (new version)
matches := classAndHandleMatcher.FindStringSubmatch(filter)
if len(matches) != 3 {
return classAndHandleList, false, fmt.Errorf("unexpected output from tc: %s %d (%v)", filter, len(matches), matches)
}
resultTmp := []string{parts[18], parts[9]}
resultTmp := []string{matches[2], matches[1]}
classAndHandleList = append(classAndHandleList, resultTmp)
}
}
Expand Down Expand Up @@ -301,7 +308,6 @@ func (t *tcShaper) Reset(cidr string) error {
}
}
return nil

}

func (t *tcShaper) deleteInterface(class string) error {
Expand Down
24 changes: 24 additions & 0 deletions pkg/util/bandwidth/linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0
filter parent 1: protocol ip pref 1 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:2
match 01020000/ffff0000 at 16
`
var tcFilterOutputNewVersion = `filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 chain 0 fh 800: ht divisor 1
filter parent 1: protocol ip pref 1 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 not_in_hw
match ac110002/ffffffff at 16
filter parent 1: protocol ip pref 1 u32 chain 0 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:2 not_in_hw
match 01020000/ffff0000 at 16
`

func TestFindCIDRClass(t *testing.T) {
tests := []struct {
Expand Down Expand Up @@ -240,6 +247,23 @@ func TestFindCIDRClass(t *testing.T) {
output: tcFilterOutput,
expectNotFound: true,
},
{
cidr: "172.17.0.2/32",
output: tcFilterOutputNewVersion,
expectedClass: "1:1",
expectedHandle: "800::800",
},
{
cidr: "1.2.3.4/16",
output: tcFilterOutputNewVersion,
expectedClass: "1:2",
expectedHandle: "800::801",
},
{
cidr: "2.2.3.4/16",
output: tcFilterOutputNewVersion,
expectNotFound: true,
},
{
err: errors.New("test error"),
expectErr: true,
Expand Down

0 comments on commit e4e3d72

Please sign in to comment.