2015-09-10 23:20:18 +00:00
|
|
|
package netlink
|
|
|
|
|
|
|
|
import (
|
2015-12-26 07:40:22 +00:00
|
|
|
"errors"
|
2015-09-10 23:20:18 +00:00
|
|
|
"fmt"
|
2015-12-26 07:19:37 +00:00
|
|
|
|
|
|
|
"github.com/vishvananda/netlink/nl"
|
2015-09-10 23:20:18 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Class interface {
|
|
|
|
Attrs() *ClassAttrs
|
|
|
|
Type() string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Class represents a netlink class. A filter is associated with a link,
|
|
|
|
// has a handle and a parent. The root filter of a device should have a
|
|
|
|
// parent == HANDLE_ROOT.
|
|
|
|
type ClassAttrs struct {
|
|
|
|
LinkIndex int
|
|
|
|
Handle uint32
|
|
|
|
Parent uint32
|
|
|
|
Leaf uint32
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q ClassAttrs) String() string {
|
|
|
|
return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Leaf: %s}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Leaf)
|
|
|
|
}
|
|
|
|
|
|
|
|
type HtbClassAttrs struct {
|
|
|
|
// TODO handle all attributes
|
|
|
|
Rate uint64
|
|
|
|
Ceil uint64
|
|
|
|
Buffer uint32
|
|
|
|
Cbuffer uint32
|
|
|
|
Quantum uint32
|
|
|
|
Level uint32
|
|
|
|
Prio uint32
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q HtbClassAttrs) String() string {
|
|
|
|
return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Htb class
|
|
|
|
type HtbClass struct {
|
|
|
|
ClassAttrs
|
2015-12-26 07:19:37 +00:00
|
|
|
Rate nl.TcRateSpec
|
|
|
|
Ceil nl.TcRateSpec
|
2015-09-10 23:20:18 +00:00
|
|
|
Buffer uint32
|
|
|
|
Cbuffer uint32
|
|
|
|
Quantum uint32
|
|
|
|
Level uint32
|
|
|
|
Prio uint32
|
2015-12-26 07:19:37 +00:00
|
|
|
Rtab [256]uint32
|
|
|
|
Ctab [256]uint32
|
2015-09-10 23:20:18 +00:00
|
|
|
}
|
|
|
|
|
2015-12-26 07:40:22 +00:00
|
|
|
func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) (*HtbClass, error) {
|
2015-12-26 07:19:37 +00:00
|
|
|
var rtab [256]uint32
|
|
|
|
var ctab [256]uint32
|
|
|
|
cell_log := -1
|
|
|
|
ccell_log := -1
|
|
|
|
linklayer := nl.LINKLAYER_ETHERNET
|
2015-09-10 23:20:18 +00:00
|
|
|
mtu := 1600
|
|
|
|
rate := cattrs.Rate / 8
|
|
|
|
ceil := cattrs.Ceil / 8
|
|
|
|
buffer := cattrs.Buffer
|
|
|
|
cbuffer := cattrs.Cbuffer
|
2015-12-26 07:19:37 +00:00
|
|
|
|
2015-09-10 23:20:18 +00:00
|
|
|
if ceil == 0 {
|
|
|
|
ceil = rate
|
|
|
|
}
|
|
|
|
|
|
|
|
if buffer == 0 {
|
|
|
|
buffer = uint32(float64(rate)/Hz() + float64(mtu))
|
|
|
|
}
|
|
|
|
buffer = uint32(Xmittime(rate, buffer))
|
|
|
|
|
|
|
|
if cbuffer == 0 {
|
|
|
|
cbuffer = uint32(float64(ceil)/Hz() + float64(mtu))
|
|
|
|
}
|
|
|
|
cbuffer = uint32(Xmittime(ceil, cbuffer))
|
|
|
|
|
2015-12-26 07:19:37 +00:00
|
|
|
tcrate := nl.TcRateSpec{Rate: uint32(rate)}
|
|
|
|
if CalcRtable(&tcrate, rtab, cell_log, uint32(mtu), linklayer) < 0 {
|
2015-12-26 07:40:22 +00:00
|
|
|
return nil, errors.New("HTB: failed to calculate rate table.")
|
2015-12-26 07:19:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tcceil := nl.TcRateSpec{Rate: uint32(ceil)}
|
|
|
|
if CalcRtable(&tcceil, ctab, ccell_log, uint32(mtu), linklayer) < 0 {
|
2015-12-26 07:40:22 +00:00
|
|
|
return nil, errors.New("HTB: failed to calculate ceil rate table.")
|
2015-12-26 07:19:37 +00:00
|
|
|
}
|
|
|
|
|
2015-09-10 23:20:18 +00:00
|
|
|
return &HtbClass{
|
|
|
|
ClassAttrs: attrs,
|
2015-12-26 07:19:37 +00:00
|
|
|
Rate: tcrate,
|
|
|
|
Ceil: tcceil,
|
2015-09-10 23:20:18 +00:00
|
|
|
Buffer: buffer,
|
|
|
|
Cbuffer: cbuffer,
|
|
|
|
Quantum: 10,
|
|
|
|
Level: 0,
|
|
|
|
Prio: 0,
|
2015-12-26 07:19:37 +00:00
|
|
|
Rtab: rtab,
|
|
|
|
Ctab: ctab,
|
2015-12-26 07:40:22 +00:00
|
|
|
}, nil
|
2015-09-10 23:20:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (q HtbClass) String() string {
|
|
|
|
return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (class *HtbClass) Attrs() *ClassAttrs {
|
|
|
|
return &class.ClassAttrs
|
|
|
|
}
|
|
|
|
|
|
|
|
func (class *HtbClass) Type() string {
|
|
|
|
return "htb"
|
|
|
|
}
|
|
|
|
|
|
|
|
// GenericClass classes represent types that are not currently understood
|
|
|
|
// by this netlink library.
|
|
|
|
type GenericClass struct {
|
|
|
|
ClassAttrs
|
|
|
|
ClassType string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (class *GenericClass) Attrs() *ClassAttrs {
|
|
|
|
return &class.ClassAttrs
|
|
|
|
}
|
|
|
|
|
|
|
|
func (class *GenericClass) Type() string {
|
|
|
|
return class.ClassType
|
|
|
|
}
|