mirror of
https://github.com/vishvananda/netlink
synced 2024-12-28 09:32:17 +00:00
Add FQ Codel
This commit is contained in:
parent
465b5fef28
commit
a2af46a09c
@ -695,3 +695,16 @@ const (
|
||||
TCA_FQ_ORPHAN_MASK // mask applied to orphaned skb hashes
|
||||
TCA_FQ_LOW_RATE_THRESHOLD // per packet delay under this rate
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_FQ_CODEL_UNSPEC = iota
|
||||
TCA_FQ_CODEL_TARGET
|
||||
TCA_FQ_CODEL_LIMIT
|
||||
TCA_FQ_CODEL_INTERVAL
|
||||
TCA_FQ_CODEL_ECN
|
||||
TCA_FQ_CODEL_FLOWS
|
||||
TCA_FQ_CODEL_QUANTUM
|
||||
TCA_FQ_CODEL_CE_THRESHOLD
|
||||
TCA_FQ_CODEL_DROP_BATCH_SIZE
|
||||
TCA_FQ_CODEL_MEMORY_LIMIT
|
||||
)
|
||||
|
27
qdisc.go
27
qdisc.go
@ -263,3 +263,30 @@ func (qdisc *Fq) Attrs() *QdiscAttrs {
|
||||
func (qdisc *Fq) Type() string {
|
||||
return "fq"
|
||||
}
|
||||
|
||||
// FQ_Codel (Fair Queuing Controlled Delay) is queuing discipline that combines Fair Queuing with the CoDel AQM scheme.
|
||||
type FqCodel struct {
|
||||
QdiscAttrs
|
||||
Target uint32
|
||||
Limit uint32
|
||||
Interval uint32
|
||||
ECN uint32
|
||||
Flows uint32
|
||||
Quantum uint32
|
||||
// There are some more attributes here, but support for them seems not ubiquitous
|
||||
}
|
||||
|
||||
func NewFqCodel(attrs QdiscAttrs) *FqCodel {
|
||||
return &FqCodel{
|
||||
QdiscAttrs: attrs,
|
||||
ECN: 1,
|
||||
}
|
||||
}
|
||||
|
||||
func (qdisc *FqCodel) Attrs() *QdiscAttrs {
|
||||
return &qdisc.QdiscAttrs
|
||||
}
|
||||
|
||||
func (qdisc *FqCodel) Type() string {
|
||||
return "fq_codel"
|
||||
}
|
||||
|
@ -232,6 +232,21 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
if qdisc.Attrs().Parent != HANDLE_INGRESS {
|
||||
return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS")
|
||||
}
|
||||
case *FqCodel:
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_ECN, nl.Uint32Attr((uint32(qdisc.ECN))))
|
||||
if qdisc.Limit > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_LIMIT, nl.Uint32Attr((uint32(qdisc.Limit))))
|
||||
}
|
||||
if qdisc.Interval > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_INTERVAL, nl.Uint32Attr((uint32(qdisc.Interval))))
|
||||
}
|
||||
if qdisc.Flows > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_FLOWS, nl.Uint32Attr((uint32(qdisc.Flows))))
|
||||
}
|
||||
if qdisc.Quantum > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
|
||||
}
|
||||
|
||||
case *Fq:
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing))))
|
||||
|
||||
@ -333,6 +348,8 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
qdisc = &Htb{}
|
||||
case "fq":
|
||||
qdisc = &Fq{}
|
||||
case "fq_codel":
|
||||
qdisc = &FqCodel{}
|
||||
case "netem":
|
||||
qdisc = &Netem{}
|
||||
default:
|
||||
@ -374,6 +391,14 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
if err := parseFqData(qdisc, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "fq_codel":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := parseFqCodelData(qdisc, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "netem":
|
||||
if err := parseNetemData(qdisc, attr.Value); err != nil {
|
||||
return nil, err
|
||||
@ -426,6 +451,29 @@ func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
native = nl.NativeEndian()
|
||||
fqCodel := qdisc.(*FqCodel)
|
||||
for _, datum := range data {
|
||||
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_FQ_CODEL_TARGET:
|
||||
fqCodel.Target = native.Uint32(datum.Value)
|
||||
case nl.TCA_FQ_CODEL_LIMIT:
|
||||
fqCodel.Limit = native.Uint32(datum.Value)
|
||||
case nl.TCA_FQ_CODEL_INTERVAL:
|
||||
fqCodel.Interval = native.Uint32(datum.Value)
|
||||
case nl.TCA_FQ_CODEL_ECN:
|
||||
fqCodel.ECN = native.Uint32(datum.Value)
|
||||
case nl.TCA_FQ_CODEL_FLOWS:
|
||||
fqCodel.Flows = native.Uint32(datum.Value)
|
||||
case nl.TCA_FQ_CODEL_QUANTUM:
|
||||
fqCodel.Quantum = native.Uint32(datum.Value)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
native = nl.NativeEndian()
|
||||
fq := qdisc.(*Fq)
|
||||
|
@ -402,3 +402,57 @@ func TestFqAddChangeDel(t *testing.T) {
|
||||
t.Fatal("Failed to remove qdisc")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFqCodelAddChangeDel(t *testing.T) {
|
||||
minKernelRequired(t, 3, 4)
|
||||
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
link, err := LinkByName("foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := LinkSetUp(link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
qdisc := &FqCodel{
|
||||
QdiscAttrs: QdiscAttrs{
|
||||
LinkIndex: link.Attrs().Index,
|
||||
Handle: MakeHandle(1, 0),
|
||||
Parent: HANDLE_ROOT,
|
||||
},
|
||||
ECN: 1,
|
||||
Quantum: 9000,
|
||||
}
|
||||
if err := QdiscAdd(qdisc); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
qdiscs, err := SafeQdiscList(link)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(qdiscs) != 1 {
|
||||
t.Fatal("Failed to add qdisc")
|
||||
}
|
||||
fqcodel, ok := qdiscs[0].(*FqCodel)
|
||||
if !ok {
|
||||
t.Fatal("Qdisc is the wrong type")
|
||||
}
|
||||
if fqcodel.Quantum != qdisc.Quantum {
|
||||
t.Fatal("Quantum does not match")
|
||||
}
|
||||
|
||||
if err := QdiscDel(qdisc); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
qdiscs, err = SafeQdiscList(link)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(qdiscs) != 0 {
|
||||
t.Fatal("Failed to remove qdisc")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user