Make htb class work on older kernels (2.6)

This commit is contained in:
chantra 2015-12-25 23:19:37 -08:00
parent bfd70f5564
commit 683203e227
3 changed files with 37 additions and 13 deletions

View File

@ -2,6 +2,8 @@ package netlink
import ( import (
"fmt" "fmt"
"github.com/vishvananda/netlink/nl"
) )
type Class interface { type Class interface {
@ -41,21 +43,29 @@ func (q HtbClassAttrs) String() string {
// Htb class // Htb class
type HtbClass struct { type HtbClass struct {
ClassAttrs ClassAttrs
Rate uint64 Rate nl.TcRateSpec
Ceil uint64 Ceil nl.TcRateSpec
Buffer uint32 Buffer uint32
Cbuffer uint32 Cbuffer uint32
Quantum uint32 Quantum uint32
Level uint32 Level uint32
Prio uint32 Prio uint32
Rtab [256]uint32
Ctab [256]uint32
} }
func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass { func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass {
var rtab [256]uint32
var ctab [256]uint32
cell_log := -1
ccell_log := -1
linklayer := nl.LINKLAYER_ETHERNET
mtu := 1600 mtu := 1600
rate := cattrs.Rate / 8 rate := cattrs.Rate / 8
ceil := cattrs.Ceil / 8 ceil := cattrs.Ceil / 8
buffer := cattrs.Buffer buffer := cattrs.Buffer
cbuffer := cattrs.Cbuffer cbuffer := cattrs.Cbuffer
if ceil == 0 { if ceil == 0 {
ceil = rate ceil = rate
} }
@ -70,15 +80,27 @@ func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass {
} }
cbuffer = uint32(Xmittime(ceil, cbuffer)) cbuffer = uint32(Xmittime(ceil, cbuffer))
tcrate := nl.TcRateSpec{Rate: uint32(rate)}
if CalcRtable(&tcrate, rtab, cell_log, uint32(mtu), linklayer) < 0 {
return nil
}
tcceil := nl.TcRateSpec{Rate: uint32(ceil)}
if CalcRtable(&tcceil, ctab, ccell_log, uint32(mtu), linklayer) < 0 {
return nil
}
return &HtbClass{ return &HtbClass{
ClassAttrs: attrs, ClassAttrs: attrs,
Rate: rate, Rate: tcrate,
Ceil: ceil, Ceil: tcceil,
Buffer: buffer, Buffer: buffer,
Cbuffer: cbuffer, Cbuffer: cbuffer,
Quantum: 10, Quantum: 10,
Level: 0, Level: 0,
Prio: 0, Prio: 0,
Rtab: rtab,
Ctab: ctab,
} }
} }

View File

@ -65,8 +65,8 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
if htb, ok := class.(*HtbClass); ok { if htb, ok := class.(*HtbClass); ok {
opt := nl.TcHtbCopt{} opt := nl.TcHtbCopt{}
opt.Rate.Rate = uint32(htb.Rate) opt.Rate = htb.Rate
opt.Ceil.Rate = uint32(htb.Ceil) opt.Ceil = htb.Ceil
opt.Buffer = htb.Buffer opt.Buffer = htb.Buffer
opt.Cbuffer = htb.Cbuffer opt.Cbuffer = htb.Cbuffer
opt.Quantum = htb.Quantum opt.Quantum = htb.Quantum
@ -74,6 +74,8 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
opt.Prio = htb.Prio opt.Prio = htb.Prio
// TODO: Handle Debug properly. For now default to 0 // TODO: Handle Debug properly. For now default to 0
nl.NewRtAttrChild(options, nl.TCA_HTB_PARMS, opt.Serialize()) nl.NewRtAttrChild(options, nl.TCA_HTB_PARMS, opt.Serialize())
nl.NewRtAttrChild(options, nl.TCA_HTB_RTAB, SerializeRtab(htb.Rtab))
nl.NewRtAttrChild(options, nl.TCA_HTB_CTAB, SerializeRtab(htb.Ctab))
} }
req.AddData(options) req.AddData(options)
return nil return nil
@ -155,8 +157,8 @@ func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, erro
switch datum.Attr.Type { switch datum.Attr.Type {
case nl.TCA_HTB_PARMS: case nl.TCA_HTB_PARMS:
opt := nl.DeserializeTcHtbCopt(datum.Value) opt := nl.DeserializeTcHtbCopt(datum.Value)
htb.Rate = uint64(opt.Rate.Rate) htb.Rate = opt.Rate
htb.Ceil = uint64(opt.Ceil.Rate) htb.Ceil = opt.Ceil
htb.Buffer = opt.Buffer htb.Buffer = opt.Buffer
htb.Cbuffer = opt.Cbuffer htb.Cbuffer = opt.Cbuffer
htb.Quantum = opt.Quantum htb.Quantum = opt.Quantum

View File

@ -67,10 +67,10 @@ func TestClassAddDel(t *testing.T) {
if !ok { if !ok {
t.Fatal("Class is the wrong type") t.Fatal("Class is the wrong type")
} }
if htb.Rate != class.Rate { if htb.Rate.Rate != class.Rate.Rate {
t.Fatal("Rate doesn't match") t.Fatal("Rate doesn't match")
} }
if htb.Ceil != class.Ceil { if htb.Ceil.Rate != class.Ceil.Rate {
t.Fatal("Ceil doesn't match") t.Fatal("Ceil doesn't match")
} }
if htb.Buffer != class.Buffer { if htb.Buffer != class.Buffer {
@ -299,7 +299,7 @@ func TestHtbClassAddHtbClassChangeDel(t *testing.T) {
t.Fatal("Class is the wrong type") t.Fatal("Class is the wrong type")
} }
// Verify that the rate value has changed. // Verify that the rate value has changed.
if htb.Rate != class.Rate { if htb.Rate.Rate != class.Rate.Rate {
t.Fatal("Rate did not get changed while changing the class.") t.Fatal("Rate did not get changed while changing the class.")
} }
@ -348,7 +348,7 @@ func TestHtbClassAddHtbClassChangeDel(t *testing.T) {
t.Fatal("Class is the wrong type") t.Fatal("Class is the wrong type")
} }
// Verify that the rate value has changed. // Verify that the rate value has changed.
if htb.Rate != class.Rate { if htb.Rate.Rate != class.Rate.Rate {
t.Fatal("Rate did not get changed while changing the class.") t.Fatal("Rate did not get changed while changing the class.")
} }
@ -375,7 +375,7 @@ func TestHtbClassAddHtbClassChangeDel(t *testing.T) {
t.Fatal("Class is the wrong type") t.Fatal("Class is the wrong type")
} }
// Verify that the rate value has changed. // Verify that the rate value has changed.
if htb.Rate != class.Rate { if htb.Rate.Rate != class.Rate.Rate {
t.Fatal("Rate did not get changed while changing the class.") t.Fatal("Rate did not get changed while changing the class.")
} }