Skip to content

Commit 6765a44

Browse files
hpcnt-daniel-laboch
authored andcommitted
Add support for TCA_NETEM_RATE64 in Netem qdisc
- `Rate64` field added to the `Netem` struct in `qdisc.go` - Implemented serialization and deserialization methods for `Rate64` - Modify `TestClassAddDel` test to validate Rate64 changes
1 parent 306ce7b commit 6765a44

File tree

4 files changed

+54
-0
lines changed

4 files changed

+54
-0
lines changed

class_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ func TestClassAddDel(t *testing.T) {
154154
ReorderProb: 23.4,
155155
CorruptProb: 10.0,
156156
CorruptCorr: 10,
157+
Rate64: 10 * 1024 * 1024,
157158
}
158159
qdiscnetem := NewNetem(qattrs, nattrs)
159160
if err := QdiscAdd(qdiscnetem); err != nil {
@@ -195,6 +196,9 @@ func TestClassAddDel(t *testing.T) {
195196
if netem.DuplicateCorr != qdiscnetem.DuplicateCorr {
196197
t.Fatal("DuplicateCorr does not match")
197198
}
199+
if netem.Rate64 != qdiscnetem.Rate64 {
200+
t.Fatalf("Rate64 does not match. Expected %d, got %d", netem.Rate64, qdiscnetem.Rate64)
201+
}
198202

199203
// Deletion
200204
// automatically removes netem qdisc

nl/tc_linux.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ const (
105105
SizeofTcNetemCorr = 0x0c
106106
SizeofTcNetemReorder = 0x08
107107
SizeofTcNetemCorrupt = 0x08
108+
SizeOfTcNetemRate = 0x10
108109
SizeofTcTbfQopt = 2*SizeofTcRateSpec + 0x0c
109110
SizeofTcHtbCopt = 2*SizeofTcRateSpec + 0x14
110111
SizeofTcHtbGlob = 0x14
@@ -372,6 +373,26 @@ func (x *TcNetemCorrupt) Serialize() []byte {
372373
return (*(*[SizeofTcNetemCorrupt]byte)(unsafe.Pointer(x)))[:]
373374
}
374375

376+
// TcNetemRate is a struct that represents the rate of a netem qdisc
377+
type TcNetemRate struct {
378+
Rate uint32
379+
PacketOverhead int32
380+
CellSize uint32
381+
CellOverhead int32
382+
}
383+
384+
func (msg *TcNetemRate) Len() int {
385+
return SizeofTcRateSpec
386+
}
387+
388+
func DeserializeTcNetemRate(b []byte) *TcNetemRate {
389+
return (*TcNetemRate)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0]))
390+
}
391+
392+
func (msg *TcNetemRate) Serialize() []byte {
393+
return (*(*[SizeOfTcNetemRate]byte)(unsafe.Pointer(msg)))[:]
394+
}
395+
375396
// struct tc_tbf_qopt {
376397
// struct tc_ratespec rate;
377398
// struct tc_ratespec peakrate;

qdisc.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ type NetemQdiscAttrs struct {
160160
ReorderCorr float32 // in %
161161
CorruptProb float32 // in %
162162
CorruptCorr float32 // in %
163+
Rate64 uint64
163164
}
164165

165166
func (q NetemQdiscAttrs) String() string {
@@ -184,6 +185,7 @@ type Netem struct {
184185
ReorderCorr uint32
185186
CorruptProb uint32
186187
CorruptCorr uint32
188+
Rate64 uint64
187189
}
188190

189191
func (netem *Netem) String() string {

qdisc_linux.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem {
1717
var lossCorr, delayCorr, duplicateCorr uint32
1818
var reorderProb, reorderCorr uint32
1919
var corruptProb, corruptCorr uint32
20+
var rate64 uint64
2021

2122
latency := nattrs.Latency
2223
loss := Percentage2u32(nattrs.Loss)
@@ -57,6 +58,7 @@ func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem {
5758

5859
corruptProb = Percentage2u32(nattrs.CorruptProb)
5960
corruptCorr = Percentage2u32(nattrs.CorruptCorr)
61+
rate64 = nattrs.Rate64
6062

6163
return &Netem{
6264
QdiscAttrs: attrs,
@@ -73,6 +75,7 @@ func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem {
7375
ReorderCorr: reorderCorr,
7476
CorruptProb: corruptProb,
7577
CorruptCorr: corruptCorr,
78+
Rate64: rate64,
7679
}
7780
}
7881

@@ -234,6 +237,17 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
234237
if reorder.Probability > 0 {
235238
options.AddRtAttr(nl.TCA_NETEM_REORDER, reorder.Serialize())
236239
}
240+
// Rate
241+
if qdisc.Rate64 > 0 {
242+
rate := nl.TcNetemRate{}
243+
if qdisc.Rate64 >= uint64(1<<32) {
244+
options.AddRtAttr(nl.TCA_NETEM_RATE64, nl.Uint64Attr(qdisc.Rate64))
245+
rate.Rate = ^uint32(0)
246+
} else {
247+
rate.Rate = uint32(qdisc.Rate64)
248+
}
249+
options.AddRtAttr(nl.TCA_NETEM_RATE, rate.Serialize())
250+
}
237251
case *Clsact:
238252
options = nil
239253
case *Ingress:
@@ -601,6 +615,8 @@ func parseNetemData(qdisc Qdisc, value []byte) error {
601615
if err != nil {
602616
return err
603617
}
618+
var rate *nl.TcNetemRate
619+
var rate64 uint64
604620
for _, datum := range data {
605621
switch datum.Attr.Type {
606622
case nl.TCA_NETEM_CORR:
@@ -616,8 +632,19 @@ func parseNetemData(qdisc Qdisc, value []byte) error {
616632
opt := nl.DeserializeTcNetemReorder(datum.Value)
617633
netem.ReorderProb = opt.Probability
618634
netem.ReorderCorr = opt.Correlation
635+
case nl.TCA_NETEM_RATE:
636+
rate = nl.DeserializeTcNetemRate(datum.Value)
637+
case nl.TCA_NETEM_RATE64:
638+
rate64 = native.Uint64(datum.Value)
619639
}
620640
}
641+
if rate != nil {
642+
netem.Rate64 = uint64(rate.Rate)
643+
if rate64 > 0 {
644+
netem.Rate64 = rate64
645+
}
646+
}
647+
621648
return nil
622649
}
623650

0 commit comments

Comments
 (0)