netlink/nl/tc_linux.go

1591 lines
33 KiB
Go

package nl
import (
"bytes"
"encoding/binary"
"fmt"
"net"
"unsafe"
"golang.org/x/sys/unix"
)
// LinkLayer
const (
LINKLAYER_UNSPEC = iota
LINKLAYER_ETHERNET
LINKLAYER_ATM
)
// ATM
const (
ATM_CELL_PAYLOAD = 48
ATM_CELL_SIZE = 53
)
const TC_LINKLAYER_MASK = 0x0F
// Police
const (
TCA_POLICE_UNSPEC = iota
TCA_POLICE_TBF
TCA_POLICE_RATE
TCA_POLICE_PEAKRATE
TCA_POLICE_AVRATE
TCA_POLICE_RESULT
TCA_POLICE_MAX = TCA_POLICE_RESULT
)
// Message types
const (
TCA_UNSPEC = iota
TCA_KIND
TCA_OPTIONS
TCA_STATS
TCA_XSTATS
TCA_RATE
TCA_FCNT
TCA_STATS2
TCA_STAB
TCA_PAD
TCA_DUMP_INVISIBLE
TCA_CHAIN
TCA_HW_OFFLOAD
TCA_INGRESS_BLOCK
TCA_EGRESS_BLOCK
TCA_DUMP_FLAGS
TCA_MAX = TCA_DUMP_FLAGS
)
const (
TCA_ACT_TAB = 1
TCAA_MAX = 1
)
const (
TCA_ACT_UNSPEC = iota
TCA_ACT_KIND
TCA_ACT_OPTIONS
TCA_ACT_INDEX
TCA_ACT_STATS
TCA_ACT_PAD
TCA_ACT_COOKIE
TCA_ACT_FLAGS
TCA_ACT_HW_STATS
TCA_ACT_USED_HW_STATS
TCA_ACT_IN_HW_COUNT
TCA_ACT_MAX
)
const (
TCA_PRIO_UNSPEC = iota
TCA_PRIO_MQ
TCA_PRIO_MAX = TCA_PRIO_MQ
)
const (
TCA_STATS_UNSPEC = iota
TCA_STATS_BASIC
TCA_STATS_RATE_EST
TCA_STATS_QUEUE
TCA_STATS_APP
TCA_STATS_RATE_EST64
TCA_STATS_PAD
TCA_STATS_BASIC_HW
TCA_STATS_PKT64
TCA_STATS_MAX = TCA_STATS_PKT64
)
const (
SizeofTcMsg = 0x14
SizeofTcActionMsg = 0x04
SizeofTcPrioMap = 0x14
SizeofTcRateSpec = 0x0c
SizeofTcNetemQopt = 0x18
SizeofTcNetemCorr = 0x0c
SizeofTcNetemReorder = 0x08
SizeofTcNetemCorrupt = 0x08
SizeofTcTbfQopt = 2*SizeofTcRateSpec + 0x0c
SizeofTcHtbCopt = 2*SizeofTcRateSpec + 0x14
SizeofTcHtbGlob = 0x14
SizeofTcU32Key = 0x10
SizeofTcU32Sel = 0x10 // without keys
SizeofTcGen = 0x16
SizeofTcConnmark = SizeofTcGen + 0x04
SizeofTcCsum = SizeofTcGen + 0x04
SizeofTcMirred = SizeofTcGen + 0x08
SizeofTcTunnelKey = SizeofTcGen + 0x04
SizeofTcSkbEdit = SizeofTcGen
SizeofTcPolice = 2*SizeofTcRateSpec + 0x20
SizeofTcSfqQopt = 0x0b
SizeofTcSfqRedStats = 0x18
SizeofTcSfqQoptV1 = SizeofTcSfqQopt + SizeofTcSfqRedStats + 0x1c
SizeofUint32Bitfield = 0x8
)
// struct tcmsg {
// unsigned char tcm_family;
// unsigned char tcm__pad1;
// unsigned short tcm__pad2;
// int tcm_ifindex;
// __u32 tcm_handle;
// __u32 tcm_parent;
// __u32 tcm_info;
// };
type TcMsg struct {
Family uint8
Pad [3]byte
Ifindex int32
Handle uint32
Parent uint32
Info uint32
}
func (msg *TcMsg) Len() int {
return SizeofTcMsg
}
func DeserializeTcMsg(b []byte) *TcMsg {
return (*TcMsg)(unsafe.Pointer(&b[0:SizeofTcMsg][0]))
}
func (x *TcMsg) Serialize() []byte {
return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:]
}
type Tcf struct {
Install uint64
LastUse uint64
Expires uint64
FirstUse uint64
}
func DeserializeTcf(b []byte) *Tcf {
const size = int(unsafe.Sizeof(Tcf{}))
return (*Tcf)(unsafe.Pointer(&b[0:size][0]))
}
// struct tcamsg {
// unsigned char tca_family;
// unsigned char tca__pad1;
// unsigned short tca__pad2;
// };
type TcActionMsg struct {
Family uint8
Pad [3]byte
}
func (msg *TcActionMsg) Len() int {
return SizeofTcActionMsg
}
func DeserializeTcActionMsg(b []byte) *TcActionMsg {
return (*TcActionMsg)(unsafe.Pointer(&b[0:SizeofTcActionMsg][0]))
}
func (x *TcActionMsg) Serialize() []byte {
return (*(*[SizeofTcActionMsg]byte)(unsafe.Pointer(x)))[:]
}
const (
TC_PRIO_MAX = 15
)
// struct tc_prio_qopt {
// int bands; /* Number of bands */
// __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
// };
type TcPrioMap struct {
Bands int32
Priomap [TC_PRIO_MAX + 1]uint8
}
func (msg *TcPrioMap) Len() int {
return SizeofTcPrioMap
}
func DeserializeTcPrioMap(b []byte) *TcPrioMap {
return (*TcPrioMap)(unsafe.Pointer(&b[0:SizeofTcPrioMap][0]))
}
func (x *TcPrioMap) Serialize() []byte {
return (*(*[SizeofTcPrioMap]byte)(unsafe.Pointer(x)))[:]
}
const (
TCA_TBF_UNSPEC = iota
TCA_TBF_PARMS
TCA_TBF_RTAB
TCA_TBF_PTAB
TCA_TBF_RATE64
TCA_TBF_PRATE64
TCA_TBF_BURST
TCA_TBF_PBURST
TCA_TBF_MAX = TCA_TBF_PBURST
)
// struct tc_ratespec {
// unsigned char cell_log;
// __u8 linklayer; /* lower 4 bits */
// unsigned short overhead;
// short cell_align;
// unsigned short mpu;
// __u32 rate;
// };
type TcRateSpec struct {
CellLog uint8
Linklayer uint8
Overhead uint16
CellAlign int16
Mpu uint16
Rate uint32
}
func (msg *TcRateSpec) Len() int {
return SizeofTcRateSpec
}
func DeserializeTcRateSpec(b []byte) *TcRateSpec {
return (*TcRateSpec)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0]))
}
func (x *TcRateSpec) Serialize() []byte {
return (*(*[SizeofTcRateSpec]byte)(unsafe.Pointer(x)))[:]
}
/**
* NETEM
*/
const (
TCA_NETEM_UNSPEC = iota
TCA_NETEM_CORR
TCA_NETEM_DELAY_DIST
TCA_NETEM_REORDER
TCA_NETEM_CORRUPT
TCA_NETEM_LOSS
TCA_NETEM_RATE
TCA_NETEM_ECN
TCA_NETEM_RATE64
TCA_NETEM_MAX = TCA_NETEM_RATE64
)
// struct tc_netem_qopt {
// __u32 latency; /* added delay (us) */
// __u32 limit; /* fifo limit (packets) */
// __u32 loss; /* random packet loss (0=none ~0=100%) */
// __u32 gap; /* re-ordering gap (0 for none) */
// __u32 duplicate; /* random packet dup (0=none ~0=100%) */
// __u32 jitter; /* random jitter in latency (us) */
// };
type TcNetemQopt struct {
Latency uint32
Limit uint32
Loss uint32
Gap uint32
Duplicate uint32
Jitter uint32
}
func (msg *TcNetemQopt) Len() int {
return SizeofTcNetemQopt
}
func DeserializeTcNetemQopt(b []byte) *TcNetemQopt {
return (*TcNetemQopt)(unsafe.Pointer(&b[0:SizeofTcNetemQopt][0]))
}
func (x *TcNetemQopt) Serialize() []byte {
return (*(*[SizeofTcNetemQopt]byte)(unsafe.Pointer(x)))[:]
}
// struct tc_netem_corr {
// __u32 delay_corr; /* delay correlation */
// __u32 loss_corr; /* packet loss correlation */
// __u32 dup_corr; /* duplicate correlation */
// };
type TcNetemCorr struct {
DelayCorr uint32
LossCorr uint32
DupCorr uint32
}
func (msg *TcNetemCorr) Len() int {
return SizeofTcNetemCorr
}
func DeserializeTcNetemCorr(b []byte) *TcNetemCorr {
return (*TcNetemCorr)(unsafe.Pointer(&b[0:SizeofTcNetemCorr][0]))
}
func (x *TcNetemCorr) Serialize() []byte {
return (*(*[SizeofTcNetemCorr]byte)(unsafe.Pointer(x)))[:]
}
// struct tc_netem_reorder {
// __u32 probability;
// __u32 correlation;
// };
type TcNetemReorder struct {
Probability uint32
Correlation uint32
}
func (msg *TcNetemReorder) Len() int {
return SizeofTcNetemReorder
}
func DeserializeTcNetemReorder(b []byte) *TcNetemReorder {
return (*TcNetemReorder)(unsafe.Pointer(&b[0:SizeofTcNetemReorder][0]))
}
func (x *TcNetemReorder) Serialize() []byte {
return (*(*[SizeofTcNetemReorder]byte)(unsafe.Pointer(x)))[:]
}
// struct tc_netem_corrupt {
// __u32 probability;
// __u32 correlation;
// };
type TcNetemCorrupt struct {
Probability uint32
Correlation uint32
}
func (msg *TcNetemCorrupt) Len() int {
return SizeofTcNetemCorrupt
}
func DeserializeTcNetemCorrupt(b []byte) *TcNetemCorrupt {
return (*TcNetemCorrupt)(unsafe.Pointer(&b[0:SizeofTcNetemCorrupt][0]))
}
func (x *TcNetemCorrupt) Serialize() []byte {
return (*(*[SizeofTcNetemCorrupt]byte)(unsafe.Pointer(x)))[:]
}
// struct tc_tbf_qopt {
// struct tc_ratespec rate;
// struct tc_ratespec peakrate;
// __u32 limit;
// __u32 buffer;
// __u32 mtu;
// };
type TcTbfQopt struct {
Rate TcRateSpec
Peakrate TcRateSpec
Limit uint32
Buffer uint32
Mtu uint32
}
func (msg *TcTbfQopt) Len() int {
return SizeofTcTbfQopt
}
func DeserializeTcTbfQopt(b []byte) *TcTbfQopt {
return (*TcTbfQopt)(unsafe.Pointer(&b[0:SizeofTcTbfQopt][0]))
}
func (x *TcTbfQopt) Serialize() []byte {
return (*(*[SizeofTcTbfQopt]byte)(unsafe.Pointer(x)))[:]
}
const (
TCA_HTB_UNSPEC = iota
TCA_HTB_PARMS
TCA_HTB_INIT
TCA_HTB_CTAB
TCA_HTB_RTAB
TCA_HTB_DIRECT_QLEN
TCA_HTB_RATE64
TCA_HTB_CEIL64
TCA_HTB_MAX = TCA_HTB_CEIL64
)
//struct tc_htb_opt {
// struct tc_ratespec rate;
// struct tc_ratespec ceil;
// __u32 buffer;
// __u32 cbuffer;
// __u32 quantum;
// __u32 level; /* out only */
// __u32 prio;
//};
type TcHtbCopt struct {
Rate TcRateSpec
Ceil TcRateSpec
Buffer uint32
Cbuffer uint32
Quantum uint32
Level uint32
Prio uint32
}
func (msg *TcHtbCopt) Len() int {
return SizeofTcHtbCopt
}
func DeserializeTcHtbCopt(b []byte) *TcHtbCopt {
return (*TcHtbCopt)(unsafe.Pointer(&b[0:SizeofTcHtbCopt][0]))
}
func (x *TcHtbCopt) Serialize() []byte {
return (*(*[SizeofTcHtbCopt]byte)(unsafe.Pointer(x)))[:]
}
type TcHtbGlob struct {
Version uint32
Rate2Quantum uint32
Defcls uint32
Debug uint32
DirectPkts uint32
}
func (msg *TcHtbGlob) Len() int {
return SizeofTcHtbGlob
}
func DeserializeTcHtbGlob(b []byte) *TcHtbGlob {
return (*TcHtbGlob)(unsafe.Pointer(&b[0:SizeofTcHtbGlob][0]))
}
func (x *TcHtbGlob) Serialize() []byte {
return (*(*[SizeofTcHtbGlob]byte)(unsafe.Pointer(x)))[:]
}
// HFSC
type Curve struct {
m1 uint32
d uint32
m2 uint32
}
type HfscCopt struct {
Rsc Curve
Fsc Curve
Usc Curve
}
func (c *Curve) Attrs() (uint32, uint32, uint32) {
return c.m1, c.d, c.m2
}
func (c *Curve) Set(m1 uint32, d uint32, m2 uint32) {
c.m1 = m1
c.d = d
c.m2 = m2
}
func DeserializeHfscCurve(b []byte) *Curve {
return &Curve{
m1: binary.LittleEndian.Uint32(b[0:4]),
d: binary.LittleEndian.Uint32(b[4:8]),
m2: binary.LittleEndian.Uint32(b[8:12]),
}
}
func SerializeHfscCurve(c *Curve) (b []byte) {
t := make([]byte, binary.MaxVarintLen32)
binary.LittleEndian.PutUint32(t, c.m1)
b = append(b, t[:4]...)
binary.LittleEndian.PutUint32(t, c.d)
b = append(b, t[:4]...)
binary.LittleEndian.PutUint32(t, c.m2)
b = append(b, t[:4]...)
return b
}
type TcHfscOpt struct {
Defcls uint16
}
func (x *TcHfscOpt) Serialize() []byte {
return (*(*[2]byte)(unsafe.Pointer(x)))[:]
}
const (
TCA_U32_UNSPEC = iota
TCA_U32_CLASSID
TCA_U32_HASH
TCA_U32_LINK
TCA_U32_DIVISOR
TCA_U32_SEL
TCA_U32_POLICE
TCA_U32_ACT
TCA_U32_INDEV
TCA_U32_PCNT
TCA_U32_MARK
TCA_U32_MAX = TCA_U32_MARK
)
// struct tc_u32_key {
// __be32 mask;
// __be32 val;
// int off;
// int offmask;
// };
type TcU32Key struct {
Mask uint32 // big endian
Val uint32 // big endian
Off int32
OffMask int32
}
func (msg *TcU32Key) Len() int {
return SizeofTcU32Key
}
func DeserializeTcU32Key(b []byte) *TcU32Key {
return (*TcU32Key)(unsafe.Pointer(&b[0:SizeofTcU32Key][0]))
}
func (x *TcU32Key) Serialize() []byte {
return (*(*[SizeofTcU32Key]byte)(unsafe.Pointer(x)))[:]
}
// struct tc_u32_sel {
// unsigned char flags;
// unsigned char offshift;
// unsigned char nkeys;
//
// __be16 offmask;
// __u16 off;
// short offoff;
//
// short hoff;
// __be32 hmask;
// struct tc_u32_key keys[0];
// };
const (
TC_U32_TERMINAL = 1 << iota
TC_U32_OFFSET = 1 << iota
TC_U32_VAROFFSET = 1 << iota
TC_U32_EAT = 1 << iota
)
type TcU32Sel struct {
Flags uint8
Offshift uint8
Nkeys uint8
Pad uint8
Offmask uint16 // big endian
Off uint16
Offoff int16
Hoff int16
Hmask uint32 // big endian
Keys []TcU32Key
}
func (msg *TcU32Sel) Len() int {
return SizeofTcU32Sel + int(msg.Nkeys)*SizeofTcU32Key
}
func DeserializeTcU32Sel(b []byte) *TcU32Sel {
x := &TcU32Sel{}
copy((*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:], b)
next := SizeofTcU32Sel
var i uint8
for i = 0; i < x.Nkeys; i++ {
x.Keys = append(x.Keys, *DeserializeTcU32Key(b[next:]))
next += SizeofTcU32Key
}
return x
}
func (x *TcU32Sel) Serialize() []byte {
// This can't just unsafe.cast because it must iterate through keys.
buf := make([]byte, x.Len())
copy(buf, (*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:])
next := SizeofTcU32Sel
for _, key := range x.Keys {
keyBuf := key.Serialize()
copy(buf[next:], keyBuf)
next += SizeofTcU32Key
}
return buf
}
type TcGen struct {
Index uint32
Capab uint32
Action int32
Refcnt int32
Bindcnt int32
}
func (msg *TcGen) Len() int {
return SizeofTcGen
}
func DeserializeTcGen(b []byte) *TcGen {
return (*TcGen)(unsafe.Pointer(&b[0:SizeofTcGen][0]))
}
func (x *TcGen) Serialize() []byte {
return (*(*[SizeofTcGen]byte)(unsafe.Pointer(x)))[:]
}
// #define tc_gen \
// __u32 index; \
// __u32 capab; \
// int action; \
// int refcnt; \
// int bindcnt
const (
TCA_ACT_GACT = 5
)
const (
TCA_GACT_UNSPEC = iota
TCA_GACT_TM
TCA_GACT_PARMS
TCA_GACT_PROB
TCA_GACT_MAX = TCA_GACT_PROB
)
type TcGact TcGen
const (
TCA_ACT_BPF = 13
)
const (
TCA_ACT_BPF_UNSPEC = iota
TCA_ACT_BPF_TM
TCA_ACT_BPF_PARMS
TCA_ACT_BPF_OPS_LEN
TCA_ACT_BPF_OPS
TCA_ACT_BPF_FD
TCA_ACT_BPF_NAME
TCA_ACT_BPF_MAX = TCA_ACT_BPF_NAME
)
const (
TCA_BPF_FLAG_ACT_DIRECT uint32 = 1 << iota
)
const (
TCA_BPF_UNSPEC = iota
TCA_BPF_ACT
TCA_BPF_POLICE
TCA_BPF_CLASSID
TCA_BPF_OPS_LEN
TCA_BPF_OPS
TCA_BPF_FD
TCA_BPF_NAME
TCA_BPF_FLAGS
TCA_BPF_FLAGS_GEN
TCA_BPF_TAG
TCA_BPF_ID
TCA_BPF_MAX = TCA_BPF_ID
)
type TcBpf TcGen
const (
TCA_ACT_CONNMARK = 14
)
const (
TCA_CONNMARK_UNSPEC = iota
TCA_CONNMARK_PARMS
TCA_CONNMARK_TM
TCA_CONNMARK_MAX = TCA_CONNMARK_TM
)
// struct tc_connmark {
// tc_gen;
// __u16 zone;
// };
type TcConnmark struct {
TcGen
Zone uint16
}
func (msg *TcConnmark) Len() int {
return SizeofTcConnmark
}
func DeserializeTcConnmark(b []byte) *TcConnmark {
return (*TcConnmark)(unsafe.Pointer(&b[0:SizeofTcConnmark][0]))
}
func (x *TcConnmark) Serialize() []byte {
return (*(*[SizeofTcConnmark]byte)(unsafe.Pointer(x)))[:]
}
const (
TCA_CSUM_UNSPEC = iota
TCA_CSUM_PARMS
TCA_CSUM_TM
TCA_CSUM_PAD
TCA_CSUM_MAX = TCA_CSUM_PAD
)
// struct tc_csum {
// tc_gen;
// __u32 update_flags;
// }
type TcCsum struct {
TcGen
UpdateFlags uint32
}
func (msg *TcCsum) Len() int {
return SizeofTcCsum
}
func DeserializeTcCsum(b []byte) *TcCsum {
return (*TcCsum)(unsafe.Pointer(&b[0:SizeofTcCsum][0]))
}
func (x *TcCsum) Serialize() []byte {
return (*(*[SizeofTcCsum]byte)(unsafe.Pointer(x)))[:]
}
const (
TCA_ACT_MIRRED = 8
)
const (
TCA_MIRRED_UNSPEC = iota
TCA_MIRRED_TM
TCA_MIRRED_PARMS
TCA_MIRRED_MAX = TCA_MIRRED_PARMS
)
// struct tc_mirred {
// tc_gen;
// int eaction; /* one of IN/EGRESS_MIRROR/REDIR */
// __u32 ifindex; /* ifindex of egress port */
// };
type TcMirred struct {
TcGen
Eaction int32
Ifindex uint32
}
func (msg *TcMirred) Len() int {
return SizeofTcMirred
}
func DeserializeTcMirred(b []byte) *TcMirred {
return (*TcMirred)(unsafe.Pointer(&b[0:SizeofTcMirred][0]))
}
func (x *TcMirred) Serialize() []byte {
return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:]
}
const (
TCA_TUNNEL_KEY_UNSPEC = iota
TCA_TUNNEL_KEY_TM
TCA_TUNNEL_KEY_PARMS
TCA_TUNNEL_KEY_ENC_IPV4_SRC
TCA_TUNNEL_KEY_ENC_IPV4_DST
TCA_TUNNEL_KEY_ENC_IPV6_SRC
TCA_TUNNEL_KEY_ENC_IPV6_DST
TCA_TUNNEL_KEY_ENC_KEY_ID
TCA_TUNNEL_KEY_PAD
TCA_TUNNEL_KEY_ENC_DST_PORT
TCA_TUNNEL_KEY_NO_CSUM
TCA_TUNNEL_KEY_ENC_OPTS
TCA_TUNNEL_KEY_ENC_TOS
TCA_TUNNEL_KEY_ENC_TTL
TCA_TUNNEL_KEY_MAX
)
type TcTunnelKey struct {
TcGen
Action int32
}
func (x *TcTunnelKey) Len() int {
return SizeofTcTunnelKey
}
func DeserializeTunnelKey(b []byte) *TcTunnelKey {
return (*TcTunnelKey)(unsafe.Pointer(&b[0:SizeofTcTunnelKey][0]))
}
func (x *TcTunnelKey) Serialize() []byte {
return (*(*[SizeofTcTunnelKey]byte)(unsafe.Pointer(x)))[:]
}
const (
TCA_SKBEDIT_UNSPEC = iota
TCA_SKBEDIT_TM
TCA_SKBEDIT_PARMS
TCA_SKBEDIT_PRIORITY
TCA_SKBEDIT_QUEUE_MAPPING
TCA_SKBEDIT_MARK
TCA_SKBEDIT_PAD
TCA_SKBEDIT_PTYPE
TCA_SKBEDIT_MASK
TCA_SKBEDIT_MAX
)
type TcSkbEdit struct {
TcGen
}
func (x *TcSkbEdit) Len() int {
return SizeofTcSkbEdit
}
func DeserializeSkbEdit(b []byte) *TcSkbEdit {
return (*TcSkbEdit)(unsafe.Pointer(&b[0:SizeofTcSkbEdit][0]))
}
func (x *TcSkbEdit) Serialize() []byte {
return (*(*[SizeofTcSkbEdit]byte)(unsafe.Pointer(x)))[:]
}
// struct tc_police {
// __u32 index;
// int action;
// __u32 limit;
// __u32 burst;
// __u32 mtu;
// struct tc_ratespec rate;
// struct tc_ratespec peakrate;
// int refcnt;
// int bindcnt;
// __u32 capab;
// };
type TcPolice struct {
Index uint32
Action int32
Limit uint32
Burst uint32
Mtu uint32
Rate TcRateSpec
PeakRate TcRateSpec
Refcnt int32
Bindcnt int32
Capab uint32
}
func (msg *TcPolice) Len() int {
return SizeofTcPolice
}
func DeserializeTcPolice(b []byte) *TcPolice {
return (*TcPolice)(unsafe.Pointer(&b[0:SizeofTcPolice][0]))
}
func (x *TcPolice) Serialize() []byte {
return (*(*[SizeofTcPolice]byte)(unsafe.Pointer(x)))[:]
}
const (
TCA_FW_UNSPEC = iota
TCA_FW_CLASSID
TCA_FW_POLICE
TCA_FW_INDEV
TCA_FW_ACT
TCA_FW_MASK
TCA_FW_MAX = TCA_FW_MASK
)
const (
TCA_MATCHALL_UNSPEC = iota
TCA_MATCHALL_CLASSID
TCA_MATCHALL_ACT
TCA_MATCHALL_FLAGS
)
const (
TCA_FQ_UNSPEC = iota
TCA_FQ_PLIMIT // limit of total number of packets in queue
TCA_FQ_FLOW_PLIMIT // limit of packets per flow
TCA_FQ_QUANTUM // RR quantum
TCA_FQ_INITIAL_QUANTUM // RR quantum for new flow
TCA_FQ_RATE_ENABLE // enable/disable rate limiting
TCA_FQ_FLOW_DEFAULT_RATE // obsolete do not use
TCA_FQ_FLOW_MAX_RATE // per flow max rate
TCA_FQ_BUCKETS_LOG // log2(number of buckets)
TCA_FQ_FLOW_REFILL_DELAY // flow credit refill delay in usec
TCA_FQ_ORPHAN_MASK // mask applied to orphaned skb hashes
TCA_FQ_LOW_RATE_THRESHOLD // per packet delay under this rate
TCA_FQ_CE_THRESHOLD // DCTCP-like CE-marking threshold
TCA_FQ_TIMER_SLACK // timer slack
TCA_FQ_HORIZON // time horizon in us
TCA_FQ_HORIZON_DROP // drop packets beyond horizon, or cap their EDT
)
const (
TCA_FQ_CODEL_UNSPEC = iota
TCA_FQ_CODEL_TARGET
TCA_FQ_CODEL_LIMIT
TCA_FQ_CODEL_INTERVAL
TCA_FQ_CODEL_ECN
TCA_FQ_CODEL_FLOWS
TCA_FQ_CODEL_QUANTUM
TCA_FQ_CODEL_CE_THRESHOLD
TCA_FQ_CODEL_DROP_BATCH_SIZE
TCA_FQ_CODEL_MEMORY_LIMIT
)
const (
TCA_HFSC_UNSPEC = iota
TCA_HFSC_RSC
TCA_HFSC_FSC
TCA_HFSC_USC
)
const (
TCA_FLOWER_UNSPEC = iota
TCA_FLOWER_CLASSID
TCA_FLOWER_INDEV
TCA_FLOWER_ACT
TCA_FLOWER_KEY_ETH_DST /* ETH_ALEN */
TCA_FLOWER_KEY_ETH_DST_MASK /* ETH_ALEN */
TCA_FLOWER_KEY_ETH_SRC /* ETH_ALEN */
TCA_FLOWER_KEY_ETH_SRC_MASK /* ETH_ALEN */
TCA_FLOWER_KEY_ETH_TYPE /* be16 */
TCA_FLOWER_KEY_IP_PROTO /* u8 */
TCA_FLOWER_KEY_IPV4_SRC /* be32 */
TCA_FLOWER_KEY_IPV4_SRC_MASK /* be32 */
TCA_FLOWER_KEY_IPV4_DST /* be32 */
TCA_FLOWER_KEY_IPV4_DST_MASK /* be32 */
TCA_FLOWER_KEY_IPV6_SRC /* struct in6_addr */
TCA_FLOWER_KEY_IPV6_SRC_MASK /* struct in6_addr */
TCA_FLOWER_KEY_IPV6_DST /* struct in6_addr */
TCA_FLOWER_KEY_IPV6_DST_MASK /* struct in6_addr */
TCA_FLOWER_KEY_TCP_SRC /* be16 */
TCA_FLOWER_KEY_TCP_DST /* be16 */
TCA_FLOWER_KEY_UDP_SRC /* be16 */
TCA_FLOWER_KEY_UDP_DST /* be16 */
TCA_FLOWER_FLAGS
TCA_FLOWER_KEY_VLAN_ID /* be16 */
TCA_FLOWER_KEY_VLAN_PRIO /* u8 */
TCA_FLOWER_KEY_VLAN_ETH_TYPE /* be16 */
TCA_FLOWER_KEY_ENC_KEY_ID /* be32 */
TCA_FLOWER_KEY_ENC_IPV4_SRC /* be32 */
TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK /* be32 */
TCA_FLOWER_KEY_ENC_IPV4_DST /* be32 */
TCA_FLOWER_KEY_ENC_IPV4_DST_MASK /* be32 */
TCA_FLOWER_KEY_ENC_IPV6_SRC /* struct in6_addr */
TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK /* struct in6_addr */
TCA_FLOWER_KEY_ENC_IPV6_DST /* struct in6_addr */
TCA_FLOWER_KEY_ENC_IPV6_DST_MASK /* struct in6_addr */
TCA_FLOWER_KEY_TCP_SRC_MASK /* be16 */
TCA_FLOWER_KEY_TCP_DST_MASK /* be16 */
TCA_FLOWER_KEY_UDP_SRC_MASK /* be16 */
TCA_FLOWER_KEY_UDP_DST_MASK /* be16 */
TCA_FLOWER_KEY_SCTP_SRC_MASK /* be16 */
TCA_FLOWER_KEY_SCTP_DST_MASK /* be16 */
TCA_FLOWER_KEY_SCTP_SRC /* be16 */
TCA_FLOWER_KEY_SCTP_DST /* be16 */
TCA_FLOWER_KEY_ENC_UDP_SRC_PORT /* be16 */
TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK /* be16 */
TCA_FLOWER_KEY_ENC_UDP_DST_PORT /* be16 */
TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK /* be16 */
TCA_FLOWER_KEY_FLAGS /* be32 */
TCA_FLOWER_KEY_FLAGS_MASK /* be32 */
TCA_FLOWER_KEY_ICMPV4_CODE /* u8 */
TCA_FLOWER_KEY_ICMPV4_CODE_MASK /* u8 */
TCA_FLOWER_KEY_ICMPV4_TYPE /* u8 */
TCA_FLOWER_KEY_ICMPV4_TYPE_MASK /* u8 */
TCA_FLOWER_KEY_ICMPV6_CODE /* u8 */
TCA_FLOWER_KEY_ICMPV6_CODE_MASK /* u8 */
TCA_FLOWER_KEY_ICMPV6_TYPE /* u8 */
TCA_FLOWER_KEY_ICMPV6_TYPE_MASK /* u8 */
TCA_FLOWER_KEY_ARP_SIP /* be32 */
TCA_FLOWER_KEY_ARP_SIP_MASK /* be32 */
TCA_FLOWER_KEY_ARP_TIP /* be32 */
TCA_FLOWER_KEY_ARP_TIP_MASK /* be32 */
TCA_FLOWER_KEY_ARP_OP /* u8 */
TCA_FLOWER_KEY_ARP_OP_MASK /* u8 */
TCA_FLOWER_KEY_ARP_SHA /* ETH_ALEN */
TCA_FLOWER_KEY_ARP_SHA_MASK /* ETH_ALEN */
TCA_FLOWER_KEY_ARP_THA /* ETH_ALEN */
TCA_FLOWER_KEY_ARP_THA_MASK /* ETH_ALEN */
TCA_FLOWER_KEY_MPLS_TTL /* u8 - 8 bits */
TCA_FLOWER_KEY_MPLS_BOS /* u8 - 1 bit */
TCA_FLOWER_KEY_MPLS_TC /* u8 - 3 bits */
TCA_FLOWER_KEY_MPLS_LABEL /* be32 - 20 bits */
TCA_FLOWER_KEY_TCP_FLAGS /* be16 */
TCA_FLOWER_KEY_TCP_FLAGS_MASK /* be16 */
TCA_FLOWER_KEY_IP_TOS /* u8 */
TCA_FLOWER_KEY_IP_TOS_MASK /* u8 */
TCA_FLOWER_KEY_IP_TTL /* u8 */
TCA_FLOWER_KEY_IP_TTL_MASK /* u8 */
TCA_FLOWER_KEY_CVLAN_ID /* be16 */
TCA_FLOWER_KEY_CVLAN_PRIO /* u8 */
TCA_FLOWER_KEY_CVLAN_ETH_TYPE /* be16 */
TCA_FLOWER_KEY_ENC_IP_TOS /* u8 */
TCA_FLOWER_KEY_ENC_IP_TOS_MASK /* u8 */
TCA_FLOWER_KEY_ENC_IP_TTL /* u8 */
TCA_FLOWER_KEY_ENC_IP_TTL_MASK /* u8 */
TCA_FLOWER_KEY_ENC_OPTS
TCA_FLOWER_KEY_ENC_OPTS_MASK
__TCA_FLOWER_MAX
)
const TCA_CLS_FLAGS_SKIP_HW = 1 << 0 /* don't offload filter to HW */
const TCA_CLS_FLAGS_SKIP_SW = 1 << 1 /* don't use filter in SW */
// struct tc_sfq_qopt {
// unsigned quantum; /* Bytes per round allocated to flow */
// int perturb_period; /* Period of hash perturbation */
// __u32 limit; /* Maximal packets in queue */
// unsigned divisor; /* Hash divisor */
// unsigned flows; /* Maximal number of flows */
// };
type TcSfqQopt struct {
Quantum uint8
Perturb int32
Limit uint32
Divisor uint8
Flows uint8
}
func (x *TcSfqQopt) Len() int {
return SizeofTcSfqQopt
}
func DeserializeTcSfqQopt(b []byte) *TcSfqQopt {
return (*TcSfqQopt)(unsafe.Pointer(&b[0:SizeofTcSfqQopt][0]))
}
func (x *TcSfqQopt) Serialize() []byte {
return (*(*[SizeofTcSfqQopt]byte)(unsafe.Pointer(x)))[:]
}
// struct tc_sfqred_stats {
// __u32 prob_drop; /* Early drops, below max threshold */
// __u32 forced_drop; /* Early drops, after max threshold */
// __u32 prob_mark; /* Marked packets, below max threshold */
// __u32 forced_mark; /* Marked packets, after max threshold */
// __u32 prob_mark_head; /* Marked packets, below max threshold */
// __u32 forced_mark_head;/* Marked packets, after max threshold */
// };
type TcSfqRedStats struct {
ProbDrop uint32
ForcedDrop uint32
ProbMark uint32
ForcedMark uint32
ProbMarkHead uint32
ForcedMarkHead uint32
}
func (x *TcSfqRedStats) Len() int {
return SizeofTcSfqRedStats
}
func DeserializeTcSfqRedStats(b []byte) *TcSfqRedStats {
return (*TcSfqRedStats)(unsafe.Pointer(&b[0:SizeofTcSfqRedStats][0]))
}
func (x *TcSfqRedStats) Serialize() []byte {
return (*(*[SizeofTcSfqRedStats]byte)(unsafe.Pointer(x)))[:]
}
// struct tc_sfq_qopt_v1 {
// struct tc_sfq_qopt v0;
// unsigned int depth; /* max number of packets per flow */
// unsigned int headdrop;
//
// /* SFQRED parameters */
//
// __u32 limit; /* HARD maximal flow queue length (bytes) */
// __u32 qth_min; /* Min average length threshold (bytes) */
// __u32 qth_max; /* Max average length threshold (bytes) */
// unsigned char Wlog; /* log(W) */
// unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */
// unsigned char Scell_log; /* cell size for idle damping */
// unsigned char flags;
// __u32 max_P; /* probability, high resolution */
//
// /* SFQRED stats */
//
// struct tc_sfqred_stats stats;
// };
type TcSfqQoptV1 struct {
TcSfqQopt
Depth uint32
HeadDrop uint32
Limit uint32
QthMin uint32
QthMax uint32
Wlog byte
Plog byte
ScellLog byte
Flags byte
MaxP uint32
TcSfqRedStats
}
func (x *TcSfqQoptV1) Len() int {
return SizeofTcSfqQoptV1
}
func DeserializeTcSfqQoptV1(b []byte) *TcSfqQoptV1 {
return (*TcSfqQoptV1)(unsafe.Pointer(&b[0:SizeofTcSfqQoptV1][0]))
}
func (x *TcSfqQoptV1) Serialize() []byte {
return (*(*[SizeofTcSfqQoptV1]byte)(unsafe.Pointer(x)))[:]
}
// IPProto represents Flower ip_proto attribute
type IPProto uint8
const (
IPPROTO_TCP IPProto = unix.IPPROTO_TCP
IPPROTO_UDP IPProto = unix.IPPROTO_UDP
IPPROTO_SCTP IPProto = unix.IPPROTO_SCTP
IPPROTO_ICMP IPProto = unix.IPPROTO_ICMP
IPPROTO_ICMPV6 IPProto = unix.IPPROTO_ICMPV6
)
func (i IPProto) Serialize() []byte {
arr := make([]byte, 1)
arr[0] = byte(i)
return arr
}
func (i IPProto) String() string {
switch i {
case IPPROTO_TCP:
return "tcp"
case IPPROTO_UDP:
return "udp"
case IPPROTO_SCTP:
return "sctp"
case IPPROTO_ICMP:
return "icmp"
case IPPROTO_ICMPV6:
return "icmpv6"
}
return fmt.Sprintf("%d", i)
}
const (
MaxOffs = 128
SizeOfPeditSel = 24
SizeOfPeditKey = 24
TCA_PEDIT_KEY_EX_HTYPE = 1
TCA_PEDIT_KEY_EX_CMD = 2
)
const (
TCA_PEDIT_UNSPEC = iota
TCA_PEDIT_TM
TCA_PEDIT_PARMS
TCA_PEDIT_PAD
TCA_PEDIT_PARMS_EX
TCA_PEDIT_KEYS_EX
TCA_PEDIT_KEY_EX
)
// /* TCA_PEDIT_KEY_EX_HDR_TYPE_NETWROK is a special case for legacy users. It
// * means no specific header type - offset is relative to the network layer
// */
type PeditHeaderType uint16
const (
TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK = iota
TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
__PEDIT_HDR_TYPE_MAX
)
type PeditCmd uint16
const (
TCA_PEDIT_KEY_EX_CMD_SET = 0
TCA_PEDIT_KEY_EX_CMD_ADD = 1
)
type TcPeditSel struct {
TcGen
NKeys uint8
Flags uint8
}
func DeserializeTcPeditKey(b []byte) *TcPeditKey {
return (*TcPeditKey)(unsafe.Pointer(&b[0:SizeOfPeditKey][0]))
}
func DeserializeTcPedit(b []byte) (*TcPeditSel, []TcPeditKey) {
x := &TcPeditSel{}
copy((*(*[SizeOfPeditSel]byte)(unsafe.Pointer(x)))[:SizeOfPeditSel], b)
var keys []TcPeditKey
next := SizeOfPeditKey
var i uint8
for i = 0; i < x.NKeys; i++ {
keys = append(keys, *DeserializeTcPeditKey(b[next:]))
next += SizeOfPeditKey
}
return x, keys
}
type TcPeditKey struct {
Mask uint32
Val uint32
Off uint32
At uint32
OffMask uint32
Shift uint32
}
type TcPeditKeyEx struct {
HeaderType PeditHeaderType
Cmd PeditCmd
}
type TcPedit struct {
Sel TcPeditSel
Keys []TcPeditKey
KeysEx []TcPeditKeyEx
Extend uint8
}
func (p *TcPedit) Encode(parent *RtAttr) {
parent.AddRtAttr(TCA_ACT_KIND, ZeroTerminated("pedit"))
actOpts := parent.AddRtAttr(TCA_ACT_OPTIONS, nil)
bbuf := bytes.NewBuffer(make([]byte, 0, int(unsafe.Sizeof(p.Sel)+unsafe.Sizeof(p.Keys))))
bbuf.Write((*(*[SizeOfPeditSel]byte)(unsafe.Pointer(&p.Sel)))[:])
for i := uint8(0); i < p.Sel.NKeys; i++ {
bbuf.Write((*(*[SizeOfPeditKey]byte)(unsafe.Pointer(&p.Keys[i])))[:])
}
actOpts.AddRtAttr(TCA_PEDIT_PARMS_EX, bbuf.Bytes())
exAttrs := actOpts.AddRtAttr(int(TCA_PEDIT_KEYS_EX|NLA_F_NESTED), nil)
for i := uint8(0); i < p.Sel.NKeys; i++ {
keyAttr := exAttrs.AddRtAttr(int(TCA_PEDIT_KEY_EX|NLA_F_NESTED), nil)
htypeBuf := make([]byte, 2)
cmdBuf := make([]byte, 2)
NativeEndian().PutUint16(htypeBuf, uint16(p.KeysEx[i].HeaderType))
NativeEndian().PutUint16(cmdBuf, uint16(p.KeysEx[i].Cmd))
keyAttr.AddRtAttr(TCA_PEDIT_KEY_EX_HTYPE, htypeBuf)
keyAttr.AddRtAttr(TCA_PEDIT_KEY_EX_CMD, cmdBuf)
}
}
func (p *TcPedit) SetEthDst(mac net.HardwareAddr) {
u32 := NativeEndian().Uint32(mac)
u16 := NativeEndian().Uint16(mac[4:])
tKey := TcPeditKey{}
tKeyEx := TcPeditKeyEx{}
tKey.Val = u32
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
tKey = TcPeditKey{}
tKeyEx = TcPeditKeyEx{}
tKey.Val = uint32(u16)
tKey.Mask = 0xffff0000
tKey.Off = 4
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
}
func (p *TcPedit) SetEthSrc(mac net.HardwareAddr) {
u16 := NativeEndian().Uint16(mac)
u32 := NativeEndian().Uint32(mac[2:])
tKey := TcPeditKey{}
tKeyEx := TcPeditKeyEx{}
tKey.Val = uint32(u16) << 16
tKey.Mask = 0x0000ffff
tKey.Off = 4
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
tKey = TcPeditKey{}
tKeyEx = TcPeditKeyEx{}
tKey.Val = u32
tKey.Mask = 0
tKey.Off = 8
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
}
func (p *TcPedit) SetIPv6Src(ip6 net.IP) {
u32 := NativeEndian().Uint32(ip6[:4])
tKey := TcPeditKey{}
tKeyEx := TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 8
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
u32 = NativeEndian().Uint32(ip6[4:8])
tKey = TcPeditKey{}
tKeyEx = TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 12
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
u32 = NativeEndian().Uint32(ip6[8:12])
tKey = TcPeditKey{}
tKeyEx = TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 16
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
u32 = NativeEndian().Uint32(ip6[12:16])
tKey = TcPeditKey{}
tKeyEx = TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 20
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
}
func (p *TcPedit) SetDstIP(ip net.IP) {
if ip.To4() != nil {
p.SetIPv4Dst(ip)
} else {
p.SetIPv6Dst(ip)
}
}
func (p *TcPedit) SetSrcIP(ip net.IP) {
if ip.To4() != nil {
p.SetIPv4Src(ip)
} else {
p.SetIPv6Src(ip)
}
}
func (p *TcPedit) SetIPv6Dst(ip6 net.IP) {
u32 := NativeEndian().Uint32(ip6[:4])
tKey := TcPeditKey{}
tKeyEx := TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 24
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
u32 = NativeEndian().Uint32(ip6[4:8])
tKey = TcPeditKey{}
tKeyEx = TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 28
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
u32 = NativeEndian().Uint32(ip6[8:12])
tKey = TcPeditKey{}
tKeyEx = TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 32
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
u32 = NativeEndian().Uint32(ip6[12:16])
tKey = TcPeditKey{}
tKeyEx = TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 36
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
}
func (p *TcPedit) SetIPv4Src(ip net.IP) {
u32 := NativeEndian().Uint32(ip[:4])
tKey := TcPeditKey{}
tKeyEx := TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 12
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
}
func (p *TcPedit) SetIPv4Dst(ip net.IP) {
u32 := NativeEndian().Uint32(ip[:4])
tKey := TcPeditKey{}
tKeyEx := TcPeditKeyEx{}
tKey.Val = u32
tKey.Off = 16
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
}
// SetDstPort only tcp and udp are supported to set port
func (p *TcPedit) SetDstPort(dstPort uint16, protocol uint8) {
tKey := TcPeditKey{}
tKeyEx := TcPeditKeyEx{}
switch protocol {
case unix.IPPROTO_TCP:
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
case unix.IPPROTO_UDP:
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
default:
return
}
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
tKey.Val = uint32(Swap16(dstPort)) << 16
tKey.Mask = 0x0000ffff
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
}
// SetSrcPort only tcp and udp are supported to set port
func (p *TcPedit) SetSrcPort(srcPort uint16, protocol uint8) {
tKey := TcPeditKey{}
tKeyEx := TcPeditKeyEx{}
switch protocol {
case unix.IPPROTO_TCP:
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
case unix.IPPROTO_UDP:
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
default:
return
}
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
tKey.Val = uint32(Swap16(srcPort))
tKey.Mask = 0xffff0000
p.Keys = append(p.Keys, tKey)
p.KeysEx = append(p.KeysEx, tKeyEx)
p.Sel.NKeys++
}