@@ -24,6 +24,7 @@ import (
24
24
"encoding/hex"
25
25
"fmt"
26
26
"net"
27
+ "regexp"
27
28
"strings"
28
29
29
30
"k8s.io/apimachinery/pkg/api/resource"
@@ -33,6 +34,11 @@ import (
33
34
"k8s.io/klog"
34
35
)
35
36
37
+ var (
38
+ classShowMatcher = regexp .MustCompile (`class htb (1:\d+)` )
39
+ classAndHandleMatcher = regexp .MustCompile (`filter parent 1:.*fh (\d+::\d+).*flowid (\d+:\d+)` )
40
+ )
41
+
36
42
// tcShaper provides an implementation of the Shaper interface on Linux using the 'tc' tool.
37
43
// In general, using this requires that the caller posses the NET_CAP_ADMIN capability, though if you
38
44
// do this within an container, it only requires the NS_CAPABLE capability for manipulations to that
@@ -75,13 +81,13 @@ func (t *tcShaper) nextClassID() (int, error) {
75
81
if len (line ) == 0 {
76
82
continue
77
83
}
78
- parts := strings .Split (line , " " )
79
84
// expected tc line:
80
85
// class htb 1:1 root prio 0 rate 1000Kbit ceil 1000Kbit burst 1600b cburst 1600b
81
- if len (parts ) != 14 {
82
- return - 1 , fmt .Errorf ("unexpected output from tc: %s (%v)" , scanner .Text (), parts )
86
+ matches := classShowMatcher .FindStringSubmatch (line )
87
+ if len (matches ) != 2 {
88
+ return - 1 , fmt .Errorf ("unexpected output from tc: %s (%v)" , scanner .Text (), matches )
83
89
}
84
- classes .Insert (parts [ 2 ])
90
+ classes .Insert (matches [ 1 ])
85
91
}
86
92
87
93
// Make sure it doesn't go forever
@@ -153,13 +159,14 @@ func (t *tcShaper) findCIDRClass(cidr string) (classAndHandleList [][]string, fo
153
159
continue
154
160
}
155
161
if strings .Contains (line , spec ) {
156
- parts := strings .Split (filter , " " )
157
162
// expected tc line:
158
- // filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1
159
- if len (parts ) != 19 {
160
- return classAndHandleList , false , fmt .Errorf ("unexpected output from tc: %s %d (%v)" , filter , len (parts ), parts )
163
+ // `filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1` (old version) or
164
+ // `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)
165
+ matches := classAndHandleMatcher .FindStringSubmatch (filter )
166
+ if len (matches ) != 3 {
167
+ return classAndHandleList , false , fmt .Errorf ("unexpected output from tc: %s %d (%v)" , filter , len (matches ), matches )
161
168
}
162
- resultTmp := []string {parts [ 18 ], parts [ 9 ]}
169
+ resultTmp := []string {matches [ 2 ], matches [ 1 ]}
163
170
classAndHandleList = append (classAndHandleList , resultTmp )
164
171
}
165
172
}
@@ -301,7 +308,6 @@ func (t *tcShaper) Reset(cidr string) error {
301
308
}
302
309
}
303
310
return nil
304
-
305
311
}
306
312
307
313
func (t * tcShaper ) deleteInterface (class string ) error {
0 commit comments