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
This commit is contained in:
Byoungchan Lee 2023-07-26 14:31:56 +09:00 committed by Alessandro Boch
parent 306ce7b5b2
commit 6765a4402e
4 changed files with 54 additions and 0 deletions

View File

@ -154,6 +154,7 @@ func TestClassAddDel(t *testing.T) {
ReorderProb: 23.4,
CorruptProb: 10.0,
CorruptCorr: 10,
Rate64: 10 * 1024 * 1024,
}
qdiscnetem := NewNetem(qattrs, nattrs)
if err := QdiscAdd(qdiscnetem); err != nil {
@ -195,6 +196,9 @@ func TestClassAddDel(t *testing.T) {
if netem.DuplicateCorr != qdiscnetem.DuplicateCorr {
t.Fatal("DuplicateCorr does not match")
}
if netem.Rate64 != qdiscnetem.Rate64 {
t.Fatalf("Rate64 does not match. Expected %d, got %d", netem.Rate64, qdiscnetem.Rate64)
}
// Deletion
// automatically removes netem qdisc

View File

@ -105,6 +105,7 @@ const (
SizeofTcNetemCorr = 0x0c
SizeofTcNetemReorder = 0x08
SizeofTcNetemCorrupt = 0x08
SizeOfTcNetemRate = 0x10
SizeofTcTbfQopt = 2*SizeofTcRateSpec + 0x0c
SizeofTcHtbCopt = 2*SizeofTcRateSpec + 0x14
SizeofTcHtbGlob = 0x14
@ -372,6 +373,26 @@ func (x *TcNetemCorrupt) Serialize() []byte {
return (*(*[SizeofTcNetemCorrupt]byte)(unsafe.Pointer(x)))[:]
}
// TcNetemRate is a struct that represents the rate of a netem qdisc
type TcNetemRate struct {
Rate uint32
PacketOverhead int32
CellSize uint32
CellOverhead int32
}
func (msg *TcNetemRate) Len() int {
return SizeofTcRateSpec
}
func DeserializeTcNetemRate(b []byte) *TcNetemRate {
return (*TcNetemRate)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0]))
}
func (msg *TcNetemRate) Serialize() []byte {
return (*(*[SizeOfTcNetemRate]byte)(unsafe.Pointer(msg)))[:]
}
// struct tc_tbf_qopt {
// struct tc_ratespec rate;
// struct tc_ratespec peakrate;

View File

@ -160,6 +160,7 @@ type NetemQdiscAttrs struct {
ReorderCorr float32 // in %
CorruptProb float32 // in %
CorruptCorr float32 // in %
Rate64 uint64
}
func (q NetemQdiscAttrs) String() string {
@ -184,6 +185,7 @@ type Netem struct {
ReorderCorr uint32
CorruptProb uint32
CorruptCorr uint32
Rate64 uint64
}
func (netem *Netem) String() string {

View File

@ -17,6 +17,7 @@ func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem {
var lossCorr, delayCorr, duplicateCorr uint32
var reorderProb, reorderCorr uint32
var corruptProb, corruptCorr uint32
var rate64 uint64
latency := nattrs.Latency
loss := Percentage2u32(nattrs.Loss)
@ -57,6 +58,7 @@ func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem {
corruptProb = Percentage2u32(nattrs.CorruptProb)
corruptCorr = Percentage2u32(nattrs.CorruptCorr)
rate64 = nattrs.Rate64
return &Netem{
QdiscAttrs: attrs,
@ -73,6 +75,7 @@ func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem {
ReorderCorr: reorderCorr,
CorruptProb: corruptProb,
CorruptCorr: corruptCorr,
Rate64: rate64,
}
}
@ -234,6 +237,17 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
if reorder.Probability > 0 {
options.AddRtAttr(nl.TCA_NETEM_REORDER, reorder.Serialize())
}
// Rate
if qdisc.Rate64 > 0 {
rate := nl.TcNetemRate{}
if qdisc.Rate64 >= uint64(1<<32) {
options.AddRtAttr(nl.TCA_NETEM_RATE64, nl.Uint64Attr(qdisc.Rate64))
rate.Rate = ^uint32(0)
} else {
rate.Rate = uint32(qdisc.Rate64)
}
options.AddRtAttr(nl.TCA_NETEM_RATE, rate.Serialize())
}
case *Clsact:
options = nil
case *Ingress:
@ -601,6 +615,8 @@ func parseNetemData(qdisc Qdisc, value []byte) error {
if err != nil {
return err
}
var rate *nl.TcNetemRate
var rate64 uint64
for _, datum := range data {
switch datum.Attr.Type {
case nl.TCA_NETEM_CORR:
@ -616,8 +632,19 @@ func parseNetemData(qdisc Qdisc, value []byte) error {
opt := nl.DeserializeTcNetemReorder(datum.Value)
netem.ReorderProb = opt.Probability
netem.ReorderCorr = opt.Correlation
case nl.TCA_NETEM_RATE:
rate = nl.DeserializeTcNetemRate(datum.Value)
case nl.TCA_NETEM_RATE64:
rate64 = native.Uint64(datum.Value)
}
}
if rate != nil {
netem.Rate64 = uint64(rate.Rate)
if rate64 > 0 {
netem.Rate64 = rate64
}
}
return nil
}