github.com/vishvananda/netlink@v1.3.0/nl/tc_linux.go (about)

     1  package nl
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"net"
     8  	"unsafe"
     9  
    10  	"golang.org/x/sys/unix"
    11  )
    12  
    13  // LinkLayer
    14  const (
    15  	LINKLAYER_UNSPEC = iota
    16  	LINKLAYER_ETHERNET
    17  	LINKLAYER_ATM
    18  )
    19  
    20  // ATM
    21  const (
    22  	ATM_CELL_PAYLOAD = 48
    23  	ATM_CELL_SIZE    = 53
    24  )
    25  
    26  const TC_LINKLAYER_MASK = 0x0F
    27  
    28  // Police
    29  const (
    30  	TCA_POLICE_UNSPEC = iota
    31  	TCA_POLICE_TBF
    32  	TCA_POLICE_RATE
    33  	TCA_POLICE_PEAKRATE
    34  	TCA_POLICE_AVRATE
    35  	TCA_POLICE_RESULT
    36  	TCA_POLICE_MAX = TCA_POLICE_RESULT
    37  )
    38  
    39  // Message types
    40  const (
    41  	TCA_UNSPEC = iota
    42  	TCA_KIND
    43  	TCA_OPTIONS
    44  	TCA_STATS
    45  	TCA_XSTATS
    46  	TCA_RATE
    47  	TCA_FCNT
    48  	TCA_STATS2
    49  	TCA_STAB
    50  	TCA_PAD
    51  	TCA_DUMP_INVISIBLE
    52  	TCA_CHAIN
    53  	TCA_HW_OFFLOAD
    54  	TCA_INGRESS_BLOCK
    55  	TCA_EGRESS_BLOCK
    56  	TCA_DUMP_FLAGS
    57  	TCA_MAX = TCA_DUMP_FLAGS
    58  )
    59  
    60  const (
    61  	TCA_ACT_TAB = 1
    62  	TCAA_MAX    = 1
    63  )
    64  
    65  const (
    66  	TCA_ACT_UNSPEC = iota
    67  	TCA_ACT_KIND
    68  	TCA_ACT_OPTIONS
    69  	TCA_ACT_INDEX
    70  	TCA_ACT_STATS
    71  	TCA_ACT_PAD
    72  	TCA_ACT_COOKIE
    73  	TCA_ACT_FLAGS
    74  	TCA_ACT_HW_STATS
    75  	TCA_ACT_USED_HW_STATS
    76  	TCA_ACT_IN_HW_COUNT
    77  	TCA_ACT_MAX
    78  )
    79  
    80  const (
    81  	TCA_PRIO_UNSPEC = iota
    82  	TCA_PRIO_MQ
    83  	TCA_PRIO_MAX = TCA_PRIO_MQ
    84  )
    85  
    86  const (
    87  	TCA_STATS_UNSPEC = iota
    88  	TCA_STATS_BASIC
    89  	TCA_STATS_RATE_EST
    90  	TCA_STATS_QUEUE
    91  	TCA_STATS_APP
    92  	TCA_STATS_RATE_EST64
    93  	TCA_STATS_PAD
    94  	TCA_STATS_BASIC_HW
    95  	TCA_STATS_PKT64
    96  	TCA_STATS_MAX = TCA_STATS_PKT64
    97  )
    98  
    99  const (
   100  	SizeofTcMsg          = 0x14
   101  	SizeofTcActionMsg    = 0x04
   102  	SizeofTcPrioMap      = 0x14
   103  	SizeofTcRateSpec     = 0x0c
   104  	SizeofTcNetemQopt    = 0x18
   105  	SizeofTcNetemCorr    = 0x0c
   106  	SizeofTcNetemReorder = 0x08
   107  	SizeofTcNetemCorrupt = 0x08
   108  	SizeOfTcNetemRate    = 0x10
   109  	SizeofTcTbfQopt      = 2*SizeofTcRateSpec + 0x0c
   110  	SizeofTcHtbCopt      = 2*SizeofTcRateSpec + 0x14
   111  	SizeofTcHtbGlob      = 0x14
   112  	SizeofTcU32Key       = 0x10
   113  	SizeofTcU32Sel       = 0x10 // without keys
   114  	SizeofTcGen          = 0x16
   115  	SizeofTcConnmark     = SizeofTcGen + 0x04
   116  	SizeofTcCsum         = SizeofTcGen + 0x04
   117  	SizeofTcMirred       = SizeofTcGen + 0x08
   118  	SizeofTcTunnelKey    = SizeofTcGen + 0x04
   119  	SizeofTcSkbEdit      = SizeofTcGen
   120  	SizeofTcPolice       = 2*SizeofTcRateSpec + 0x20
   121  	SizeofTcSfqQopt      = 0x0b
   122  	SizeofTcSfqRedStats  = 0x18
   123  	SizeofTcSfqQoptV1    = SizeofTcSfqQopt + SizeofTcSfqRedStats + 0x1c
   124  	SizeofUint32Bitfield = 0x8
   125  )
   126  
   127  // struct tcmsg {
   128  //   unsigned char tcm_family;
   129  //   unsigned char tcm__pad1;
   130  //   unsigned short  tcm__pad2;
   131  //   int   tcm_ifindex;
   132  //   __u32   tcm_handle;
   133  //   __u32   tcm_parent;
   134  //   __u32   tcm_info;
   135  // };
   136  
   137  type TcMsg struct {
   138  	Family  uint8
   139  	Pad     [3]byte
   140  	Ifindex int32
   141  	Handle  uint32
   142  	Parent  uint32
   143  	Info    uint32
   144  }
   145  
   146  func (msg *TcMsg) Len() int {
   147  	return SizeofTcMsg
   148  }
   149  
   150  func DeserializeTcMsg(b []byte) *TcMsg {
   151  	return (*TcMsg)(unsafe.Pointer(&b[0:SizeofTcMsg][0]))
   152  }
   153  
   154  func (x *TcMsg) Serialize() []byte {
   155  	return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:]
   156  }
   157  
   158  type Tcf struct {
   159  	Install  uint64
   160  	LastUse  uint64
   161  	Expires  uint64
   162  	FirstUse uint64
   163  }
   164  
   165  func DeserializeTcf(b []byte) *Tcf {
   166  	const size = int(unsafe.Sizeof(Tcf{}))
   167  	return (*Tcf)(unsafe.Pointer(&b[0:size][0]))
   168  }
   169  
   170  // struct tcamsg {
   171  //   unsigned char tca_family;
   172  //   unsigned char tca__pad1;
   173  //   unsigned short  tca__pad2;
   174  // };
   175  
   176  type TcActionMsg struct {
   177  	Family uint8
   178  	Pad    [3]byte
   179  }
   180  
   181  func (msg *TcActionMsg) Len() int {
   182  	return SizeofTcActionMsg
   183  }
   184  
   185  func DeserializeTcActionMsg(b []byte) *TcActionMsg {
   186  	return (*TcActionMsg)(unsafe.Pointer(&b[0:SizeofTcActionMsg][0]))
   187  }
   188  
   189  func (x *TcActionMsg) Serialize() []byte {
   190  	return (*(*[SizeofTcActionMsg]byte)(unsafe.Pointer(x)))[:]
   191  }
   192  
   193  const (
   194  	TC_PRIO_MAX = 15
   195  )
   196  
   197  // struct tc_prio_qopt {
   198  // 	int bands;      /* Number of bands */
   199  // 	__u8  priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
   200  // };
   201  
   202  type TcPrioMap struct {
   203  	Bands   int32
   204  	Priomap [TC_PRIO_MAX + 1]uint8
   205  }
   206  
   207  func (msg *TcPrioMap) Len() int {
   208  	return SizeofTcPrioMap
   209  }
   210  
   211  func DeserializeTcPrioMap(b []byte) *TcPrioMap {
   212  	return (*TcPrioMap)(unsafe.Pointer(&b[0:SizeofTcPrioMap][0]))
   213  }
   214  
   215  func (x *TcPrioMap) Serialize() []byte {
   216  	return (*(*[SizeofTcPrioMap]byte)(unsafe.Pointer(x)))[:]
   217  }
   218  
   219  const (
   220  	TCA_TBF_UNSPEC = iota
   221  	TCA_TBF_PARMS
   222  	TCA_TBF_RTAB
   223  	TCA_TBF_PTAB
   224  	TCA_TBF_RATE64
   225  	TCA_TBF_PRATE64
   226  	TCA_TBF_BURST
   227  	TCA_TBF_PBURST
   228  	TCA_TBF_MAX = TCA_TBF_PBURST
   229  )
   230  
   231  // struct tc_ratespec {
   232  //   unsigned char cell_log;
   233  //   __u8    linklayer; /* lower 4 bits */
   234  //   unsigned short  overhead;
   235  //   short   cell_align;
   236  //   unsigned short  mpu;
   237  //   __u32   rate;
   238  // };
   239  
   240  type TcRateSpec struct {
   241  	CellLog   uint8
   242  	Linklayer uint8
   243  	Overhead  uint16
   244  	CellAlign int16
   245  	Mpu       uint16
   246  	Rate      uint32
   247  }
   248  
   249  func (msg *TcRateSpec) Len() int {
   250  	return SizeofTcRateSpec
   251  }
   252  
   253  func DeserializeTcRateSpec(b []byte) *TcRateSpec {
   254  	return (*TcRateSpec)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0]))
   255  }
   256  
   257  func (x *TcRateSpec) Serialize() []byte {
   258  	return (*(*[SizeofTcRateSpec]byte)(unsafe.Pointer(x)))[:]
   259  }
   260  
   261  /**
   262  * NETEM
   263   */
   264  
   265  const (
   266  	TCA_NETEM_UNSPEC = iota
   267  	TCA_NETEM_CORR
   268  	TCA_NETEM_DELAY_DIST
   269  	TCA_NETEM_REORDER
   270  	TCA_NETEM_CORRUPT
   271  	TCA_NETEM_LOSS
   272  	TCA_NETEM_RATE
   273  	TCA_NETEM_ECN
   274  	TCA_NETEM_RATE64
   275  	TCA_NETEM_MAX = TCA_NETEM_RATE64
   276  )
   277  
   278  // struct tc_netem_qopt {
   279  //	__u32	latency;	/* added delay (us) */
   280  //	__u32   limit;		/* fifo limit (packets) */
   281  //	__u32	loss;		/* random packet loss (0=none ~0=100%) */
   282  //	__u32	gap;		/* re-ordering gap (0 for none) */
   283  //	__u32   duplicate;	/* random packet dup  (0=none ~0=100%) */
   284  // 	__u32	jitter;		/* random jitter in latency (us) */
   285  // };
   286  
   287  type TcNetemQopt struct {
   288  	Latency   uint32
   289  	Limit     uint32
   290  	Loss      uint32
   291  	Gap       uint32
   292  	Duplicate uint32
   293  	Jitter    uint32
   294  }
   295  
   296  func (msg *TcNetemQopt) Len() int {
   297  	return SizeofTcNetemQopt
   298  }
   299  
   300  func DeserializeTcNetemQopt(b []byte) *TcNetemQopt {
   301  	return (*TcNetemQopt)(unsafe.Pointer(&b[0:SizeofTcNetemQopt][0]))
   302  }
   303  
   304  func (x *TcNetemQopt) Serialize() []byte {
   305  	return (*(*[SizeofTcNetemQopt]byte)(unsafe.Pointer(x)))[:]
   306  }
   307  
   308  // struct tc_netem_corr {
   309  //  __u32   delay_corr; /* delay correlation */
   310  //  __u32   loss_corr;  /* packet loss correlation */
   311  //  __u32   dup_corr;   /* duplicate correlation  */
   312  // };
   313  
   314  type TcNetemCorr struct {
   315  	DelayCorr uint32
   316  	LossCorr  uint32
   317  	DupCorr   uint32
   318  }
   319  
   320  func (msg *TcNetemCorr) Len() int {
   321  	return SizeofTcNetemCorr
   322  }
   323  
   324  func DeserializeTcNetemCorr(b []byte) *TcNetemCorr {
   325  	return (*TcNetemCorr)(unsafe.Pointer(&b[0:SizeofTcNetemCorr][0]))
   326  }
   327  
   328  func (x *TcNetemCorr) Serialize() []byte {
   329  	return (*(*[SizeofTcNetemCorr]byte)(unsafe.Pointer(x)))[:]
   330  }
   331  
   332  // struct tc_netem_reorder {
   333  //  __u32   probability;
   334  //  __u32   correlation;
   335  // };
   336  
   337  type TcNetemReorder struct {
   338  	Probability uint32
   339  	Correlation uint32
   340  }
   341  
   342  func (msg *TcNetemReorder) Len() int {
   343  	return SizeofTcNetemReorder
   344  }
   345  
   346  func DeserializeTcNetemReorder(b []byte) *TcNetemReorder {
   347  	return (*TcNetemReorder)(unsafe.Pointer(&b[0:SizeofTcNetemReorder][0]))
   348  }
   349  
   350  func (x *TcNetemReorder) Serialize() []byte {
   351  	return (*(*[SizeofTcNetemReorder]byte)(unsafe.Pointer(x)))[:]
   352  }
   353  
   354  // struct tc_netem_corrupt {
   355  //  __u32   probability;
   356  //  __u32   correlation;
   357  // };
   358  
   359  type TcNetemCorrupt struct {
   360  	Probability uint32
   361  	Correlation uint32
   362  }
   363  
   364  func (msg *TcNetemCorrupt) Len() int {
   365  	return SizeofTcNetemCorrupt
   366  }
   367  
   368  func DeserializeTcNetemCorrupt(b []byte) *TcNetemCorrupt {
   369  	return (*TcNetemCorrupt)(unsafe.Pointer(&b[0:SizeofTcNetemCorrupt][0]))
   370  }
   371  
   372  func (x *TcNetemCorrupt) Serialize() []byte {
   373  	return (*(*[SizeofTcNetemCorrupt]byte)(unsafe.Pointer(x)))[:]
   374  }
   375  
   376  // TcNetemRate is a struct that represents the rate of a netem qdisc
   377  type TcNetemRate struct {
   378  	Rate           uint32
   379  	PacketOverhead int32
   380  	CellSize       uint32
   381  	CellOverhead   int32
   382  }
   383  
   384  func (msg *TcNetemRate) Len() int {
   385  	return SizeofTcRateSpec
   386  }
   387  
   388  func DeserializeTcNetemRate(b []byte) *TcNetemRate {
   389  	return (*TcNetemRate)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0]))
   390  }
   391  
   392  func (msg *TcNetemRate) Serialize() []byte {
   393  	return (*(*[SizeOfTcNetemRate]byte)(unsafe.Pointer(msg)))[:]
   394  }
   395  
   396  // struct tc_tbf_qopt {
   397  //   struct tc_ratespec rate;
   398  //   struct tc_ratespec peakrate;
   399  //   __u32   limit;
   400  //   __u32   buffer;
   401  //   __u32   mtu;
   402  // };
   403  
   404  type TcTbfQopt struct {
   405  	Rate     TcRateSpec
   406  	Peakrate TcRateSpec
   407  	Limit    uint32
   408  	Buffer   uint32
   409  	Mtu      uint32
   410  }
   411  
   412  func (msg *TcTbfQopt) Len() int {
   413  	return SizeofTcTbfQopt
   414  }
   415  
   416  func DeserializeTcTbfQopt(b []byte) *TcTbfQopt {
   417  	return (*TcTbfQopt)(unsafe.Pointer(&b[0:SizeofTcTbfQopt][0]))
   418  }
   419  
   420  func (x *TcTbfQopt) Serialize() []byte {
   421  	return (*(*[SizeofTcTbfQopt]byte)(unsafe.Pointer(x)))[:]
   422  }
   423  
   424  const (
   425  	TCA_HTB_UNSPEC = iota
   426  	TCA_HTB_PARMS
   427  	TCA_HTB_INIT
   428  	TCA_HTB_CTAB
   429  	TCA_HTB_RTAB
   430  	TCA_HTB_DIRECT_QLEN
   431  	TCA_HTB_RATE64
   432  	TCA_HTB_CEIL64
   433  	TCA_HTB_MAX = TCA_HTB_CEIL64
   434  )
   435  
   436  //struct tc_htb_opt {
   437  //	struct tc_ratespec	rate;
   438  //	struct tc_ratespec	ceil;
   439  //	__u32	buffer;
   440  //	__u32	cbuffer;
   441  //	__u32	quantum;
   442  //	__u32	level;		/* out only */
   443  //	__u32	prio;
   444  //};
   445  
   446  type TcHtbCopt struct {
   447  	Rate    TcRateSpec
   448  	Ceil    TcRateSpec
   449  	Buffer  uint32
   450  	Cbuffer uint32
   451  	Quantum uint32
   452  	Level   uint32
   453  	Prio    uint32
   454  }
   455  
   456  func (msg *TcHtbCopt) Len() int {
   457  	return SizeofTcHtbCopt
   458  }
   459  
   460  func DeserializeTcHtbCopt(b []byte) *TcHtbCopt {
   461  	return (*TcHtbCopt)(unsafe.Pointer(&b[0:SizeofTcHtbCopt][0]))
   462  }
   463  
   464  func (x *TcHtbCopt) Serialize() []byte {
   465  	return (*(*[SizeofTcHtbCopt]byte)(unsafe.Pointer(x)))[:]
   466  }
   467  
   468  type TcHtbGlob struct {
   469  	Version      uint32
   470  	Rate2Quantum uint32
   471  	Defcls       uint32
   472  	Debug        uint32
   473  	DirectPkts   uint32
   474  }
   475  
   476  func (msg *TcHtbGlob) Len() int {
   477  	return SizeofTcHtbGlob
   478  }
   479  
   480  func DeserializeTcHtbGlob(b []byte) *TcHtbGlob {
   481  	return (*TcHtbGlob)(unsafe.Pointer(&b[0:SizeofTcHtbGlob][0]))
   482  }
   483  
   484  func (x *TcHtbGlob) Serialize() []byte {
   485  	return (*(*[SizeofTcHtbGlob]byte)(unsafe.Pointer(x)))[:]
   486  }
   487  
   488  // HFSC
   489  
   490  type Curve struct {
   491  	m1 uint32
   492  	d  uint32
   493  	m2 uint32
   494  }
   495  
   496  type HfscCopt struct {
   497  	Rsc Curve
   498  	Fsc Curve
   499  	Usc Curve
   500  }
   501  
   502  func (c *Curve) Attrs() (uint32, uint32, uint32) {
   503  	return c.m1, c.d, c.m2
   504  }
   505  
   506  func (c *Curve) Set(m1 uint32, d uint32, m2 uint32) {
   507  	c.m1 = m1
   508  	c.d = d
   509  	c.m2 = m2
   510  }
   511  
   512  func DeserializeHfscCurve(b []byte) *Curve {
   513  	return &Curve{
   514  		m1: binary.LittleEndian.Uint32(b[0:4]),
   515  		d:  binary.LittleEndian.Uint32(b[4:8]),
   516  		m2: binary.LittleEndian.Uint32(b[8:12]),
   517  	}
   518  }
   519  
   520  func SerializeHfscCurve(c *Curve) (b []byte) {
   521  	t := make([]byte, binary.MaxVarintLen32)
   522  	binary.LittleEndian.PutUint32(t, c.m1)
   523  	b = append(b, t[:4]...)
   524  	binary.LittleEndian.PutUint32(t, c.d)
   525  	b = append(b, t[:4]...)
   526  	binary.LittleEndian.PutUint32(t, c.m2)
   527  	b = append(b, t[:4]...)
   528  	return b
   529  }
   530  
   531  type TcHfscOpt struct {
   532  	Defcls uint16
   533  }
   534  
   535  func (x *TcHfscOpt) Serialize() []byte {
   536  	return (*(*[2]byte)(unsafe.Pointer(x)))[:]
   537  }
   538  
   539  const (
   540  	TCA_U32_UNSPEC = iota
   541  	TCA_U32_CLASSID
   542  	TCA_U32_HASH
   543  	TCA_U32_LINK
   544  	TCA_U32_DIVISOR
   545  	TCA_U32_SEL
   546  	TCA_U32_POLICE
   547  	TCA_U32_ACT
   548  	TCA_U32_INDEV
   549  	TCA_U32_PCNT
   550  	TCA_U32_MARK
   551  	TCA_U32_MAX = TCA_U32_MARK
   552  )
   553  
   554  // struct tc_u32_key {
   555  //   __be32    mask;
   556  //   __be32    val;
   557  //   int   off;
   558  //   int   offmask;
   559  // };
   560  
   561  type TcU32Key struct {
   562  	Mask    uint32 // big endian
   563  	Val     uint32 // big endian
   564  	Off     int32
   565  	OffMask int32
   566  }
   567  
   568  func (msg *TcU32Key) Len() int {
   569  	return SizeofTcU32Key
   570  }
   571  
   572  func DeserializeTcU32Key(b []byte) *TcU32Key {
   573  	return (*TcU32Key)(unsafe.Pointer(&b[0:SizeofTcU32Key][0]))
   574  }
   575  
   576  func (x *TcU32Key) Serialize() []byte {
   577  	return (*(*[SizeofTcU32Key]byte)(unsafe.Pointer(x)))[:]
   578  }
   579  
   580  // struct tc_u32_sel {
   581  //   unsigned char   flags;
   582  //   unsigned char   offshift;
   583  //   unsigned char   nkeys;
   584  //
   585  //   __be16      offmask;
   586  //   __u16     off;
   587  //   short     offoff;
   588  //
   589  //   short     hoff;
   590  //   __be32      hmask;
   591  //   struct tc_u32_key keys[0];
   592  // };
   593  
   594  const (
   595  	TC_U32_TERMINAL  = 1 << iota
   596  	TC_U32_OFFSET    = 1 << iota
   597  	TC_U32_VAROFFSET = 1 << iota
   598  	TC_U32_EAT       = 1 << iota
   599  )
   600  
   601  type TcU32Sel struct {
   602  	Flags    uint8
   603  	Offshift uint8
   604  	Nkeys    uint8
   605  	Pad      uint8
   606  	Offmask  uint16 // big endian
   607  	Off      uint16
   608  	Offoff   int16
   609  	Hoff     int16
   610  	Hmask    uint32 // big endian
   611  	Keys     []TcU32Key
   612  }
   613  
   614  func (msg *TcU32Sel) Len() int {
   615  	return SizeofTcU32Sel + int(msg.Nkeys)*SizeofTcU32Key
   616  }
   617  
   618  func DeserializeTcU32Sel(b []byte) *TcU32Sel {
   619  	x := &TcU32Sel{}
   620  	copy((*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:], b)
   621  	next := SizeofTcU32Sel
   622  	var i uint8
   623  	for i = 0; i < x.Nkeys; i++ {
   624  		x.Keys = append(x.Keys, *DeserializeTcU32Key(b[next:]))
   625  		next += SizeofTcU32Key
   626  	}
   627  	return x
   628  }
   629  
   630  func (x *TcU32Sel) Serialize() []byte {
   631  	// This can't just unsafe.cast because it must iterate through keys.
   632  	buf := make([]byte, x.Len())
   633  	copy(buf, (*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:])
   634  	next := SizeofTcU32Sel
   635  	for _, key := range x.Keys {
   636  		keyBuf := key.Serialize()
   637  		copy(buf[next:], keyBuf)
   638  		next += SizeofTcU32Key
   639  	}
   640  	return buf
   641  }
   642  
   643  type TcGen struct {
   644  	Index   uint32
   645  	Capab   uint32
   646  	Action  int32
   647  	Refcnt  int32
   648  	Bindcnt int32
   649  }
   650  
   651  func (msg *TcGen) Len() int {
   652  	return SizeofTcGen
   653  }
   654  
   655  func DeserializeTcGen(b []byte) *TcGen {
   656  	return (*TcGen)(unsafe.Pointer(&b[0:SizeofTcGen][0]))
   657  }
   658  
   659  func (x *TcGen) Serialize() []byte {
   660  	return (*(*[SizeofTcGen]byte)(unsafe.Pointer(x)))[:]
   661  }
   662  
   663  // #define tc_gen \
   664  //   __u32                 index; \
   665  //   __u32                 capab; \
   666  //   int                   action; \
   667  //   int                   refcnt; \
   668  //   int                   bindcnt
   669  
   670  const (
   671  	TCA_ACT_GACT = 5
   672  )
   673  
   674  const (
   675  	TCA_GACT_UNSPEC = iota
   676  	TCA_GACT_TM
   677  	TCA_GACT_PARMS
   678  	TCA_GACT_PROB
   679  	TCA_GACT_MAX = TCA_GACT_PROB
   680  )
   681  
   682  type TcGact TcGen
   683  
   684  const (
   685  	TCA_ACT_BPF = 13
   686  )
   687  
   688  const (
   689  	TCA_ACT_BPF_UNSPEC = iota
   690  	TCA_ACT_BPF_TM
   691  	TCA_ACT_BPF_PARMS
   692  	TCA_ACT_BPF_OPS_LEN
   693  	TCA_ACT_BPF_OPS
   694  	TCA_ACT_BPF_FD
   695  	TCA_ACT_BPF_NAME
   696  	TCA_ACT_BPF_MAX = TCA_ACT_BPF_NAME
   697  )
   698  
   699  const (
   700  	TCA_BPF_FLAG_ACT_DIRECT uint32 = 1 << iota
   701  )
   702  
   703  const (
   704  	TCA_BPF_UNSPEC = iota
   705  	TCA_BPF_ACT
   706  	TCA_BPF_POLICE
   707  	TCA_BPF_CLASSID
   708  	TCA_BPF_OPS_LEN
   709  	TCA_BPF_OPS
   710  	TCA_BPF_FD
   711  	TCA_BPF_NAME
   712  	TCA_BPF_FLAGS
   713  	TCA_BPF_FLAGS_GEN
   714  	TCA_BPF_TAG
   715  	TCA_BPF_ID
   716  	TCA_BPF_MAX = TCA_BPF_ID
   717  )
   718  
   719  type TcBpf TcGen
   720  
   721  const (
   722  	TCA_ACT_CONNMARK = 14
   723  )
   724  
   725  const (
   726  	TCA_CONNMARK_UNSPEC = iota
   727  	TCA_CONNMARK_PARMS
   728  	TCA_CONNMARK_TM
   729  	TCA_CONNMARK_MAX = TCA_CONNMARK_TM
   730  )
   731  
   732  // struct tc_connmark {
   733  //   tc_gen;
   734  //   __u16 zone;
   735  // };
   736  
   737  type TcConnmark struct {
   738  	TcGen
   739  	Zone uint16
   740  }
   741  
   742  func (msg *TcConnmark) Len() int {
   743  	return SizeofTcConnmark
   744  }
   745  
   746  func DeserializeTcConnmark(b []byte) *TcConnmark {
   747  	return (*TcConnmark)(unsafe.Pointer(&b[0:SizeofTcConnmark][0]))
   748  }
   749  
   750  func (x *TcConnmark) Serialize() []byte {
   751  	return (*(*[SizeofTcConnmark]byte)(unsafe.Pointer(x)))[:]
   752  }
   753  
   754  const (
   755  	TCA_CSUM_UNSPEC = iota
   756  	TCA_CSUM_PARMS
   757  	TCA_CSUM_TM
   758  	TCA_CSUM_PAD
   759  	TCA_CSUM_MAX = TCA_CSUM_PAD
   760  )
   761  
   762  // struct tc_csum {
   763  //   tc_gen;
   764  //   __u32 update_flags;
   765  // }
   766  
   767  type TcCsum struct {
   768  	TcGen
   769  	UpdateFlags uint32
   770  }
   771  
   772  func (msg *TcCsum) Len() int {
   773  	return SizeofTcCsum
   774  }
   775  
   776  func DeserializeTcCsum(b []byte) *TcCsum {
   777  	return (*TcCsum)(unsafe.Pointer(&b[0:SizeofTcCsum][0]))
   778  }
   779  
   780  func (x *TcCsum) Serialize() []byte {
   781  	return (*(*[SizeofTcCsum]byte)(unsafe.Pointer(x)))[:]
   782  }
   783  
   784  const (
   785  	TCA_ACT_MIRRED = 8
   786  )
   787  
   788  const (
   789  	TCA_MIRRED_UNSPEC = iota
   790  	TCA_MIRRED_TM
   791  	TCA_MIRRED_PARMS
   792  	TCA_MIRRED_MAX = TCA_MIRRED_PARMS
   793  )
   794  
   795  // struct tc_mirred {
   796  // 	tc_gen;
   797  // 	int                     eaction;   /* one of IN/EGRESS_MIRROR/REDIR */
   798  // 	__u32                   ifindex;  /* ifindex of egress port */
   799  // };
   800  
   801  type TcMirred struct {
   802  	TcGen
   803  	Eaction int32
   804  	Ifindex uint32
   805  }
   806  
   807  func (msg *TcMirred) Len() int {
   808  	return SizeofTcMirred
   809  }
   810  
   811  func DeserializeTcMirred(b []byte) *TcMirred {
   812  	return (*TcMirred)(unsafe.Pointer(&b[0:SizeofTcMirred][0]))
   813  }
   814  
   815  func (x *TcMirred) Serialize() []byte {
   816  	return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:]
   817  }
   818  
   819  const (
   820  	TCA_TUNNEL_KEY_UNSPEC = iota
   821  	TCA_TUNNEL_KEY_TM
   822  	TCA_TUNNEL_KEY_PARMS
   823  	TCA_TUNNEL_KEY_ENC_IPV4_SRC
   824  	TCA_TUNNEL_KEY_ENC_IPV4_DST
   825  	TCA_TUNNEL_KEY_ENC_IPV6_SRC
   826  	TCA_TUNNEL_KEY_ENC_IPV6_DST
   827  	TCA_TUNNEL_KEY_ENC_KEY_ID
   828  	TCA_TUNNEL_KEY_PAD
   829  	TCA_TUNNEL_KEY_ENC_DST_PORT
   830  	TCA_TUNNEL_KEY_NO_CSUM
   831  	TCA_TUNNEL_KEY_ENC_OPTS
   832  	TCA_TUNNEL_KEY_ENC_TOS
   833  	TCA_TUNNEL_KEY_ENC_TTL
   834  	TCA_TUNNEL_KEY_MAX
   835  )
   836  
   837  type TcTunnelKey struct {
   838  	TcGen
   839  	Action int32
   840  }
   841  
   842  func (x *TcTunnelKey) Len() int {
   843  	return SizeofTcTunnelKey
   844  }
   845  
   846  func DeserializeTunnelKey(b []byte) *TcTunnelKey {
   847  	return (*TcTunnelKey)(unsafe.Pointer(&b[0:SizeofTcTunnelKey][0]))
   848  }
   849  
   850  func (x *TcTunnelKey) Serialize() []byte {
   851  	return (*(*[SizeofTcTunnelKey]byte)(unsafe.Pointer(x)))[:]
   852  }
   853  
   854  const (
   855  	TCA_SKBEDIT_UNSPEC = iota
   856  	TCA_SKBEDIT_TM
   857  	TCA_SKBEDIT_PARMS
   858  	TCA_SKBEDIT_PRIORITY
   859  	TCA_SKBEDIT_QUEUE_MAPPING
   860  	TCA_SKBEDIT_MARK
   861  	TCA_SKBEDIT_PAD
   862  	TCA_SKBEDIT_PTYPE
   863  	TCA_SKBEDIT_MASK
   864  	TCA_SKBEDIT_MAX
   865  )
   866  
   867  type TcSkbEdit struct {
   868  	TcGen
   869  }
   870  
   871  func (x *TcSkbEdit) Len() int {
   872  	return SizeofTcSkbEdit
   873  }
   874  
   875  func DeserializeSkbEdit(b []byte) *TcSkbEdit {
   876  	return (*TcSkbEdit)(unsafe.Pointer(&b[0:SizeofTcSkbEdit][0]))
   877  }
   878  
   879  func (x *TcSkbEdit) Serialize() []byte {
   880  	return (*(*[SizeofTcSkbEdit]byte)(unsafe.Pointer(x)))[:]
   881  }
   882  
   883  // struct tc_police {
   884  // 	__u32			index;
   885  // 	int			action;
   886  // 	__u32			limit;
   887  // 	__u32			burst;
   888  // 	__u32			mtu;
   889  // 	struct tc_ratespec	rate;
   890  // 	struct tc_ratespec	peakrate;
   891  // 	int				refcnt;
   892  // 	int				bindcnt;
   893  // 	__u32			capab;
   894  // };
   895  
   896  type TcPolice struct {
   897  	Index    uint32
   898  	Action   int32
   899  	Limit    uint32
   900  	Burst    uint32
   901  	Mtu      uint32
   902  	Rate     TcRateSpec
   903  	PeakRate TcRateSpec
   904  	Refcnt   int32
   905  	Bindcnt  int32
   906  	Capab    uint32
   907  }
   908  
   909  func (msg *TcPolice) Len() int {
   910  	return SizeofTcPolice
   911  }
   912  
   913  func DeserializeTcPolice(b []byte) *TcPolice {
   914  	return (*TcPolice)(unsafe.Pointer(&b[0:SizeofTcPolice][0]))
   915  }
   916  
   917  func (x *TcPolice) Serialize() []byte {
   918  	return (*(*[SizeofTcPolice]byte)(unsafe.Pointer(x)))[:]
   919  }
   920  
   921  const (
   922  	TCA_FW_UNSPEC = iota
   923  	TCA_FW_CLASSID
   924  	TCA_FW_POLICE
   925  	TCA_FW_INDEV
   926  	TCA_FW_ACT
   927  	TCA_FW_MASK
   928  	TCA_FW_MAX = TCA_FW_MASK
   929  )
   930  
   931  const (
   932  	TCA_MATCHALL_UNSPEC = iota
   933  	TCA_MATCHALL_CLASSID
   934  	TCA_MATCHALL_ACT
   935  	TCA_MATCHALL_FLAGS
   936  )
   937  
   938  const (
   939  	TCA_FQ_UNSPEC             = iota
   940  	TCA_FQ_PLIMIT             // limit of total number of packets in queue
   941  	TCA_FQ_FLOW_PLIMIT        // limit of packets per flow
   942  	TCA_FQ_QUANTUM            // RR quantum
   943  	TCA_FQ_INITIAL_QUANTUM    // RR quantum for new flow
   944  	TCA_FQ_RATE_ENABLE        // enable/disable rate limiting
   945  	TCA_FQ_FLOW_DEFAULT_RATE  // obsolete do not use
   946  	TCA_FQ_FLOW_MAX_RATE      // per flow max rate
   947  	TCA_FQ_BUCKETS_LOG        // log2(number of buckets)
   948  	TCA_FQ_FLOW_REFILL_DELAY  // flow credit refill delay in usec
   949  	TCA_FQ_ORPHAN_MASK        // mask applied to orphaned skb hashes
   950  	TCA_FQ_LOW_RATE_THRESHOLD // per packet delay under this rate
   951  	TCA_FQ_CE_THRESHOLD       // DCTCP-like CE-marking threshold
   952  	TCA_FQ_TIMER_SLACK        // timer slack
   953  	TCA_FQ_HORIZON            // time horizon in us
   954  	TCA_FQ_HORIZON_DROP       // drop packets beyond horizon, or cap their EDT
   955  )
   956  
   957  const (
   958  	TCA_FQ_CODEL_UNSPEC = iota
   959  	TCA_FQ_CODEL_TARGET
   960  	TCA_FQ_CODEL_LIMIT
   961  	TCA_FQ_CODEL_INTERVAL
   962  	TCA_FQ_CODEL_ECN
   963  	TCA_FQ_CODEL_FLOWS
   964  	TCA_FQ_CODEL_QUANTUM
   965  	TCA_FQ_CODEL_CE_THRESHOLD
   966  	TCA_FQ_CODEL_DROP_BATCH_SIZE
   967  	TCA_FQ_CODEL_MEMORY_LIMIT
   968  )
   969  
   970  const (
   971  	TCA_HFSC_UNSPEC = iota
   972  	TCA_HFSC_RSC
   973  	TCA_HFSC_FSC
   974  	TCA_HFSC_USC
   975  )
   976  
   977  const (
   978  	TCA_FLOWER_UNSPEC = iota
   979  	TCA_FLOWER_CLASSID
   980  	TCA_FLOWER_INDEV
   981  	TCA_FLOWER_ACT
   982  	TCA_FLOWER_KEY_ETH_DST       /* ETH_ALEN */
   983  	TCA_FLOWER_KEY_ETH_DST_MASK  /* ETH_ALEN */
   984  	TCA_FLOWER_KEY_ETH_SRC       /* ETH_ALEN */
   985  	TCA_FLOWER_KEY_ETH_SRC_MASK  /* ETH_ALEN */
   986  	TCA_FLOWER_KEY_ETH_TYPE      /* be16 */
   987  	TCA_FLOWER_KEY_IP_PROTO      /* u8 */
   988  	TCA_FLOWER_KEY_IPV4_SRC      /* be32 */
   989  	TCA_FLOWER_KEY_IPV4_SRC_MASK /* be32 */
   990  	TCA_FLOWER_KEY_IPV4_DST      /* be32 */
   991  	TCA_FLOWER_KEY_IPV4_DST_MASK /* be32 */
   992  	TCA_FLOWER_KEY_IPV6_SRC      /* struct in6_addr */
   993  	TCA_FLOWER_KEY_IPV6_SRC_MASK /* struct in6_addr */
   994  	TCA_FLOWER_KEY_IPV6_DST      /* struct in6_addr */
   995  	TCA_FLOWER_KEY_IPV6_DST_MASK /* struct in6_addr */
   996  	TCA_FLOWER_KEY_TCP_SRC       /* be16 */
   997  	TCA_FLOWER_KEY_TCP_DST       /* be16 */
   998  	TCA_FLOWER_KEY_UDP_SRC       /* be16 */
   999  	TCA_FLOWER_KEY_UDP_DST       /* be16 */
  1000  
  1001  	TCA_FLOWER_FLAGS
  1002  	TCA_FLOWER_KEY_VLAN_ID       /* be16 */
  1003  	TCA_FLOWER_KEY_VLAN_PRIO     /* u8   */
  1004  	TCA_FLOWER_KEY_VLAN_ETH_TYPE /* be16 */
  1005  
  1006  	TCA_FLOWER_KEY_ENC_KEY_ID        /* be32 */
  1007  	TCA_FLOWER_KEY_ENC_IPV4_SRC      /* be32 */
  1008  	TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK /* be32 */
  1009  	TCA_FLOWER_KEY_ENC_IPV4_DST      /* be32 */
  1010  	TCA_FLOWER_KEY_ENC_IPV4_DST_MASK /* be32 */
  1011  	TCA_FLOWER_KEY_ENC_IPV6_SRC      /* struct in6_addr */
  1012  	TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK /* struct in6_addr */
  1013  	TCA_FLOWER_KEY_ENC_IPV6_DST      /* struct in6_addr */
  1014  	TCA_FLOWER_KEY_ENC_IPV6_DST_MASK /* struct in6_addr */
  1015  
  1016  	TCA_FLOWER_KEY_TCP_SRC_MASK  /* be16 */
  1017  	TCA_FLOWER_KEY_TCP_DST_MASK  /* be16 */
  1018  	TCA_FLOWER_KEY_UDP_SRC_MASK  /* be16 */
  1019  	TCA_FLOWER_KEY_UDP_DST_MASK  /* be16 */
  1020  	TCA_FLOWER_KEY_SCTP_SRC_MASK /* be16 */
  1021  	TCA_FLOWER_KEY_SCTP_DST_MASK /* be16 */
  1022  
  1023  	TCA_FLOWER_KEY_SCTP_SRC /* be16 */
  1024  	TCA_FLOWER_KEY_SCTP_DST /* be16 */
  1025  
  1026  	TCA_FLOWER_KEY_ENC_UDP_SRC_PORT      /* be16 */
  1027  	TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK /* be16 */
  1028  	TCA_FLOWER_KEY_ENC_UDP_DST_PORT      /* be16 */
  1029  	TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK /* be16 */
  1030  
  1031  	TCA_FLOWER_KEY_FLAGS      /* be32 */
  1032  	TCA_FLOWER_KEY_FLAGS_MASK /* be32 */
  1033  
  1034  	TCA_FLOWER_KEY_ICMPV4_CODE      /* u8 */
  1035  	TCA_FLOWER_KEY_ICMPV4_CODE_MASK /* u8 */
  1036  	TCA_FLOWER_KEY_ICMPV4_TYPE      /* u8 */
  1037  	TCA_FLOWER_KEY_ICMPV4_TYPE_MASK /* u8 */
  1038  	TCA_FLOWER_KEY_ICMPV6_CODE      /* u8 */
  1039  	TCA_FLOWER_KEY_ICMPV6_CODE_MASK /* u8 */
  1040  	TCA_FLOWER_KEY_ICMPV6_TYPE      /* u8 */
  1041  	TCA_FLOWER_KEY_ICMPV6_TYPE_MASK /* u8 */
  1042  
  1043  	TCA_FLOWER_KEY_ARP_SIP      /* be32 */
  1044  	TCA_FLOWER_KEY_ARP_SIP_MASK /* be32 */
  1045  	TCA_FLOWER_KEY_ARP_TIP      /* be32 */
  1046  	TCA_FLOWER_KEY_ARP_TIP_MASK /* be32 */
  1047  	TCA_FLOWER_KEY_ARP_OP       /* u8 */
  1048  	TCA_FLOWER_KEY_ARP_OP_MASK  /* u8 */
  1049  	TCA_FLOWER_KEY_ARP_SHA      /* ETH_ALEN */
  1050  	TCA_FLOWER_KEY_ARP_SHA_MASK /* ETH_ALEN */
  1051  	TCA_FLOWER_KEY_ARP_THA      /* ETH_ALEN */
  1052  	TCA_FLOWER_KEY_ARP_THA_MASK /* ETH_ALEN */
  1053  
  1054  	TCA_FLOWER_KEY_MPLS_TTL   /* u8 - 8 bits */
  1055  	TCA_FLOWER_KEY_MPLS_BOS   /* u8 - 1 bit */
  1056  	TCA_FLOWER_KEY_MPLS_TC    /* u8 - 3 bits */
  1057  	TCA_FLOWER_KEY_MPLS_LABEL /* be32 - 20 bits */
  1058  
  1059  	TCA_FLOWER_KEY_TCP_FLAGS      /* be16 */
  1060  	TCA_FLOWER_KEY_TCP_FLAGS_MASK /* be16 */
  1061  
  1062  	TCA_FLOWER_KEY_IP_TOS      /* u8 */
  1063  	TCA_FLOWER_KEY_IP_TOS_MASK /* u8 */
  1064  	TCA_FLOWER_KEY_IP_TTL      /* u8 */
  1065  	TCA_FLOWER_KEY_IP_TTL_MASK /* u8 */
  1066  
  1067  	TCA_FLOWER_KEY_CVLAN_ID       /* be16 */
  1068  	TCA_FLOWER_KEY_CVLAN_PRIO     /* u8   */
  1069  	TCA_FLOWER_KEY_CVLAN_ETH_TYPE /* be16 */
  1070  
  1071  	TCA_FLOWER_KEY_ENC_IP_TOS      /* u8 */
  1072  	TCA_FLOWER_KEY_ENC_IP_TOS_MASK /* u8 */
  1073  	TCA_FLOWER_KEY_ENC_IP_TTL      /* u8 */
  1074  	TCA_FLOWER_KEY_ENC_IP_TTL_MASK /* u8 */
  1075  
  1076  	TCA_FLOWER_KEY_ENC_OPTS
  1077  	TCA_FLOWER_KEY_ENC_OPTS_MASK
  1078  
  1079  	__TCA_FLOWER_MAX
  1080  )
  1081  
  1082  const TCA_CLS_FLAGS_SKIP_HW = 1 << 0 /* don't offload filter to HW */
  1083  const TCA_CLS_FLAGS_SKIP_SW = 1 << 1 /* don't use filter in SW */
  1084  
  1085  // struct tc_sfq_qopt {
  1086  // 	unsigned	quantum;	/* Bytes per round allocated to flow */
  1087  // 	int		perturb_period;	/* Period of hash perturbation */
  1088  // 	__u32		limit;		/* Maximal packets in queue */
  1089  // 	unsigned	divisor;	/* Hash divisor  */
  1090  // 	unsigned	flows;		/* Maximal number of flows  */
  1091  // };
  1092  
  1093  type TcSfqQopt struct {
  1094  	Quantum uint8
  1095  	Perturb int32
  1096  	Limit   uint32
  1097  	Divisor uint8
  1098  	Flows   uint8
  1099  }
  1100  
  1101  func (x *TcSfqQopt) Len() int {
  1102  	return SizeofTcSfqQopt
  1103  }
  1104  
  1105  func DeserializeTcSfqQopt(b []byte) *TcSfqQopt {
  1106  	return (*TcSfqQopt)(unsafe.Pointer(&b[0:SizeofTcSfqQopt][0]))
  1107  }
  1108  
  1109  func (x *TcSfqQopt) Serialize() []byte {
  1110  	return (*(*[SizeofTcSfqQopt]byte)(unsafe.Pointer(x)))[:]
  1111  }
  1112  
  1113  //	struct tc_sfqred_stats {
  1114  //		__u32           prob_drop;      /* Early drops, below max threshold */
  1115  //		__u32           forced_drop;	/* Early drops, after max threshold */
  1116  //		__u32           prob_mark;      /* Marked packets, below max threshold */
  1117  //		__u32           forced_mark;    /* Marked packets, after max threshold */
  1118  //		__u32           prob_mark_head; /* Marked packets, below max threshold */
  1119  //		__u32           forced_mark_head;/* Marked packets, after max threshold */
  1120  //	};
  1121  type TcSfqRedStats struct {
  1122  	ProbDrop       uint32
  1123  	ForcedDrop     uint32
  1124  	ProbMark       uint32
  1125  	ForcedMark     uint32
  1126  	ProbMarkHead   uint32
  1127  	ForcedMarkHead uint32
  1128  }
  1129  
  1130  func (x *TcSfqRedStats) Len() int {
  1131  	return SizeofTcSfqRedStats
  1132  }
  1133  
  1134  func DeserializeTcSfqRedStats(b []byte) *TcSfqRedStats {
  1135  	return (*TcSfqRedStats)(unsafe.Pointer(&b[0:SizeofTcSfqRedStats][0]))
  1136  }
  1137  
  1138  func (x *TcSfqRedStats) Serialize() []byte {
  1139  	return (*(*[SizeofTcSfqRedStats]byte)(unsafe.Pointer(x)))[:]
  1140  }
  1141  
  1142  //	struct tc_sfq_qopt_v1 {
  1143  //		struct tc_sfq_qopt v0;
  1144  //		unsigned int	depth;		/* max number of packets per flow */
  1145  //		unsigned int	headdrop;
  1146  //
  1147  // /* SFQRED parameters */
  1148  //
  1149  //	__u32		limit;		/* HARD maximal flow queue length (bytes) */
  1150  //	__u32		qth_min;	/* Min average length threshold (bytes) */
  1151  //	__u32		qth_max;	/* Max average length threshold (bytes) */
  1152  //	unsigned char   Wlog;		/* log(W)		*/
  1153  //	unsigned char   Plog;		/* log(P_max/(qth_max-qth_min))	*/
  1154  //	unsigned char   Scell_log;	/* cell size for idle damping */
  1155  //	unsigned char	flags;
  1156  //	__u32		max_P;		/* probability, high resolution */
  1157  //
  1158  // /* SFQRED stats */
  1159  //
  1160  //		struct tc_sfqred_stats stats;
  1161  //	};
  1162  type TcSfqQoptV1 struct {
  1163  	TcSfqQopt
  1164  	Depth    uint32
  1165  	HeadDrop uint32
  1166  	Limit    uint32
  1167  	QthMin   uint32
  1168  	QthMax   uint32
  1169  	Wlog     byte
  1170  	Plog     byte
  1171  	ScellLog byte
  1172  	Flags    byte
  1173  	MaxP     uint32
  1174  	TcSfqRedStats
  1175  }
  1176  
  1177  func (x *TcSfqQoptV1) Len() int {
  1178  	return SizeofTcSfqQoptV1
  1179  }
  1180  
  1181  func DeserializeTcSfqQoptV1(b []byte) *TcSfqQoptV1 {
  1182  	return (*TcSfqQoptV1)(unsafe.Pointer(&b[0:SizeofTcSfqQoptV1][0]))
  1183  }
  1184  
  1185  func (x *TcSfqQoptV1) Serialize() []byte {
  1186  	return (*(*[SizeofTcSfqQoptV1]byte)(unsafe.Pointer(x)))[:]
  1187  }
  1188  
  1189  // IPProto represents Flower ip_proto attribute
  1190  type IPProto uint8
  1191  
  1192  const (
  1193  	IPPROTO_TCP    IPProto = unix.IPPROTO_TCP
  1194  	IPPROTO_UDP    IPProto = unix.IPPROTO_UDP
  1195  	IPPROTO_SCTP   IPProto = unix.IPPROTO_SCTP
  1196  	IPPROTO_ICMP   IPProto = unix.IPPROTO_ICMP
  1197  	IPPROTO_ICMPV6 IPProto = unix.IPPROTO_ICMPV6
  1198  )
  1199  
  1200  func (i IPProto) Serialize() []byte {
  1201  	arr := make([]byte, 1)
  1202  	arr[0] = byte(i)
  1203  	return arr
  1204  }
  1205  
  1206  func (i IPProto) String() string {
  1207  	switch i {
  1208  	case IPPROTO_TCP:
  1209  		return "tcp"
  1210  	case IPPROTO_UDP:
  1211  		return "udp"
  1212  	case IPPROTO_SCTP:
  1213  		return "sctp"
  1214  	case IPPROTO_ICMP:
  1215  		return "icmp"
  1216  	case IPPROTO_ICMPV6:
  1217  		return "icmpv6"
  1218  	}
  1219  	return fmt.Sprintf("%d", i)
  1220  }
  1221  
  1222  const (
  1223  	MaxOffs        = 128
  1224  	SizeOfPeditSel = 24
  1225  	SizeOfPeditKey = 24
  1226  
  1227  	TCA_PEDIT_KEY_EX_HTYPE = 1
  1228  	TCA_PEDIT_KEY_EX_CMD   = 2
  1229  )
  1230  
  1231  const (
  1232  	TCA_PEDIT_UNSPEC = iota
  1233  	TCA_PEDIT_TM
  1234  	TCA_PEDIT_PARMS
  1235  	TCA_PEDIT_PAD
  1236  	TCA_PEDIT_PARMS_EX
  1237  	TCA_PEDIT_KEYS_EX
  1238  	TCA_PEDIT_KEY_EX
  1239  )
  1240  
  1241  // /* TCA_PEDIT_KEY_EX_HDR_TYPE_NETWROK is a special case for legacy users. It
  1242  //  * means no specific header type - offset is relative to the network layer
  1243  //  */
  1244  type PeditHeaderType uint16
  1245  
  1246  const (
  1247  	TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK = iota
  1248  	TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
  1249  	TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
  1250  	TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
  1251  	TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
  1252  	TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
  1253  	__PEDIT_HDR_TYPE_MAX
  1254  )
  1255  
  1256  type PeditCmd uint16
  1257  
  1258  const (
  1259  	TCA_PEDIT_KEY_EX_CMD_SET = 0
  1260  	TCA_PEDIT_KEY_EX_CMD_ADD = 1
  1261  )
  1262  
  1263  type TcPeditSel struct {
  1264  	TcGen
  1265  	NKeys uint8
  1266  	Flags uint8
  1267  }
  1268  
  1269  func DeserializeTcPeditKey(b []byte) *TcPeditKey {
  1270  	return (*TcPeditKey)(unsafe.Pointer(&b[0:SizeOfPeditKey][0]))
  1271  }
  1272  
  1273  func DeserializeTcPedit(b []byte) (*TcPeditSel, []TcPeditKey) {
  1274  	x := &TcPeditSel{}
  1275  	copy((*(*[SizeOfPeditSel]byte)(unsafe.Pointer(x)))[:SizeOfPeditSel], b)
  1276  
  1277  	var keys []TcPeditKey
  1278  
  1279  	next := SizeOfPeditKey
  1280  	var i uint8
  1281  	for i = 0; i < x.NKeys; i++ {
  1282  		keys = append(keys, *DeserializeTcPeditKey(b[next:]))
  1283  		next += SizeOfPeditKey
  1284  	}
  1285  
  1286  	return x, keys
  1287  }
  1288  
  1289  type TcPeditKey struct {
  1290  	Mask    uint32
  1291  	Val     uint32
  1292  	Off     uint32
  1293  	At      uint32
  1294  	OffMask uint32
  1295  	Shift   uint32
  1296  }
  1297  
  1298  type TcPeditKeyEx struct {
  1299  	HeaderType PeditHeaderType
  1300  	Cmd        PeditCmd
  1301  }
  1302  
  1303  type TcPedit struct {
  1304  	Sel    TcPeditSel
  1305  	Keys   []TcPeditKey
  1306  	KeysEx []TcPeditKeyEx
  1307  	Extend uint8
  1308  }
  1309  
  1310  func (p *TcPedit) Encode(parent *RtAttr) {
  1311  	parent.AddRtAttr(TCA_ACT_KIND, ZeroTerminated("pedit"))
  1312  	actOpts := parent.AddRtAttr(TCA_ACT_OPTIONS, nil)
  1313  
  1314  	bbuf := bytes.NewBuffer(make([]byte, 0, int(unsafe.Sizeof(p.Sel)+unsafe.Sizeof(p.Keys))))
  1315  
  1316  	bbuf.Write((*(*[SizeOfPeditSel]byte)(unsafe.Pointer(&p.Sel)))[:])
  1317  
  1318  	for i := uint8(0); i < p.Sel.NKeys; i++ {
  1319  		bbuf.Write((*(*[SizeOfPeditKey]byte)(unsafe.Pointer(&p.Keys[i])))[:])
  1320  	}
  1321  	actOpts.AddRtAttr(TCA_PEDIT_PARMS_EX, bbuf.Bytes())
  1322  
  1323  	exAttrs := actOpts.AddRtAttr(int(TCA_PEDIT_KEYS_EX|NLA_F_NESTED), nil)
  1324  	for i := uint8(0); i < p.Sel.NKeys; i++ {
  1325  		keyAttr := exAttrs.AddRtAttr(int(TCA_PEDIT_KEY_EX|NLA_F_NESTED), nil)
  1326  
  1327  		htypeBuf := make([]byte, 2)
  1328  		cmdBuf := make([]byte, 2)
  1329  
  1330  		NativeEndian().PutUint16(htypeBuf, uint16(p.KeysEx[i].HeaderType))
  1331  		NativeEndian().PutUint16(cmdBuf, uint16(p.KeysEx[i].Cmd))
  1332  
  1333  		keyAttr.AddRtAttr(TCA_PEDIT_KEY_EX_HTYPE, htypeBuf)
  1334  		keyAttr.AddRtAttr(TCA_PEDIT_KEY_EX_CMD, cmdBuf)
  1335  	}
  1336  }
  1337  
  1338  func (p *TcPedit) SetEthDst(mac net.HardwareAddr) {
  1339  	u32 := NativeEndian().Uint32(mac)
  1340  	u16 := NativeEndian().Uint16(mac[4:])
  1341  
  1342  	tKey := TcPeditKey{}
  1343  	tKeyEx := TcPeditKeyEx{}
  1344  
  1345  	tKey.Val = u32
  1346  
  1347  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
  1348  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1349  
  1350  	p.Keys = append(p.Keys, tKey)
  1351  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1352  	p.Sel.NKeys++
  1353  
  1354  	tKey = TcPeditKey{}
  1355  	tKeyEx = TcPeditKeyEx{}
  1356  
  1357  	tKey.Val = uint32(u16)
  1358  	tKey.Mask = 0xffff0000
  1359  	tKey.Off = 4
  1360  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
  1361  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1362  
  1363  	p.Keys = append(p.Keys, tKey)
  1364  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1365  
  1366  	p.Sel.NKeys++
  1367  }
  1368  
  1369  func (p *TcPedit) SetEthSrc(mac net.HardwareAddr) {
  1370  	u16 := NativeEndian().Uint16(mac)
  1371  	u32 := NativeEndian().Uint32(mac[2:])
  1372  
  1373  	tKey := TcPeditKey{}
  1374  	tKeyEx := TcPeditKeyEx{}
  1375  
  1376  	tKey.Val = uint32(u16) << 16
  1377  	tKey.Mask = 0x0000ffff
  1378  	tKey.Off = 4
  1379  
  1380  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
  1381  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1382  
  1383  	p.Keys = append(p.Keys, tKey)
  1384  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1385  	p.Sel.NKeys++
  1386  
  1387  	tKey = TcPeditKey{}
  1388  	tKeyEx = TcPeditKeyEx{}
  1389  
  1390  	tKey.Val = u32
  1391  	tKey.Mask = 0
  1392  	tKey.Off = 8
  1393  
  1394  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
  1395  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1396  
  1397  	p.Keys = append(p.Keys, tKey)
  1398  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1399  
  1400  	p.Sel.NKeys++
  1401  }
  1402  
  1403  func (p *TcPedit) SetIPv6Src(ip6 net.IP) {
  1404  	u32 := NativeEndian().Uint32(ip6[:4])
  1405  
  1406  	tKey := TcPeditKey{}
  1407  	tKeyEx := TcPeditKeyEx{}
  1408  
  1409  	tKey.Val = u32
  1410  	tKey.Off = 8
  1411  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
  1412  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1413  
  1414  	p.Keys = append(p.Keys, tKey)
  1415  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1416  	p.Sel.NKeys++
  1417  
  1418  	u32 = NativeEndian().Uint32(ip6[4:8])
  1419  	tKey = TcPeditKey{}
  1420  	tKeyEx = TcPeditKeyEx{}
  1421  
  1422  	tKey.Val = u32
  1423  	tKey.Off = 12
  1424  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
  1425  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1426  
  1427  	p.Keys = append(p.Keys, tKey)
  1428  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1429  
  1430  	p.Sel.NKeys++
  1431  
  1432  	u32 = NativeEndian().Uint32(ip6[8:12])
  1433  	tKey = TcPeditKey{}
  1434  	tKeyEx = TcPeditKeyEx{}
  1435  
  1436  	tKey.Val = u32
  1437  	tKey.Off = 16
  1438  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
  1439  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1440  
  1441  	p.Keys = append(p.Keys, tKey)
  1442  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1443  
  1444  	p.Sel.NKeys++
  1445  
  1446  	u32 = NativeEndian().Uint32(ip6[12:16])
  1447  	tKey = TcPeditKey{}
  1448  	tKeyEx = TcPeditKeyEx{}
  1449  
  1450  	tKey.Val = u32
  1451  	tKey.Off = 20
  1452  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
  1453  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1454  
  1455  	p.Keys = append(p.Keys, tKey)
  1456  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1457  
  1458  	p.Sel.NKeys++
  1459  }
  1460  
  1461  func (p *TcPedit) SetDstIP(ip net.IP) {
  1462  	if ip.To4() != nil {
  1463  		p.SetIPv4Dst(ip)
  1464  	} else {
  1465  		p.SetIPv6Dst(ip)
  1466  	}
  1467  }
  1468  
  1469  func (p *TcPedit) SetSrcIP(ip net.IP) {
  1470  	if ip.To4() != nil {
  1471  		p.SetIPv4Src(ip)
  1472  	} else {
  1473  		p.SetIPv6Src(ip)
  1474  	}
  1475  }
  1476  
  1477  func (p *TcPedit) SetIPv6Dst(ip6 net.IP) {
  1478  	u32 := NativeEndian().Uint32(ip6[:4])
  1479  
  1480  	tKey := TcPeditKey{}
  1481  	tKeyEx := TcPeditKeyEx{}
  1482  
  1483  	tKey.Val = u32
  1484  	tKey.Off = 24
  1485  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
  1486  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1487  
  1488  	p.Keys = append(p.Keys, tKey)
  1489  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1490  	p.Sel.NKeys++
  1491  
  1492  	u32 = NativeEndian().Uint32(ip6[4:8])
  1493  	tKey = TcPeditKey{}
  1494  	tKeyEx = TcPeditKeyEx{}
  1495  
  1496  	tKey.Val = u32
  1497  	tKey.Off = 28
  1498  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
  1499  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1500  
  1501  	p.Keys = append(p.Keys, tKey)
  1502  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1503  
  1504  	p.Sel.NKeys++
  1505  
  1506  	u32 = NativeEndian().Uint32(ip6[8:12])
  1507  	tKey = TcPeditKey{}
  1508  	tKeyEx = TcPeditKeyEx{}
  1509  
  1510  	tKey.Val = u32
  1511  	tKey.Off = 32
  1512  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
  1513  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1514  
  1515  	p.Keys = append(p.Keys, tKey)
  1516  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1517  
  1518  	p.Sel.NKeys++
  1519  
  1520  	u32 = NativeEndian().Uint32(ip6[12:16])
  1521  	tKey = TcPeditKey{}
  1522  	tKeyEx = TcPeditKeyEx{}
  1523  
  1524  	tKey.Val = u32
  1525  	tKey.Off = 36
  1526  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
  1527  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1528  
  1529  	p.Keys = append(p.Keys, tKey)
  1530  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1531  
  1532  	p.Sel.NKeys++
  1533  }
  1534  
  1535  func (p *TcPedit) SetIPv4Src(ip net.IP) {
  1536  	u32 := NativeEndian().Uint32(ip[:4])
  1537  
  1538  	tKey := TcPeditKey{}
  1539  	tKeyEx := TcPeditKeyEx{}
  1540  
  1541  	tKey.Val = u32
  1542  	tKey.Off = 12
  1543  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
  1544  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1545  
  1546  	p.Keys = append(p.Keys, tKey)
  1547  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1548  	p.Sel.NKeys++
  1549  }
  1550  
  1551  func (p *TcPedit) SetIPv4Dst(ip net.IP) {
  1552  	u32 := NativeEndian().Uint32(ip[:4])
  1553  
  1554  	tKey := TcPeditKey{}
  1555  	tKeyEx := TcPeditKeyEx{}
  1556  
  1557  	tKey.Val = u32
  1558  	tKey.Off = 16
  1559  	tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
  1560  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1561  
  1562  	p.Keys = append(p.Keys, tKey)
  1563  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1564  	p.Sel.NKeys++
  1565  }
  1566  
  1567  // SetDstPort only tcp and udp are supported to set port
  1568  func (p *TcPedit) SetDstPort(dstPort uint16, protocol uint8) {
  1569  	tKey := TcPeditKey{}
  1570  	tKeyEx := TcPeditKeyEx{}
  1571  
  1572  	switch protocol {
  1573  	case unix.IPPROTO_TCP:
  1574  		tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
  1575  	case unix.IPPROTO_UDP:
  1576  		tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
  1577  	default:
  1578  		return
  1579  	}
  1580  
  1581  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1582  
  1583  	tKey.Val = uint32(Swap16(dstPort)) << 16
  1584  	tKey.Mask = 0x0000ffff
  1585  	p.Keys = append(p.Keys, tKey)
  1586  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1587  	p.Sel.NKeys++
  1588  }
  1589  
  1590  // SetSrcPort only tcp and udp are supported to set port
  1591  func (p *TcPedit) SetSrcPort(srcPort uint16, protocol uint8) {
  1592  	tKey := TcPeditKey{}
  1593  	tKeyEx := TcPeditKeyEx{}
  1594  
  1595  	switch protocol {
  1596  	case unix.IPPROTO_TCP:
  1597  		tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
  1598  	case unix.IPPROTO_UDP:
  1599  		tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
  1600  	default:
  1601  		return
  1602  	}
  1603  
  1604  	tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
  1605  
  1606  	tKey.Val = uint32(Swap16(srcPort))
  1607  	tKey.Mask = 0xffff0000
  1608  	p.Keys = append(p.Keys, tKey)
  1609  	p.KeysEx = append(p.KeysEx, tKeyEx)
  1610  	p.Sel.NKeys++
  1611  }