Documentation
¶
Overview ¶
Package tc allows to show and alter traffic control settings in the Linux kernel.
Traffic control is composed of the elements shaping, scheduling, policing and dropping. This processing is controlled by qdiscs, classes and filters.
For a more detailed introduction of these elements, please have a look at http://man7.org/linux/man-pages/man8/tc.8.html.
Example (CBPF) ¶
This example demonstrate the use with classic BPF
tcIface := "ExampleClassicBPF"
rtnl, err := setupDummyInterface(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
qdisc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: core.BuildHandle(tc.HandleIngress, 0x0000),
Parent: tc.HandleIngress,
Info: 0,
},
tc.Attribute{
Kind: "clsact",
},
}
if err := tcnl.Qdisc().Add(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign clsact to %s: %v\n", tcIface, err)
return
}
// when deleting the qdisc, the applied filter will also be gone
defer tcnl.Qdisc().Delete(&qdisc)
ops := []byte{0x6, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff}
opsLen := uint16(1)
classID := uint32(0x1001)
flags := uint32(0x1)
filter := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: 0,
Parent: tc.HandleIngress,
Info: 0x300,
},
tc.Attribute{
Kind: "bpf",
BPF: &tc.Bpf{
Ops: &ops,
OpsLen: &opsLen,
ClassID: &classID,
Flags: &flags,
},
},
}
if err := tcnl.Filter().Add(&filter); err != nil {
fmt.Fprintf(os.Stderr, "could not assign cBPF: %v\n", err)
return
}
Example (EBPF) ¶
This example demonstrate how to attach an eBPF program with TC to an interface.
tcIface := "ExampleEBPF"
// For the purpose of testing a dummy network interface is set up for the example.
rtnl, err := setupDummyInterface(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
// Get the net.Interface by its name to which the tc/qdisc and tc/filter with
// the eBPF program will be attached on.
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
// As a dummy network interface was set up for this test make sure to
// remove this link again once this example finished.
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
// Open a netlink/tc connection to the Linux kernel. This connection is
// used to manage the tc/qdisc and tc/filter to which
// the eBPF program will be attached
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
// For enhanced error messages from the kernel, it is recommended to set
// option `NETLINK_EXT_ACK`, which is supported since 4.12 kernel.
//
// If not supported, `unix.ENOPROTOOPT` is returned.
if err := tcnl.SetOption(netlink.ExtendedAcknowledge, true); err != nil {
fmt.Fprintf(os.Stderr, "could not set option ExtendedAcknowledge: %v\n", err)
return
}
// Create a qdisc/clsact object that will be attached to the ingress part
// of the networking interface.
qdisc := tc.Object{
Msg: tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: core.BuildHandle(tc.HandleRoot, 0x0000),
Parent: tc.HandleIngress,
Info: 0,
},
Attribute: tc.Attribute{
Kind: "clsact",
},
}
// Attach the qdisc/clsact to the networking interface.
if err := tcnl.Qdisc().Add(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign clsact to %s: %v\n", tcIface, err)
return
}
// When deleting the qdisc, the applied filter will also be gone
defer tcnl.Qdisc().Delete(&qdisc)
// Handcraft an eBPF program of type BPF_PROG_TYPE_SCHED_CLS that will be attached to
// the networking interface via qdisc/clsact.
//
// For eBPF programs of type BPF_PROG_TYPE_SCHED_CLS the returned code defines the action that
// will be applied to the network packet. Returning 0 translates to TC_ACT_OK and will terminate
// the packet processing pipeline within netlink/tc and allows the packet to proceed.
spec := ebpf.ProgramSpec{
Name: "test",
Type: ebpf.SchedCLS,
Instructions: asm.Instructions{
// Set exit code to 0
asm.Mov.Imm(asm.R0, 0),
asm.Return(),
},
License: "GPL",
}
// Load the eBPF program into the kernel.
prog, err := ebpf.NewProgram(&spec)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load eBPF program: %v\n", err)
return
}
fd := uint32(prog.FD())
flags := uint32(0x1)
// Create a tc/filter object that will attach the eBPF program to the qdisc/clsact.
filter := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: 0,
Parent: core.BuildHandle(tc.HandleRoot, tc.HandleMinIngress),
Info: 0x300,
},
tc.Attribute{
Kind: "bpf",
BPF: &tc.Bpf{
FD: &fd,
Flags: &flags,
},
},
}
// Attach the tc/filter object with the eBPF program to the qdisc/clsact.
if err := tcnl.Filter().Add(&filter); err != nil {
fmt.Fprintf(os.Stderr, "could not attach filter for eBPF program: %v\n", err)
return
}
Index ¶
- Constants
- Variables
- type ActBpf
- type ActBpfParms
- type Action
- type Actions
- type Atm
- type AtmPvc
- type Attribute
- type Basic
- type Bpf
- type Cake
- type Cbq
- type CbqFOpt
- type CbqLssOpt
- type CbqOvl
- type CbqPolice
- type CbqWrrOpt
- type CbqXStats
- type Cbs
- type CbsOpt
- type Cgroup
- type Chain
- type Choke
- type ChokeXStats
- type Class
- type CmpMatch
- type CmpMatchAlign
- type CmpMatchFlag
- type Codel
- type CodelXStats
- type Config
- type Connmark
- type ConnmarkParam
- type ContainerMatch
- type Csum
- type CsumParms
- type Ct
- type CtParms
- type Defact
- type DefactParms
- type Drr
- type Dsmark
- type Ematch
- type EmatchHdr
- type EmatchKind
- type EmatchLayer
- type EmatchMatch
- type EmatchOpnd
- type EmatchTreeHdr
- type ErrorFunc
- type Ets
- type FifoOpt
- type Filter
- type Flow
- type Flower
- type Fq
- type FqCodel
- type FqCodelClStats
- type FqCodelQdStats
- type FqCodelXStats
- type FqPrioQopt
- type FqQdStats
- type Fw
- type Gact
- type GactParms
- type GactProb
- type Gate
- type GateParms
- type GenBasic
- type GenQueue
- type GenRateEst
- type GenRateEst64
- type GenStats
- type Hfsc
- type HfscQOpt
- type HfscXStats
- type Hhf
- type HhfXStats
- type HookFunc
- type Htb
- type HtbGlob
- type HtbOpt
- type HtbXStats
- type IPSetDir
- type IPSetMatch
- type Ife
- type IfeParms
- type Ipt
- type IptCnt
- type IptMatch
- type MPLS
- type MPLSAction
- type MPLSParam
- type Matchall
- type Mirred
- type MirredParam
- type MqPrio
- type MqPrioQopt
- type Msg
- type NByteMatch
- type Nat
- type NatParms
- type Netem
- type NetemCorr
- type NetemCorrupt
- type NetemQopt
- type NetemRate
- type NetemReorder
- type NetemSlot
- type Object
- type Pie
- type PieXStats
- type Plug
- type PlugAction
- type Police
- type Policy
- type PolicyAction
- type Prio
- type Qdisc
- type Qfq
- type RateSpec
- type Red
- type RedQOpt
- type RedXStats
- type Route4
- type Rsvp
- type RsvpGpi
- type RsvpPInfo
- type Sample
- type SampleParms
- type ServiceCurve
- type Sfb
- type SfbQopt
- type SfbXStats
- type Sfq
- type SfqQopt
- type SfqXStats
- type SizeSpec
- type SkbEdit
- type SkbEditParms
- type Stab
- type Stats
- type Stats2
- type TaPrio
- type Tbf
- type TbfQopt
- type Tc
- func (tc *Tc) Actions() *Actions
- func (tc *Tc) Chain() *Chain
- func (tc *Tc) Class() *Class
- func (tc *Tc) Close() error
- func (tc *Tc) Filter() *Filter
- func (tc *Tc) Monitor(ctx context.Context, deadline time.Duration, fn HookFunc) errordeprecated
- func (tc *Tc) MonitorWithErrorFunc(ctx context.Context, deadline time.Duration, fn HookFunc, errfn ErrorFunc) error
- func (tc *Tc) Qdisc() *Qdisc
- func (tc *Tc) SetOption(o netlink.ConnOption, enable bool) error
- type TcIndex
- type Tcft
- type TunnelKey
- type TunnelParms
- type U32
- type U32Key
- type U32Mark
- type U32Match
- type U32Sel
- type VLan
- type VLanParms
- type XStats
Examples ¶
Constants ¶
const ( EmatchLayerLink = EmatchLayer(0) EmatchLayerNetwork = EmatchLayer(1) EmatchLayerTransport = EmatchLayer(2) )
Various Ematch network layers.
const ( EmatchOpndEq = EmatchOpnd(0) EmatchOpndGt = EmatchOpnd(1) EmatchOpndLt = EmatchOpnd(2) )
Various Ematch operands
const ( EmatchContainer = EmatchKind(iota) EmatchCmp EmatchNByte EmatchU32 EmatchMeta EmatchText EmatchVLan EmatchCanID EmatchIPSet EmatchIPT )
Various Ematch kinds
const ( EmatchRelEnd uint16 = 0 EmatchRelAnd uint16 = 1 << (iota - 1) EmatchRelOr EmatchInvert EmatchSimple )
Various Ematch flags
const ( CmpMatchU8 = CmpMatchAlign(1) CmpMatchU16 = CmpMatchAlign(2) CmpMatchU32 = CmpMatchAlign(4) )
Various byte alignments.
const ( IPSetSrc = IPSetDir(1) IPSetDst = IPSetDir(2) )
Various IP packet directions.
const ( ActBind = 1 ActNoBind = 0 ActUnbind = 1 ActNoUnbind = 0 ActReplace = 1 ActNoReplace = 0 )
Various action binding types.
const ( ActOk = 0 ActReclassify = 1 ActShot = 2 ActPipe = 3 ActStolen = 4 ActQueued = 5 ActRepeat = 6 ActRedirect = 7 ActTrap = 8 )
Various action returns.
const ( MPLSActPop = MPLSAction(1) MPLSActPush = MPLSAction(2) MPLSActModify = MPLSAction(3) MPLSActDecTTL = MPLSAction(4) MPLSActMACPush = MPLSAction(5) )
Various MPLS actions
const ( HandleRoot uint32 = 0xFFFFFFFF HandleIngress uint32 = 0xFFFFFFF1 HandleMinPriority uint32 = 0xFFE0 HandleMinIngress uint32 = 0xFFF2 HandleMinEgress uint32 = 0xFFF3 // To alter filter in shared blocks, set Msg.Ifindex to MagicBlock MagicBlock = 0xFFFFFFFF )
Constants to define the direction
const ( // don't offload filter to HW SkipHw uint32 = 1 << iota // don't use filter in SW SkipSw // filter is offloaded to HW InHw // filter isn't offloaded to HW NotInHw // verbose logging Verbose )
Common flags from include/uapi/linux/pkt_cls.h
const (
BpfActDirect = 1
)
Flags defined by the kernel for the BPF filter
const (
CmpMatchTrans = CmpMatchFlag(1)
)
Various flags.
Variables ¶
var ( ErrNoArgAlter = errors.New("argument cannot be altered") ErrInvalidDev = errors.New("invalid device ID") // ErrNotImplemented is returned for not yet implemented parts. ErrNotImplemented = errors.New("functionality not yet implemented") // ErrNoArg is returned for missing arguments. ErrNoArg = errors.New("missing argument") // ErrInvalidArg is returned on invalid given arguments. ErrInvalidArg = errors.New("invalid argument") // ErrUnknownKind is returned for unknown qdisc, filter or class types. ErrUnknownKind = errors.New("unknown kind") )
Various errors
Functions ¶
This section is empty.
Types ¶
type ActBpf ¶
type ActBpf struct {
Tm *Tcft
Parms *ActBpfParms
Ops *[]byte
OpsLen *uint16
FD *uint32
Name *string
Tag *[]byte
ID *uint32
}
ActBpf represents policing attributes of various filters and classes
type ActBpfParms ¶
ActBpfParms from include/uapi/linux/tc_act/tc_bpf.h
type Action ¶
type Action struct {
Kind string
Index uint32
Stats *GenStats
Cookie *[]byte
Flags *uint64 // 32-bit bitfield value; 32-bit bitfield selector
HwStats *uint64 // 32-bit bitfield value; 32-bit bitfield selector
UsedHwStats *uint64 // 32-bit bitfield value; 32-bit bitfield selector
InHwCount *uint32
Bpf *ActBpf
ConnMark *Connmark
CSum *Csum
Ct *Ct
Defact *Defact
Gact *Gact
Gate *Gate
Ife *Ife
Ipt *Ipt
Mirred *Mirred
Nat *Nat
Sample *Sample
VLan *VLan
Police *Police
TunnelKey *TunnelKey
MPLS *MPLS
SkbEdit *SkbEdit
}
Action represents action attributes of various filters and classes
type Actions ¶
type Actions struct {
Tc
}
Actions represents the actions part of rtnetlink
Example ¶
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
// Create a gact Actions.
if err := tcnl.Actions().Add([]*tc.Action{
{
Kind: "gact",
Gact: &tc.Gact{
Parms: &tc.GactParms{
Action: 2, // drop
},
},
},
}); err != nil {
fmt.Fprintf(os.Stderr, "failed to add actions: %v\n", err)
return
}
// Delete the gact Actions on Index 1.
if err := tcnl.Actions().Delete([]*tc.Action{
{
Kind: "gact",
Index: 1,
},
}); err != nil {
fmt.Fprintf(os.Stderr, "failed to delete gact actions: %v\n", err)
return
}
type Attribute ¶
type Attribute struct {
Kind string
EgressBlock *uint32
IngressBlock *uint32
HwOffload *uint8
Chain *uint32
Stats *Stats
XStats *XStats
Stats2 *Stats2
Stab *Stab
ExtWarnMsg string
// Filters
Basic *Basic
BPF *Bpf
Cgroup *Cgroup
U32 *U32
Rsvp *Rsvp
Route4 *Route4
Fw *Fw
Flow *Flow
Flower *Flower
Matchall *Matchall
TcIndex *TcIndex
// Classless qdiscs
Cake *Cake
FqCodel *FqCodel
Codel *Codel
Fq *Fq
Pie *Pie
Hhf *Hhf
Tbf *Tbf
Sfb *Sfb
Sfq *Sfq
Red *Red
MqPrio *MqPrio
Pfifo *FifoOpt
Bfifo *FifoOpt
Choke *Choke
Netem *Netem
Plug *Plug
// Classful qdiscs
Cbs *Cbs
Htb *Htb
Hfsc *Hfsc
HfscQOpt *HfscQOpt
Dsmark *Dsmark
Drr *Drr
Cbq *Cbq
Atm *Atm
Qfq *Qfq
Prio *Prio
TaPrio *TaPrio
}
Attribute contains various elements for traffic control
type Bpf ¶
type Bpf struct {
Action *Action
Police *Police
ClassID *uint32
OpsLen *uint16
Ops *[]byte
FD *uint32
Name *string
Flags *uint32
FlagsGen *uint32
Tag *[]byte
ID *uint32
}
Bpf contains attributes of the bpf discipline
type Cake ¶
type Cake struct {
BaseRate *uint64
DiffServMode *uint32
Atm *uint32
FlowMode *uint32
Overhead *uint32
Rtt *uint32
Target *uint32
Autorate *uint32
Memory *uint32
Nat *uint32
Raw *uint32
Wash *uint32
Mpu *uint32
Ingress *uint32
AckFilter *uint32
SplitGso *uint32
FwMark *uint32
}
Cake contains attributes of the cake discipline. http://man7.org/linux/man-pages/man8/tc-cake.8.html
type Cbq ¶
type Cbq struct {
LssOpt *CbqLssOpt
WrrOpt *CbqWrrOpt
FOpt *CbqFOpt
OVLStrategy *CbqOvl
Rate *RateSpec
RTab []byte
Police *CbqPolice
}
Cbq contains attributes of the cbq discipline
type CbqLssOpt ¶
type CbqLssOpt struct {
Change byte
Flags byte
EwmaLog byte
Level byte
Maxidle uint32
Minidle uint32
OffTime uint32
Avpkt uint32
}
CbqLssOpt from include/uapi/linux/pkt_sched.h
type CbqWrrOpt ¶
type CbqWrrOpt struct {
Flags byte
Priority byte
CPriority byte
Reserved byte
Allot uint32
Weight uint32
}
CbqWrrOpt from include/uapi/linux/pkt_sched.h
type CbsOpt ¶
type CbsOpt struct {
Offload uint8
Pad [3]uint8
HiCredit int32
LoCredit int32
IdleSlope int32
SendSlope int32
}
CbsOpt contains attributes of the cbs discipline
type ChokeXStats ¶
ChokeXStats from include/uapi/linux/pkt_sched.h
type CmpMatch ¶
type CmpMatch struct {
Val uint32
Mask uint32
Off uint16
Align CmpMatchAlign
Flags CmpMatchFlag
Layer EmatchLayer
Opnd EmatchOpnd
}
CmpMatch contains attributes of the cmp match discipline
type CodelXStats ¶
type CodelXStats struct {
MaxPacket uint32
Count uint32
LastCount uint32
LDelay uint32
DropNext int32
DropOverlimit uint32
EcnMark uint32
Dropping uint32
CeMark uint32
}
CodelXStats from include/uapi/linux/pkt_sched.h
type Config ¶
type Config struct {
// NetNS defines the network namespace
NetNS int
// Interface to log internals
Logger *log.Logger
}
Config contains options for RTNETLINK
type Connmark ¶
type Connmark struct {
Parms *ConnmarkParam
Tm *Tcft
}
Connmark represents policing attributes of various filters and classes
type ConnmarkParam ¶
type ConnmarkParam struct {
Index uint32
Capab uint32
Action uint32
RefCnt uint32
BindCnt uint32
Zone uint16
}
ConnmarkParam from include/uapi/linux/tc_act/tc_connmark.h
type ContainerMatch ¶
type ContainerMatch struct {
Pos uint32
}
ContainerMatch contains attributes of the container match discipline
type CsumParms ¶
type CsumParms struct {
Index uint32
Capab uint32
Action uint32
RefCnt uint32
BindCnt uint32
UpdateFlags uint32
}
CsumParms from include/uapi/linux/tc_act/tc_csum.h
type Ct ¶
type Ct struct {
Parms *CtParms
Tm *Tcft
Action *uint16
Zone *uint16
Mark *uint32
MarkMask *uint32
NatIPv4Min *net.IP
NatIPv4Max *net.IP
NatPortMin *uint16
NatPortMax *uint16
}
Ct contains attributes of the ct discipline
type Defact ¶
type Defact struct {
Parms *DefactParms
Tm *Tcft
Data *string
}
Defact contains attributes of the defact discipline
type DefactParms ¶
DefactParms from include/uapi/linux/tc_act/tc_defact.h
type Dsmark ¶
type Dsmark struct {
Indices *uint16
DefaultIndex *uint16
SetTCIndex *bool
Mask *uint8
Value *uint8
}
Dsmark contains attributes of the dsmark discipline
type Ematch ¶
type Ematch struct {
Hdr *EmatchTreeHdr
Matches *[]EmatchMatch
}
Ematch contains attributes of the ematch discipline https://man7.org/linux/man-pages/man8/tc-ematch.8.html
type EmatchHdr ¶
type EmatchHdr struct {
MatchID uint16
Kind EmatchKind
Flags uint16
Pad uint16
}
EmatchHdr from tcf_ematch_hdr in include/uapi/linux/pkt_cls.h
type EmatchLayer ¶
type EmatchLayer uint8
EmatchLayer defines the layer the match will be applied upon.
type EmatchMatch ¶
type EmatchMatch struct {
Hdr EmatchHdr
U32Match *U32Match
CmpMatch *CmpMatch
IPSetMatch *IPSetMatch
IptMatch *IptMatch
ContainerMatch *ContainerMatch
NByteMatch *NByteMatch
}
EmatchMatch contains attributes of the ematch discipline
type EmatchTreeHdr ¶
EmatchTreeHdr from tcf_ematch_tree_hdr in include/uapi/linux/pkt_cls.h
type ErrorFunc ¶
ErrorFunc is a function that receives all errors that happen while reading from a Netlinkgroup. To stop receiving messages return something different than 0.
type Ets ¶
Ets represents a struct for Enhanced Transmission Selection, a 802.1Qaz-based Qdisc. More info at https://lwn.net/Articles/805229/
type Flow ¶
type Flow struct {
Keys *uint32
Mode *uint32
BaseClass *uint32
RShift *uint32
Addend *uint32
Mask *uint32
XOR *uint32
Divisor *uint32
PerTurb *uint32
Ematch *Ematch
Actions *[]*Action
}
Flow contains attributes of the flow discipline
type Flower ¶
type Flower struct {
ClassID *uint32
Indev *string
Actions *[]*Action
KeyEthDst *net.HardwareAddr
KeyEthDstMask *net.HardwareAddr
KeyEthSrc *net.HardwareAddr
KeyEthSrcMask *net.HardwareAddr
KeyEthType *uint16
KeyIPProto *uint8
KeyIPv4Src *net.IP
KeyIPv4SrcMask *net.IP
KeyIPv4Dst *net.IP
KeyIPv4DstMask *net.IP
KeyTCPSrc *uint16
KeyTCPDst *uint16
KeyUDPSrc *uint16
KeyUDPDst *uint16
Flags *uint32
KeyVlanID *uint16
KeyVlanPrio *uint8
KeyVlanEthType *uint16
KeyEncKeyID *uint32
KeyEncIPv4Src *net.IP
KeyEncIPv4SrcMask *net.IP
KeyEncIPv4Dst *net.IP
KeyEncIPv4DstMask *net.IP
KeyTCPSrcMask *uint16
KeyTCPDstMask *uint16
KeyUDPSrcMask *uint16
KeyUDPDstMask *uint16
KeySctpSrc *uint16
KeySctpDst *uint16
KeyEncUDPSrcPort *uint16
KeyEncUDPSrcPortMask *uint16
KeyEncUDPDstPort *uint16
KeyEncUDPDstPortMask *uint16
KeyFlags *uint32
KeyFlagsMask *uint32
KeyIcmpv4Code *uint8
KeyIcmpv4CodeMask *uint8
KeyIcmpv4Type *uint8
KeyIcmpv4TypeMask *uint8
KeyIcmpv6Code *uint8
KeyIcmpv6CodeMask *uint8
KeyArpSIP *uint32
KeyArpSIPMask *uint32
KeyArpTIP *uint32
KeyArpTIPMask *uint32
KeyArpOp *uint8
KeyArpOpMask *uint8
KeyMplsTTL *uint8
KeyMplsBos *uint8
KeyMplsTc *uint8
KeyMplsLabel *uint32
KeyTCPFlags *uint16
KeyTCPFlagsMask *uint16
KeyIPTOS *uint8
KeyIPTOSMask *uint8
KeyIPTTL *uint8
KeyIPTTLMask *uint8
KeyCVlanID *uint16
KeyCVlanPrio *uint8
KeyCVlanEthType *uint16
KeyEncIPTOS *uint8
KeyEncIPTOSMask *uint8
KeyEncIPTTL *uint8
KeyEncIPTTLMask *uint8
InHwCount *uint32
}
Flower contains attrobutes of the flower discipline
Example ¶
tcIface := "ExampleFlower"
rtnl, err := setupDummyInterface(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
qdisc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: core.BuildHandle(tc.HandleRoot, 0),
Parent: tc.HandleIngress,
Info: 0,
},
tc.Attribute{
Kind: "clsact",
},
}
if err := tcnl.Qdisc().Add(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign clsact to lo: %v\n", err)
return
}
defer func() {
if err := tcnl.Qdisc().Delete(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not delete qdisc from iface (%d): %v\n", devID.Index, err)
return
}
}()
srcMac, _ := net.ParseMAC("00:00:5e:00:53:01")
actions := []*tc.Action{
{
Kind: "gact",
Gact: &tc.Gact{
Parms: &tc.GactParms{
Action: 2, // action drop
},
},
},
}
filter := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: 0,
Parent: tc.HandleIngress + 1,
Info: 768,
},
tc.Attribute{
Kind: "flower",
Flower: &tc.Flower{
KeyEthSrc: &srcMac,
Actions: &actions,
},
},
}
// tc filter add dev ExampleFlower ingress protocol all prio 1 \
// flower src_mac 00:00:5e:00:53:01 \
// action gact drop
if err := tcnl.Filter().Add(&filter); err != nil {
fmt.Fprintf(os.Stderr, "could not assign flower filter to iface (%d): %v\n", devID.Index, err)
return
}
type Fq ¶
type Fq struct {
PLimit *uint32
FlowPLimit *uint32
Quantum *uint32
InitQuantum *uint32
RateEnable *uint32
FlowDefaultRate *uint32
FlowMaxRate *uint32
BucketsLog *uint32
FlowRefillDelay *uint32
OrphanMask *uint32
LowRateThreshold *uint32
CEThreshold *uint32
TimerSlack *uint32
Horizon *uint32
HorizonDrop *uint8
PrioMap *FqPrioQopt
Weights *[]int32
}
Fq contains attributes of the fq discipline
type FqCodel ¶
type FqCodel struct {
Target *uint32
Limit *uint32
Interval *uint32
ECN *uint32
Flows *uint32
Quantum *uint32
CEThreshold *uint32
DropBatchSize *uint32
MemoryLimit *uint32
}
FqCodel contains attributes of the fq_codel discipline
Example ¶
tcIface := "ExampleFQCodel"
rtnl, err := setupDummyInterface(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
target := uint32(0xbb8)
limit := uint32(0x7d0)
interval := uint32(0x9c40)
ecn := uint32(0x0)
qdisc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: core.BuildHandle(0x1, 0x0),
Parent: tc.HandleRoot,
Info: 0,
},
tc.Attribute{
Kind: "fq_codel",
// http://man7.org/linux/man-pages/man8/tc-fq_codel.8.html
// fq_codel limit 2000 target 3ms interval 40ms noecn
FqCodel: &tc.FqCodel{
Target: &target,
Limit: &limit,
Interval: &interval,
ECN: &ecn,
},
},
}
if err := tcnl.Qdisc().Add(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign htb to lo: %v\n", err)
return
}
defer func() {
if err := tcnl.Qdisc().Delete(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not delete htb qdisc of lo: %v\n", err)
return
}
}()
qdiscs, err := tcnl.Qdisc().Get()
if err != nil {
fmt.Fprintf(os.Stderr, "could not get all qdiscs: %v\n", err)
}
for _, qdisc := range qdiscs {
iface, err := net.InterfaceByIndex(int(qdisc.Ifindex))
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface from id %d: %v", qdisc.Ifindex, err)
return
}
fmt.Printf("%20s\t%s\n", iface.Name, qdisc.Kind)
}
type FqCodelClStats ¶
type FqCodelClStats struct {
Deficit int32
LDelay uint32
Count uint32
LastCount uint32
Dropping uint32
DropNext int32
}
FqCodelClStats from include/uapi/linux/pkt_sched.h
type FqCodelQdStats ¶
type FqCodelQdStats struct {
MaxPacket uint32
DropOverlimit uint32
EcnMark uint32
NewFlowCount uint32
NewFlowsLen uint32
OldFlowsLen uint32
CeMark uint32
MemoryUsage uint32
DropOvermemory uint32
}
FqCodelQdStats from include/uapi/linux/pkt_sched.h
type FqCodelXStats ¶
type FqCodelXStats struct {
Type uint32
Qd *FqCodelQdStats
Cl *FqCodelClStats
}
FqCodelXStats from include/uapi/linux/pkt_sched.h
type FqPrioQopt ¶
FqPrioQopt according to tc_prio_qopt in /include/uapi/linux/pkt_sched.h
type FqQdStats ¶
type FqQdStats struct {
GcFlows uint64
HighPrioPackets uint64
TCPRetrans uint64
Throttled uint64
FlowsPlimit uint64
PktsTooLong uint64
AllocationErrors uint64
TimeNextDelayedFlow int64
Flows uint32
InactiveFlows uint32
ThrottledFlows uint32
UnthrottleLatencyNs uint32
CEMark uint64
HorizonDrops uint64
HorizonCaps uint64
FastpathPackets uint64
BandDrops [3]uint64 // FQ_BANDS = 3
BandPktCount [3]uint32 // FQ_BANDS = 3
// contains filtered or unexported fields
}
FqQdStats from include/uapi/linux/pkt_sched.h
type Gate ¶
type Gate struct {
Tm *Tcft
Parms *GateParms
Priority *int32
BaseTime *uint64
CycleTime *uint64
CycleTimeExt *uint64
Flags *uint32
ClockID *int32
}
Gate contains attributes of the gate discipline https://man7.org/linux/man-pages/man8/tc-gate.8.html
type GenQueue ¶
type GenQueue struct {
QueueLen uint32
Backlog uint32
Drops uint32
Requeues uint32
Overlimits uint32
}
GenQueue from include/uapi/linux/gen_stats.h
type GenRateEst ¶
GenRateEst from include/uapi/linux/gen_stats.h
type GenRateEst64 ¶
GenRateEst64 from include/uapi/linux/gen_stats.h
type GenStats ¶
type GenStats struct {
Basic *GenBasic
RateEst *GenRateEst
Queue *GenQueue
RateEst64 *GenRateEst64
BasicHw *GenBasic
}
GenStats from include/uapi/linux/gen_stats.h
type Hfsc ¶
type Hfsc struct {
Rsc *ServiceCurve
Fsc *ServiceCurve
Usc *ServiceCurve
}
Hfsc contains attributes of the hfsc class
Example ¶
//go:build linux
// +build linux
package main
import (
"fmt"
"net"
"os"
"github.com/Atul-source/go-tc"
"github.com/Atul-source/go-tc/core"
"github.com/jsimonetti/rtnetlink"
"golang.org/x/sys/unix"
)
func addHfscClass(class *tc.Class, devID, maj, min uint32, serviceCurve *tc.ServiceCurve) (*tc.Object, error) {
hfsc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: devID,
Handle: core.BuildHandle(maj, min),
Parent: 0x10000,
Info: 0,
},
tc.Attribute{
Kind: "hfsc",
Hfsc: &tc.Hfsc{
Rsc: serviceCurve,
Fsc: serviceCurve,
Usc: serviceCurve,
},
},
}
if err := class.Add(&hfsc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign hfsc class: %v\n", err)
return nil, err
}
return &hfsc, nil
}
func main() {
var rtnl *rtnetlink.Conn
var err error
tcIface := "tcDev"
if rtnl, err = setupDummyInterface(tcIface); err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
qdisc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: 0x10000,
Parent: tc.HandleRoot,
Info: 0,
},
// tc qdisc add dev tcDev stab linklayer ethernet mtu 1500 root handle 1: hfsc default 3
// http://man7.org/linux/man-pages/man8/tc-stab.8.html
tc.Attribute{
Kind: "hfsc",
HfscQOpt: &tc.HfscQOpt{
DefCls: 3,
},
Stab: &tc.Stab{
Base: &tc.SizeSpec{
CellLog: 0,
SizeLog: 0,
CellAlign: 0,
Overhead: 0,
LinkLayer: 1,
MPU: 0,
MTU: 1500,
TSize: 0,
},
},
},
}
if err := tcnl.Qdisc().Add(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign hfsc to %s: %v\n", tcIface, err)
return
}
defer func() {
if err := tcnl.Qdisc().Delete(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not delete htb qdisc of %s: %v\n", tcIface, err)
return
}
}()
class1, err := addHfscClass(tcnl.Class(), uint32(devID.Index), 0x10000, 0x1, &tc.ServiceCurve{M2: 0x1e848})
if err != nil {
fmt.Fprintf(os.Stderr, "failed to add hfsc: %v\n", err)
return
}
defer func() {
if err := tcnl.Class().Delete(class1); err != nil {
fmt.Fprintf(os.Stderr, "could not delete hfsc class of %s: %v\n", tcIface, err)
return
}
}()
class2, err := addHfscClass(tcnl.Class(), uint32(devID.Index), 0x10000, 0x2, &tc.ServiceCurve{M2: 0x1e848})
if err != nil {
fmt.Fprintf(os.Stderr, "failed to add hfsc: %v\n", err)
return
}
defer func() {
if err := tcnl.Class().Delete(class2); err != nil {
fmt.Fprintf(os.Stderr, "could not delete hfsc class of %s: %v\n", tcIface, err)
return
}
}()
class3, err := addHfscClass(tcnl.Class(), uint32(devID.Index), 0x10000, 0x3, &tc.ServiceCurve{M2: 0x1e848})
if err != nil {
fmt.Fprintf(os.Stderr, "failed to add hfsc: %v\n", err)
return
}
defer func() {
if err := tcnl.Class().Delete(class3); err != nil {
fmt.Fprintf(os.Stderr, "could not delete hfsc class of %s: %v\n", tcIface, err)
return
}
}()
classes, err := tcnl.Class().Get(&tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
})
if err != nil {
fmt.Fprintf(os.Stderr, "could not get all classes: %v\n", err)
}
for _, class := range classes {
iface, err := net.InterfaceByIndex(int(qdisc.Ifindex))
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface from id %d: %v", qdisc.Ifindex, err)
return
}
fmt.Printf("%20s\t%s\n", iface.Name, class.Kind)
}
}
type HfscQOpt ¶
type HfscQOpt struct {
DefCls uint16
}
HfscQOpt contains attributes of the hfsc qdisc
type HfscXStats ¶
HfscXStats from include/uapi/linux/pkt_sched.h
type Hhf ¶
type Hhf struct {
BacklogLimit *uint32
Quantum *uint32
HHFlowsLimit *uint32
ResetTimeout *uint32
AdmitBytes *uint32
EVICTTimeout *uint32
NonHHWeight *uint32
}
Hhf contains attributes of the hhf discipline
type HhfXStats ¶
type HhfXStats struct {
DropOverlimit uint32
HhOverlimit uint32
HhTotCount uint32
HhCurCount uint32
}
HhfXStats from include/uapi/linux/pkt_sched.h
type HookFunc ¶
HookFunc is a function, which is called for each altered RTNETLINK Object. Return something different than 0, to stop receiving messages. action will have the value of unix.RTM_[NEW|GET|DEL][QDISC|TCLASS|FILTER].
type Htb ¶
type Htb struct {
Parms *HtbOpt
Init *HtbGlob
Ctab *[]byte
Rtab *[]byte
DirectQlen *uint32
Rate64 *uint64
Ceil64 *uint64
}
Htb contains attributes of the HTB discipline
Example ¶
tcIface := "ExampleHtb"
rtnl, err := setupDummyInterface(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
qdisc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: core.BuildHandle(0x1, 0x0),
Parent: tc.HandleRoot,
Info: 0,
},
// configure a very basic hierarchy token bucket (htb) qdisc
tc.Attribute{
Kind: "htb",
Htb: &tc.Htb{
Init: &tc.HtbGlob{
Version: 0x3,
Rate2Quantum: 0xa,
},
},
},
}
if err := tcnl.Qdisc().Add(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign htb to lo: %v\n", err)
return
}
// delete the qdisc, if this program terminates
defer func() {
if err := tcnl.Qdisc().Delete(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not delete htb qdisc of lo: %v\n", err)
return
}
}()
qdiscs, err := tcnl.Qdisc().Get()
if err != nil {
fmt.Fprintf(os.Stderr, "could not get all qdiscs: %v\n", err)
}
for _, qdisc := range qdiscs {
iface, err := net.InterfaceByIndex(int(qdisc.Ifindex))
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface from id %d: %v", qdisc.Ifindex, err)
return
}
fmt.Printf("%20s\t%s\n", iface.Name, qdisc.Kind)
}
type HtbGlob ¶
type HtbGlob struct {
Version uint32
Rate2Quantum uint32
Defcls uint32
Debug uint32
DirectPkts uint32
}
HtbGlob from include/uapi/linux/pkt_sched.h
type HtbOpt ¶
type HtbOpt struct {
Rate RateSpec
Ceil RateSpec
Buffer uint32
Cbuffer uint32
Quantum uint32
Level uint32
Prio uint32
}
HtbOpt from include/uapi/linux/pkt_sched.h
type IPSetMatch ¶
IPSetMatch contains attributes of the ipset match discipline
type Ife ¶
type Ife struct {
Parms *IfeParms
SMac *net.HardwareAddr
DMac *net.HardwareAddr
Type *uint16
Tm *Tcft
}
Ife contains attribute of the ife discipline
type IfeParms ¶
type IfeParms struct {
Index uint32
Capab uint32
Action uint32
RefCnt uint32
BindCnt uint32
Flags uint16
}
IfeParms from include/uapi/linux/tc_act/tc_ife.h
type IptMatch ¶
type IptMatch struct {
Hook *uint32
MatchName *string
Revision *uint8
NFProto *uint8
MatchData *[]byte
}
IptMatch contains attributes of the ipt match discipline
type MPLS ¶
type MPLS struct {
Parms *MPLSParam
Tm *Tcft
Proto *int16
Label *uint32
TC *uint8
TTL *uint8
BOS *uint8
}
MPLS contains attributes of the mpls discipline https://man7.org/linux/man-pages/man8/tc-mpls.8.html
type MPLSParam ¶
type MPLSParam struct {
Index uint32
Capab uint32
Action uint32
RefCnt uint32
BindCnt uint32
MAction MPLSAction
}
MPLSParam contains further MPLS attributes.
type Mirred ¶
type Mirred struct {
Parms *MirredParam
Tm *Tcft
}
Mirred represents policing attributes of various filters and classes
type MirredParam ¶
type MirredParam struct {
Index uint32
Capab uint32
Action uint32
RefCnt uint32
BindCnt uint32
Eaction uint32
IfIndex uint32
}
MirredParam from include/uapi/linux/tc_act/tc_mirred.h
type MqPrio ¶
type MqPrio struct {
Opt *MqPrioQopt
Mode *uint16
Shaper *uint16
MinRate64 *uint64
MaxRate64 *uint64
}
MqPrio contains attributes of the mqprio discipline
type MqPrioQopt ¶
type MqPrioQopt struct {
NumTc uint8
PrioTcMap [16]uint8 // TC_QOPT_BITMASK + 1 = 16
Hw uint8
Count [16]uint16 // TC_QOPT_MAX_QUEUE = 16
Offset [16]uint16 // TC_QOPT_MAX_QUEUE = 16
}
MqPrioQopt according to tc_mqprio_qopt in /include/uapi/linux/pkt_sched.h
type NByteMatch ¶
NByteMatch contains attributes of the Nbyte match discipline
type NatParms ¶
type NatParms struct {
Index uint32
Capab uint32
Action uint32
RefCnt uint32
BindCnt uint32
OldAddr uint32
NewAddr uint32
Mask uint32
Flags uint32
}
NatParms from include/uapi/linux/tc_act/tc_nat.h
type Netem ¶
type Netem struct {
Qopt NetemQopt
Corr *NetemCorr
DelayDist *[]int16
Reorder *NetemReorder
Corrupt *NetemCorrupt
Rate *NetemRate
Ecn *uint32
Rate64 *uint64
Latency64 *int64
Jitter64 *int64
Slot *NetemSlot
}
Netem contains attributes of the netem discipline
Example ¶
tcIface := "ExampleNetem"
rtnl, err := setupDummyInterface(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
var ecn uint32 = 1
qdisc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: core.BuildHandle(0x1, 0x0),
Parent: tc.HandleRoot,
Info: 0,
},
tc.Attribute{
Kind: "netem",
// tc qdisc replace dev tcDev root netem loss 1% ecn
Netem: &tc.Netem{
Qopt: tc.NetemQopt{
Limit: 1000,
Loss: 42949673,
},
Ecn: &ecn,
},
},
}
if err := tcnl.Qdisc().Replace(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign qdisc netem to lo: %v\n", err)
return
}
defer func() {
if err := tcnl.Qdisc().Delete(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not delete netem qdisc of lo: %v\n", err)
return
}
}()
qdiscs, err := tcnl.Qdisc().Get()
if err != nil {
fmt.Fprintf(os.Stderr, "could not get all qdiscs: %v\n", err)
}
for _, qdisc := range qdiscs {
iface, err := net.InterfaceByIndex(int(qdisc.Ifindex))
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface from id %d: %v", qdisc.Ifindex, err)
return
}
fmt.Printf("%20s\t%s\n", iface.Name, qdisc.Kind)
}
type NetemCorrupt ¶
NetemCorrupt from include/uapi/linux/pkt_sched.h
type NetemQopt ¶
type NetemQopt struct {
Latency uint32
Limit uint32
Loss uint32
Gap uint32
Duplicate uint32
Jitter uint32
}
NetemQopt from include/uapi/linux/pkt_sched.h
type NetemReorder ¶
NetemReorder from include/uapi/linux/pkt_sched.h
type NetemSlot ¶
type NetemSlot struct {
MinDelay int64
MaxDelay int64
MaxPackets int32
MaxBytes int32
DistDelay int64
DistJitter int64
}
NetemSlot from include/uapi/linux/pkt_sched.h
type Pie ¶
type Pie struct {
Target *uint32
Limit *uint32
TUpdate *uint32
Alpha *uint32
Beta *uint32
ECN *uint32
Bytemode *uint32
}
Pie contains attributes of the pie discipline
type PieXStats ¶
type PieXStats struct {
Prob uint64
Delay uint32
AvgDqRate uint32
PacketsIn uint32
Dropped uint32
Overlimit uint32
Maxq uint32
EcnMark uint32
}
PieXStats from include/uapi/linux/pkt_sched.h
type Plug ¶
type Plug struct {
Action PlugAction
Limit uint32
}
Plug contains attributes of the plug discipline
type PlugAction ¶
type PlugAction int32
PlugAction defines actions for plug.
const ( PlugBuffer PlugAction = iota PlugReleaseOne PlugReleaseIndefinite PlugLimit )
Various Plug actions.
type Police ¶
type Police struct {
Tbf *Policy
Rate *RateSpec
PeakRate *RateSpec
AvRate *uint32
Result *uint32
Tm *Tcft
Rate64 *uint64
PeakRate64 *uint64
}
Police represents policing attributes of various filters and classes
type Policy ¶
type Policy struct {
Index uint32
Action PolicyAction
Limit uint32
Burst uint32
Mtu uint32
Rate RateSpec
PeakRate RateSpec
RefCnt uint32
BindCnt uint32
Capab uint32
}
Policy from include/uapi/linux/pkt_sched.h
type PolicyAction ¶
type PolicyAction uint32
PolicyAction defines the action that is applied by Policy.
const ( PolicyOk PolicyAction = iota PolicyReclassify PolicyShot PolicyPipe )
Default Policy actions. PolicyUnspec - skipped as it is -1
type Qdisc ¶
type Qdisc struct {
Tc
}
Qdisc represents the queueing discipline part of traffic control
Example ¶
This example demonstraces how to add a qdisc to an interface and delete it again
tcIface := "ExampleQdisc"
rtnl, err := setupDummyInterface(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
// open a rtnetlink socket
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := rtnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
qdisc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: core.BuildHandle(0xFFFF, 0x0000),
Parent: 0xFFFFFFF1,
Info: 0,
},
tc.Attribute{
Kind: "clsact",
},
}
if err := tcnl.Qdisc().Add(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign clsact to %s: %v\n", tcIface, err)
return
}
if err := tcnl.Qdisc().Delete(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not delete clsact qdisc from %s: %v\n", tcIface, err)
return
}
func (*Qdisc) Get ¶
Get fetches all queueing disciplines
Example ¶
This example demonstrate how Get() can get used to read information
// open a rtnetlink socket
rtnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := rtnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
qdiscs, err := rtnl.Qdisc().Get()
if err != nil {
fmt.Fprintf(os.Stderr, "could not get qdiscs: %v\n", err)
return
}
for _, qdisc := range qdiscs {
iface, err := net.InterfaceByIndex(int(qdisc.Ifindex))
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface from id %d: %v", qdisc.Ifindex, err)
return
}
fmt.Printf("%20s\t%s\n", iface.Name, qdisc.Kind)
}
type RateSpec ¶
type RateSpec struct {
CellLog uint8
Linklayer uint8
Overhead uint16
CellAlign uint16
Mpu uint16
Rate uint32
}
RateSpec from include/uapi/linux/pkt_sched.h
type RedQOpt ¶
type RedQOpt struct {
Limit uint32
QthMin uint32
QthMax uint32
Wlog byte
Plog byte
ScellLog byte
Flags byte
}
RedQOpt from include/uapi/linux/pkt_sched.h
type Rsvp ¶
type Rsvp struct {
ClassID *uint32
Dst *[]byte
Src *[]byte
PInfo *RsvpPInfo
Police *Police
Actions *[]*Action
}
Rsvp contains attributes of the rsvp discipline
type RsvpPInfo ¶
type RsvpPInfo struct {
Dpi RsvpGpi
Spi RsvpGpi
Protocol uint8
TunnelID uint8
TunnelHdr uint8
Pad uint8
}
RsvpPInfo from include/uapi/linux/pkt_sched.h
type Sample ¶
type Sample struct {
Parms *SampleParms
Tm *Tcft
Rate *uint32
TruncSize *uint32
SampleGroup *uint32
}
Sample contains attribute of the Sample discipline
type SampleParms ¶
SampleParms from include/uapi/linux/tc_act/tc_sample.h
type ServiceCurve ¶
ServiceCurve from include/uapi/linux/pkt_sched.h
type SfbQopt ¶
type SfbQopt struct {
RehashInterval uint32 // in ms
WarmupTime uint32 // in ms
Max uint32
BinSize uint32
Increment uint32
Decrement uint32
Limit uint32
PenaltyRate uint32
PenaltyBurst uint32
}
SfbQopt from include/uapi/linux/pkt_sched.h
type SfbXStats ¶
type SfbXStats struct {
EarlyDrop uint32
PenaltyDrop uint32
BucketDrop uint32
QueueDrop uint32
ChildDrop uint32
Marked uint32
MaxQlen uint32
MaxProb uint32
AvgProb uint32
}
SfbXStats from include/uapi/linux/pkt_sched.h
type Sfq ¶
type Sfq struct {
V0 SfqQopt
Depth uint32 /* max number of packets per flow */
Headdrop uint32
/* SFQRED parameters */
Limit uint32 /* HARD maximal flow queue length (bytes) */
QthMin uint32 /* Min average length threshold (bytes) */
QthMax uint32 /* Max average length threshold (bytes) */
Wlog uint8 /* log(W) */
Plog uint8 /* log(P_max/(qth_max-qth_min)) */
ScellLog uint8 /* cell size for idle damping */
Flags uint8
MaxP uint32 /* probability, high resolution */
}
Sfq contains attributes of the SFQ discipline https://man7.org/linux/man-pages/man8/sfq.8.html
type SfqQopt ¶
type SfqQopt struct {
Quantum uint32 /* Bytes per round allocated to flow */
PerturbPeriod int32 /* Period of hash perturbation */
Limit uint32 /* Maximal packets in queue */
Divisor uint32 /* Hash divisor */
Flows uint32 /* Maximal number of flows */
}
SfqQopt contains SFQ attributes
type SfqXStats ¶
type SfqXStats struct {
Allot int32
}
SfqXStats from include/uapi/linux/pkt_sched.h
type SizeSpec ¶
type SizeSpec struct {
CellLog uint8
SizeLog uint8
CellAlign int16
Overhead int32
LinkLayer uint32
MPU uint32
MTU uint32
TSize uint32
}
SizeSpec implements tc_sizespec
type SkbEdit ¶
type SkbEdit struct {
Tm *Tcft
Parms *SkbEditParms
Priority *uint32
QueueMapping *uint16
Mark *uint32
Ptype *uint16
Mask *uint32
Flags *uint64
QueueMappingMax *uint16
}
SkbEdit contains attribute of the SkbEdit discipline
type SkbEditParms ¶
SkbEditParms from include/uapi/linux/tc_act/tc_skbedit.h
type Stab ¶
Stab contains attributes of a stab http://man7.org/linux/man-pages/man8/tc-stab.8.html
type Stats ¶
type Stats struct {
Bytes uint64 /* Number of enqueued bytes */
Packets uint32 /* Number of enqueued packets */
Drops uint32 /* Packets dropped because of lack of resources */
Overlimits uint32 /* Number of throttle events when this
* flow goes out of allocated bandwidth */
Bps uint32 /* Current flow byte rate */
Pps uint32 /* Current flow packet rate */
Qlen uint32
Backlog uint32
}
Stats from include/uapi/linux/pkt_sched.h
type Stats2 ¶
type Stats2 struct {
// gnet_stats_basic
Bytes uint64
Packets uint32
// gnet_stats_queue
Qlen uint32
Backlog uint32
Drops uint32
Requeues uint32
Overlimits uint32
}
Stats2 from include/uapi/linux/pkt_sched.h
type TaPrio ¶
type TaPrio struct {
PrioMap *MqPrioQopt
SchedBaseTime *int64
SchedClockID *int32
SchedCycleTime *int64
SchedCycleTimeExtension *int64
Flags *uint32
TxTimeDelay *uint32
}
TaPrio contains TaPrio attributes
type Tbf ¶
Tbf contains attributes of the TBF discipline
Example ¶
tcIface := "tcExampleTbf"
rtnl, err := setupDummyInterface(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
linklayerEthernet := uint8(1)
burst := uint32(0x500000)
qdisc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: core.BuildHandle(tc.HandleRoot, 0x0),
Parent: tc.HandleRoot,
Info: 0,
},
tc.Attribute{
Kind: "tbf",
Tbf: &tc.Tbf{
Parms: &tc.TbfQopt{
Mtu: 1514,
Limit: 0x5000,
Rate: tc.RateSpec{
Rate: 0x7d00,
Linklayer: linklayerEthernet,
CellLog: 0x3,
},
},
Burst: &burst,
},
},
}
// tc qdisc add dev tcExampleTbf root tbf burst 20480 limit 20480 mtu 1514 rate 32000bps
if err := tcnl.Qdisc().Add(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign tbf to %s: %v\n", tcIface, err)
return
}
defer func() {
if err := tcnl.Qdisc().Delete(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not delete tbf qdisc of %s: %v\n", tcIface, err)
return
}
}()
qdiscs, err := tcnl.Qdisc().Get()
if err != nil {
fmt.Fprintf(os.Stderr, "could not get all qdiscs: %v\n", err)
// return
}
fmt.Println("## qdiscs:")
for _, qdisc := range qdiscs {
iface, err := net.InterfaceByIndex(int(qdisc.Ifindex))
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface from id %d: %v", qdisc.Ifindex, err)
return
}
fmt.Printf("%20s\t%-11s\n", iface.Name, qdisc.Kind)
}
type Tc ¶
type Tc struct {
// contains filtered or unexported fields
}
Tc represents a RTNETLINK wrapper
func (*Tc) Monitor
deprecated
Monitor NETLINK_ROUTE messages
Deprecated: Use MonitorWithErrorFunc() instead.
Example ¶
This example demonstrates how Monitor() can be used
tcSocket, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Printf("could not open socket for TC: %v", err)
return
}
defer func() {
if err := tcSocket.Close(); err != nil {
fmt.Printf("coult not close TC socket: %v", err)
return
}
}()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Hook function mon, which is called every time,
// something is received by the kernel on this socket
mon := func(action uint16, m tc.Object) int {
fmt.Printf("Action:\t%d\nObject: \t%#v\n", action, m)
return 0
}
tcSocket.Monitor(ctx, 10*time.Millisecond, mon)
<-ctx.Done()
type TcIndex ¶
type TcIndex struct {
Hash *uint32
Mask *uint16
Shift *uint32
FallThrough *uint32
ClassID *uint32
Actions *[]*Action
}
TcIndex contains attributes of the tcIndex discipline
type TunnelKey ¶
type TunnelKey struct {
Parms *TunnelParms
Tm *Tcft
KeyEncSrc *net.IP
KeyEncDst *net.IP
KeyEncKeyID *uint32
KeyEncDstPort *uint16
KeyNoCSUM *uint8
KeyEncTOS *uint8
KeyEncTTL *uint8
}
TunnelKey contains attribute of the TunnelKey discipline
type TunnelParms ¶
type TunnelParms struct {
Index uint32
Capab uint32
Action uint32
RefCnt uint32
BindCnt uint32
TunnelKeyAction uint32
}
TunnelParms from include/uapi/linux/tc_act/tc_tunnel_key.h
type U32 ¶
type U32 struct {
ClassID *uint32
Hash *uint32
Link *uint32
Divisor *uint32
Sel *U32Sel
InDev *string
Pcnt *uint64
Mark *U32Mark
Flags *uint32
Police *Police
Actions *[]*Action
}
U32 contains attributes of the u32 discipline
Example ¶
// example from http://man7.org/linux/man-pages/man8/tc-police.8.html
tcIface := "ExampleU32"
rtnl, err := setupDummyInterface(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not setup dummy interface: %v\n", err)
return
}
defer rtnl.Close()
devID, err := net.InterfaceByName(tcIface)
if err != nil {
fmt.Fprintf(os.Stderr, "could not get interface ID: %v\n", err)
return
}
defer func(devID uint32, rtnl *rtnetlink.Conn) {
if err := rtnl.Link.Delete(devID); err != nil {
fmt.Fprintf(os.Stderr, "could not delete interface: %v\n", err)
}
}(uint32(devID.Index), rtnl)
tcnl, err, _ := tc.Open(&tc.Config{})
if err != nil {
fmt.Fprintf(os.Stderr, "could not open rtnetlink socket: %v\n", err)
return
}
defer func() {
if err := tcnl.Close(); err != nil {
fmt.Fprintf(os.Stderr, "could not close rtnetlink socket: %v\n", err)
}
}()
qdisc := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: 0,
Parent: 0xFFFF0000,
Info: 768,
},
tc.Attribute{
Kind: "u32",
U32: &tc.U32{
Sel: &tc.U32Sel{
Flags: 0x1,
NKeys: 0x3,
Keys: []tc.U32Key{
// match ip protocol 6 0xff
{Mask: 0xff0000, Val: 0x60000, Off: 0x800, OffMask: 0x0},
{Mask: 0xff000f00, Val: 0x5c0, Off: 0x0, OffMask: 0x0},
{Mask: 0xff0000, Val: 0x100000, Off: 0x2000, OffMask: 0x0},
},
},
Police: &tc.Police{
Tbf: &tc.Policy{
Action: 0x1,
Burst: 0xc35000,
Rate: tc.RateSpec{
CellLog: 0x3,
Linklayer: 0x1,
CellAlign: 0xffff,
Rate: 0x1e848,
},
},
},
},
},
}
if err := tcnl.Qdisc().Add(&qdisc); err != nil {
fmt.Fprintf(os.Stderr, "could not assign clsact to %s: %v\n", tcIface, err)
return
}
// when deleting the qdisc, the applied filter will also be gone
defer tcnl.Qdisc().Delete(&qdisc)
ops := []byte{0x6, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff}
opsLen := uint16(1)
classID := uint32(0x1001)
flags := uint32(0x1)
filter := tc.Object{
tc.Msg{
Family: unix.AF_UNSPEC,
Ifindex: uint32(devID.Index),
Handle: 0,
Parent: tc.HandleIngress,
Info: 0x300,
},
tc.Attribute{
Kind: "bpf",
BPF: &tc.Bpf{
Ops: &ops,
OpsLen: &opsLen,
ClassID: &classID,
Flags: &flags,
},
},
}
if err := tcnl.Filter().Add(&filter); err != nil {
fmt.Fprintf(os.Stderr, "could not assign cBPF: %v\n", err)
return
}
type U32Match ¶
type U32Match struct {
Mask uint32 // big endian
Value uint32 // big endian
Off int32
OffMask uint32
}
U32Match contains attributes of the u32 match discipline
type U32Sel ¶
type U32Sel struct {
Flags uint8
Offshift uint8
NKeys uint8
OffMask uint16
Off uint16
Offoff uint16
Hoff uint16
Hmask uint32
Keys []U32Key
}
U32Sel from include/uapi/linux/pkt_sched.h
type VLan ¶
type VLan struct {
Parms *VLanParms
Tm *Tcft
PushID *uint16
PushProtocol *uint16
PushPriority *uint32
}
VLan contains attribute of the VLan discipline
type VLanParms ¶
type VLanParms struct {
Index uint32
Capab uint32
Action uint32
RefCnt uint32
BindCnt uint32
VLanAction uint32
}
VLanParms from include/uapi/linux/tc_act/tc_vlan.h
type XStats ¶
type XStats struct {
Sfb *SfbXStats
Sfq *SfqXStats
Red *RedXStats
Choke *ChokeXStats
Htb *HtbXStats
Cbq *CbqXStats
Codel *CodelXStats
Hhf *HhfXStats
Pie *PieXStats
FqCodel *FqCodelXStats
Fq *FqQdStats
Hfsc *HfscXStats
}
XStats contains further statistics to the TCA_KIND
Source Files
¶
- actions.go
- attributeTcMsg.go
- chain.go
- class.go
- converter.go
- doc.go
- ematch.go
- ematch_cmp.go
- ematch_container.go
- ematch_ipset.go
- ematch_ipt.go
- ematch_nbyte.go
- ematch_u32.go
- errors.go
- f_basic.go
- f_bpf.go
- f_cgroup.go
- f_flow.go
- f_flower.go
- f_fw.go
- f_matchall.go
- f_route4.go
- f_rsvp.go
- f_tcindex.go
- f_u32.go
- filter.go
- helper.go
- m_action.go
- m_bpf.go
- m_connmark.go
- m_csum.go
- m_ct.go
- m_defact.go
- m_gact.go
- m_gate.go
- m_ife.go
- m_ipt.go
- m_mirred.go
- m_mpls.go
- m_nat.go
- m_police.go
- m_sample.go
- m_skbedit.go
- m_tunnel_key.go
- m_vlan.go
- nest.go
- q_atm.go
- q_cake.go
- q_cbq.go
- q_cbs.go
- q_choke.go
- q_codel.go
- q_drr.go
- q_dsmark.go
- q_ets.go
- q_fq.go
- q_fqCodel.go
- q_hfsc.go
- q_hhf.go
- q_htb.go
- q_mqPrio.go
- q_netem.go
- q_pie.go
- q_plug.go
- q_prio.go
- q_qfq.go
- q_red.go
- q_sfb.go
- q_sfq.go
- q_taprio.go
- q_tbf.go
- qdisc.go
- ratetable.go
- stab.go
- stats.go
- structs.go
- tc.go
- tc_gteq_1.16.go
- types.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package core contains some generic helper functions for the package github.com/Atul-source/go-tc.
|
Package core contains some generic helper functions for the package github.com/Atul-source/go-tc. |
|
internal
|
|
|
unix
Package unix contains some constants, that are needed to use github.com/Atul-source/go-tc.
|
Package unix contains some constants, that are needed to use github.com/Atul-source/go-tc. |