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 }
Output:
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 }
Output:
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 }
Output:
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 }
Output:
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) }
Output:
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) } }
Output:
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) }
Output:
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) }
Output:
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 }
Output:
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) }
Output:
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) }
Output:
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()
Output:
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 }
Output:
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. |