1package netlink 2 3import ( 4 "fmt" 5) 6 7const ( 8 HANDLE_NONE = 0 9 HANDLE_INGRESS = 0xFFFFFFF1 10 HANDLE_ROOT = 0xFFFFFFFF 11 PRIORITY_MAP_LEN = 16 12) 13 14type Qdisc interface { 15 Attrs() *QdiscAttrs 16 Type() string 17} 18 19// Qdisc represents a netlink qdisc. A qdisc is associated with a link, 20// has a handle, a parent and a refcnt. The root qdisc of a device should 21// have parent == HANDLE_ROOT. 22type QdiscAttrs struct { 23 LinkIndex int 24 Handle uint32 25 Parent uint32 26 Refcnt uint32 // read only 27} 28 29func (q QdiscAttrs) String() string { 30 return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Refcnt: %s}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Refcnt) 31} 32 33func MakeHandle(major, minor uint16) uint32 { 34 return (uint32(major) << 16) | uint32(minor) 35} 36 37func MajorMinor(handle uint32) (uint16, uint16) { 38 return uint16((handle & 0xFFFF0000) >> 16), uint16(handle & 0x0000FFFFF) 39} 40 41func HandleStr(handle uint32) string { 42 switch handle { 43 case HANDLE_NONE: 44 return "none" 45 case HANDLE_INGRESS: 46 return "ingress" 47 case HANDLE_ROOT: 48 return "root" 49 default: 50 major, minor := MajorMinor(handle) 51 return fmt.Sprintf("%x:%x", major, minor) 52 } 53} 54 55// PfifoFast is the default qdisc created by the kernel if one has not 56// been defined for the interface 57type PfifoFast struct { 58 QdiscAttrs 59 Bands uint8 60 PriorityMap [PRIORITY_MAP_LEN]uint8 61} 62 63func (qdisc *PfifoFast) Attrs() *QdiscAttrs { 64 return &qdisc.QdiscAttrs 65} 66 67func (qdisc *PfifoFast) Type() string { 68 return "pfifo_fast" 69} 70 71// Prio is a basic qdisc that works just like PfifoFast 72type Prio struct { 73 QdiscAttrs 74 Bands uint8 75 PriorityMap [PRIORITY_MAP_LEN]uint8 76} 77 78func NewPrio(attrs QdiscAttrs) *Prio { 79 return &Prio{ 80 QdiscAttrs: attrs, 81 Bands: 3, 82 PriorityMap: [PRIORITY_MAP_LEN]uint8{1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, 83 } 84} 85 86func (qdisc *Prio) Attrs() *QdiscAttrs { 87 return &qdisc.QdiscAttrs 88} 89 90func (qdisc *Prio) Type() string { 91 return "prio" 92} 93 94// Tbf is a classful qdisc that rate limits based on tokens 95type Tbf struct { 96 QdiscAttrs 97 // TODO: handle 64bit rate properly 98 Rate uint64 99 Limit uint32 100 Buffer uint32 101 // TODO: handle other settings 102} 103 104func (qdisc *Tbf) Attrs() *QdiscAttrs { 105 return &qdisc.QdiscAttrs 106} 107 108func (qdisc *Tbf) Type() string { 109 return "tbf" 110} 111 112// Ingress is a qdisc for adding ingress filters 113type Ingress struct { 114 QdiscAttrs 115} 116 117func (qdisc *Ingress) Attrs() *QdiscAttrs { 118 return &qdisc.QdiscAttrs 119} 120 121func (qdisc *Ingress) Type() string { 122 return "ingress" 123} 124 125// GenericQdisc qdiscs represent types that are not currently understood 126// by this netlink library. 127type GenericQdisc struct { 128 QdiscAttrs 129 QdiscType string 130} 131 132func (qdisc *GenericQdisc) Attrs() *QdiscAttrs { 133 return &qdisc.QdiscAttrs 134} 135 136func (qdisc *GenericQdisc) Type() string { 137 return qdisc.QdiscType 138} 139