github.com/contiv/libOpenflow@v0.0.0-20210609050114-d967b14cc688/openflow13/multipart.go (about)

     1  package openflow13
     2  
     3  import (
     4  	"encoding/binary"
     5  
     6  	log "github.com/sirupsen/logrus"
     7  
     8  	"github.com/contiv/libOpenflow/common"
     9  	"github.com/contiv/libOpenflow/util"
    10  )
    11  
    12  // ofp_multipart_request 1.3
    13  type MultipartRequest struct {
    14  	common.Header
    15  	Type  uint16
    16  	Flags uint16
    17  	pad   []byte // 4 bytes
    18  	Body  util.Message
    19  }
    20  
    21  func (s *MultipartRequest) Len() (n uint16) {
    22  	return s.Header.Len() + 8 + s.Body.Len()
    23  }
    24  
    25  func (s *MultipartRequest) MarshalBinary() (data []byte, err error) {
    26  	s.Header.Length = s.Len()
    27  	data, err = s.Header.MarshalBinary()
    28  
    29  	b := make([]byte, 8)
    30  	n := 0
    31  	binary.BigEndian.PutUint16(b[n:], s.Type)
    32  	n += 2
    33  	binary.BigEndian.PutUint16(b[n:], s.Flags)
    34  	n += 2
    35  	n += 4 // for padding
    36  	data = append(data, b...)
    37  
    38  	b, err = s.Body.MarshalBinary()
    39  	data = append(data, b...)
    40  
    41  	log.Debugf("Sending MultipartRequest (%d): %v", len(data), data)
    42  
    43  	return
    44  }
    45  
    46  func (s *MultipartRequest) UnmarshalBinary(data []byte) error {
    47  	err := s.Header.UnmarshalBinary(data)
    48  	n := s.Header.Len()
    49  
    50  	s.Type = binary.BigEndian.Uint16(data[n:])
    51  	n += 2
    52  	s.Flags = binary.BigEndian.Uint16(data[n:])
    53  	n += 2
    54  	n += 4 // for padding
    55  
    56  	var req util.Message
    57  	switch s.Type {
    58  	case MultipartType_Aggregate:
    59  		req = s.Body.(*AggregateStatsRequest)
    60  		err = req.UnmarshalBinary(data[n:])
    61  	case MultipartType_Desc:
    62  		break
    63  	case MultipartType_Flow:
    64  		req = s.Body.(*FlowStatsRequest)
    65  		err = req.UnmarshalBinary(data[n:])
    66  	case MultipartType_Port:
    67  		req = s.Body.(*PortStatsRequest)
    68  		err = req.UnmarshalBinary(data[n:])
    69  	case MultipartType_Table:
    70  		break
    71  	case MultipartType_Queue:
    72  		req = s.Body.(*QueueStatsRequest)
    73  		err = req.UnmarshalBinary(data[n:])
    74  	case MultipartType_Experimenter:
    75  		break
    76  	}
    77  	return err
    78  }
    79  
    80  // ofp_multipart_reply 1.3
    81  type MultipartReply struct {
    82  	common.Header
    83  	Type  uint16
    84  	Flags uint16
    85  	pad   []byte // 4 bytes
    86  	Body  []util.Message
    87  }
    88  
    89  func (s *MultipartReply) Len() (n uint16) {
    90  	n = s.Header.Len()
    91  	n += 8
    92  	for _, r := range s.Body {
    93  		n += uint16(r.Len())
    94  	}
    95  	return
    96  }
    97  
    98  func (s *MultipartReply) MarshalBinary() (data []byte, err error) {
    99  	s.Header.Length = s.Len()
   100  	data, err = s.Header.MarshalBinary()
   101  
   102  	b := make([]byte, 8)
   103  	n := 0
   104  	binary.BigEndian.PutUint16(b[n:], s.Type)
   105  	n += 2
   106  	binary.BigEndian.PutUint16(b[n:], s.Flags)
   107  	n += 2
   108  	n += 4 // for padding
   109  	data = append(data, b...)
   110  
   111  	for _, r := range s.Body {
   112  		b, err = r.MarshalBinary()
   113  		data = append(data, b...)
   114  	}
   115  
   116  	return
   117  }
   118  
   119  func (s *MultipartReply) UnmarshalBinary(data []byte) error {
   120  	err := s.Header.UnmarshalBinary(data)
   121  	n := s.Header.Len()
   122  
   123  	s.Type = binary.BigEndian.Uint16(data[n:])
   124  	n += 2
   125  	s.Flags = binary.BigEndian.Uint16(data[n:])
   126  	n += 2
   127  	n += 4 // for padding
   128  	var req []util.Message
   129  	for n < s.Header.Length {
   130  		var repl util.Message
   131  		switch s.Type {
   132  		case MultipartType_Aggregate:
   133  			repl = new(AggregateStats)
   134  		case MultipartType_Desc:
   135  			repl = new(DescStats)
   136  		case MultipartType_Flow:
   137  			repl = new(FlowStats)
   138  		case MultipartType_Port:
   139  			repl = new(PortStats)
   140  		case MultipartType_Table:
   141  			repl = new(TableStats)
   142  		case MultipartType_Queue:
   143  			repl = new(QueueStats)
   144  		// FIXME: Support all types
   145  		case MultipartType_Experimenter:
   146  			break
   147  		}
   148  
   149  		err = repl.UnmarshalBinary(data[n:])
   150  		if err != nil {
   151  			log.Printf("Error parsing stats reply")
   152  		}
   153  		n += repl.Len()
   154  		req = append(req, repl)
   155  
   156  	}
   157  
   158  	s.Body = req
   159  
   160  	return err
   161  }
   162  
   163  // ofp_multipart_request_flags & ofp_multipart_reply_flags 1.3
   164  const (
   165  	OFPMPF_REQ_MORE   = 1 << 0 /* More requests to follow. */
   166  	OFPMPF_REPLY_MORE = 1 << 0 /* More replies to follow. */
   167  )
   168  
   169  // _stats_types
   170  const (
   171  	/* Description of this OpenFlow switch.
   172  	 * The request body is empty.
   173  	 * The reply body is struct ofp_desc_stats. */
   174  	MultipartType_Desc = iota
   175  
   176  	/* Individual flow statistics.
   177  	 * The request body is struct ofp_flow_stats_request.
   178  	 * The reply body is an array of struct ofp_flow_stats. */
   179  	MultipartType_Flow
   180  
   181  	/* Aggregate flow statistics.
   182  	 * The request body is struct ofp_aggregate_stats_request.
   183  	 * The reply body is struct ofp_aggregate_stats_reply. */
   184  	MultipartType_Aggregate
   185  
   186  	/* Flow table statistics.
   187  	 * The request body is empty.
   188  	 * The reply body is an array of struct ofp_table_stats. */
   189  	MultipartType_Table
   190  
   191  	/* Port statistics.
   192  	 * The request body is struct ofp_port_stats_request.
   193  	 * The reply body is an array of struct ofp_port_stats. */
   194  	MultipartType_Port
   195  
   196  	/* Queue statistics for a port
   197  	 * The request body is struct _queue_stats_request.
   198  	 * The reply body is an array of struct ofp_queue_stats */
   199  	MultipartType_Queue
   200  
   201  	/* Group counter statistics.
   202  	 * The request body is struct ofp_group_stats_request.
   203  	 * The reply is an array of struct ofp_group_stats. */
   204  	MultipartType_Group
   205  
   206  	/* Group description.
   207  	 * The request body is empty.
   208  	 * The reply body is an array of struct ofp_group_desc. */
   209  	MultipartType_GroupDesc
   210  
   211  	/* Group features.
   212  	 * The request body is empty.
   213  	 * The reply body is struct ofp_group_features. */
   214  	MultipartType_GroupFeatures
   215  
   216  	/* Meter statistics.
   217  	 * The request body is struct ofp_meter_multipart_requests.
   218  	 * The reply body is an array of struct ofp_meter_stats. */
   219  	MultipartType_Meter
   220  
   221  	/* Meter configuration.
   222  	 * The request body is struct ofp_meter_multipart_requests.
   223  	 * The reply body is an array of struct ofp_meter_config. */
   224  	MultipartType_MeterConfig
   225  
   226  	/* Meter features.
   227  	 * The request body is empty.
   228  	 * The reply body is struct ofp_meter_features. */
   229  	MultipartType_MeterFeatures
   230  
   231  	/* Table features.
   232  	 * The request body is either empty or contains an array of
   233  	 * struct ofp_table_features containing the controller’s
   234  	 * desired view of the switch. If the switch is unable to
   235  	 * set the specified view an error is returned.
   236  	 * The reply body is an array of struct ofp_table_features. */
   237  	MultipartType_TableFeatures
   238  
   239  	/* Port description.
   240  	 * The request body is empty.
   241  	 * The reply body is an array of struct ofp_port. */
   242  	MultipartType_PortDesc
   243  
   244  	/* Experimenter extension.
   245  	 * The request and reply bodies begin with
   246  	 * struct ofp_experimenter_multipart_header.
   247  	 * The request and reply bodies are otherwise experimenter-defined. */
   248  	MultipartType_Experimenter = 0xffff
   249  )
   250  
   251  // ofp_desc_stats 1.3
   252  type DescStats struct {
   253  	MfrDesc   []byte // Size DESC_STR_LEN
   254  	HWDesc    []byte // Size DESC_STR_LEN
   255  	SWDesc    []byte // Size DESC_STR_LEN
   256  	SerialNum []byte // Size SERIAL_NUM_LEN
   257  	DPDesc    []byte // Size DESC_STR_LEN
   258  }
   259  
   260  func NewDescStats() *DescStats {
   261  	s := new(DescStats)
   262  	s.MfrDesc = make([]byte, DESC_STR_LEN)
   263  	s.HWDesc = make([]byte, DESC_STR_LEN)
   264  	s.SWDesc = make([]byte, DESC_STR_LEN)
   265  	s.SerialNum = make([]byte, SERIAL_NUM_LEN)
   266  	s.DPDesc = make([]byte, DESC_STR_LEN)
   267  	return s
   268  }
   269  
   270  func (s *DescStats) Len() (n uint16) {
   271  	return uint16(DESC_STR_LEN*4 + SERIAL_NUM_LEN)
   272  }
   273  
   274  func (s *DescStats) MarshalBinary() (data []byte, err error) {
   275  	data = make([]byte, int(s.Len()))
   276  	n := 0
   277  	copy(data[n:], s.MfrDesc)
   278  	n += len(s.MfrDesc)
   279  	copy(data[n:], s.HWDesc)
   280  	n += len(s.HWDesc)
   281  	copy(data[n:], s.SWDesc)
   282  	n += len(s.SWDesc)
   283  	copy(data[n:], s.SerialNum)
   284  	n += len(s.SerialNum)
   285  	copy(data[n:], s.DPDesc)
   286  	n += len(s.DPDesc)
   287  	return
   288  }
   289  
   290  func (s *DescStats) UnmarshalBinary(data []byte) error {
   291  	n := 0
   292  	copy(s.MfrDesc, data[n:])
   293  	n += len(s.MfrDesc)
   294  	copy(s.HWDesc, data[n:])
   295  	n += len(s.HWDesc)
   296  	copy(s.SWDesc, data[n:])
   297  	n += len(s.SWDesc)
   298  	copy(s.SerialNum, data[n:])
   299  	n += len(s.SerialNum)
   300  	copy(s.DPDesc, data[n:])
   301  	n += len(s.DPDesc)
   302  	return nil
   303  }
   304  
   305  const (
   306  	DESC_STR_LEN   = 256
   307  	SERIAL_NUM_LEN = 32
   308  )
   309  
   310  const (
   311  	OFPTT_MAX = 0xfe
   312  	/* Fake tables. */
   313  	OFPTT_ALL = 0xff /* Wildcard table used for table config, flow stats and flow deletes. */
   314  )
   315  
   316  // ofp_flow_stats_request 1.3
   317  type FlowStatsRequest struct {
   318  	TableId    uint8
   319  	pad        []byte // 3 bytes
   320  	OutPort    uint32
   321  	OutGroup   uint32
   322  	pad2       []byte // 4 bytes
   323  	Cookie     uint64
   324  	CookieMask uint64
   325  	Match      Match
   326  }
   327  
   328  func NewFlowStatsRequest() *FlowStatsRequest {
   329  	s := new(FlowStatsRequest)
   330  	s.OutPort = P_ANY
   331  	s.OutGroup = OFPG_ANY
   332  	s.pad = make([]byte, 3)
   333  	s.pad2 = make([]byte, 4)
   334  	s.Match = *NewMatch()
   335  	return s
   336  }
   337  
   338  func (s *FlowStatsRequest) Len() (n uint16) {
   339  	return s.Match.Len() + 32
   340  }
   341  
   342  func (s *FlowStatsRequest) MarshalBinary() (data []byte, err error) {
   343  	data = make([]byte, 32)
   344  	n := 0
   345  	data[n] = s.TableId
   346  	n += 1
   347  	copy(data[n:], s.pad)
   348  	n += 3
   349  	binary.BigEndian.PutUint32(data[n:], s.OutPort)
   350  	n += 4
   351  	binary.BigEndian.PutUint32(data[n:], s.OutGroup)
   352  	n += 4
   353  	copy(data[n:], s.pad2)
   354  	n += 4
   355  	binary.BigEndian.PutUint64(data[n:], s.Cookie)
   356  	n += 8
   357  	binary.BigEndian.PutUint64(data[n:], s.CookieMask)
   358  	n += 8
   359  
   360  	b, err := s.Match.MarshalBinary()
   361  	data = append(data, b...)
   362  	return
   363  }
   364  
   365  func (s *FlowStatsRequest) UnmarshalBinary(data []byte) error {
   366  	n := 0
   367  	s.TableId = data[n]
   368  	n += 1
   369  	copy(s.pad, data[n:n+3])
   370  	n += 3
   371  	s.OutPort = binary.BigEndian.Uint32(data[n:])
   372  	n += 4
   373  	s.OutGroup = binary.BigEndian.Uint32(data[n:])
   374  	n += 4
   375  	copy(s.pad2, data[n:n+4])
   376  	n += 4
   377  	s.Cookie = binary.BigEndian.Uint64(data[n:])
   378  	n += 8
   379  	s.CookieMask = binary.BigEndian.Uint64(data[n:])
   380  	n += 8
   381  
   382  	err := s.Match.UnmarshalBinary(data[n:])
   383  	n += int(s.Match.Len())
   384  
   385  	return err
   386  }
   387  
   388  // ofp_flow_stats 1.3
   389  type FlowStats struct {
   390  	Length       uint16
   391  	TableId      uint8
   392  	pad          uint8
   393  	DurationSec  uint32
   394  	DurationNSec uint32
   395  	Priority     uint16
   396  	IdleTimeout  uint16
   397  	HardTimeout  uint16
   398  	Flags        uint16
   399  	pad2         []uint8 // Size 4
   400  	Cookie       uint64
   401  	PacketCount  uint64
   402  	ByteCount    uint64
   403  	Match        Match
   404  	Instructions []Instruction
   405  }
   406  
   407  func NewFlowStats() *FlowStats {
   408  	f := new(FlowStats)
   409  	f.Match = *NewMatch()
   410  	f.pad2 = make([]byte, 4)
   411  	f.Instructions = make([]Instruction, 0)
   412  	return f
   413  }
   414  
   415  func (s *FlowStats) Len() (n uint16) {
   416  	n = 48 + s.Match.Len()
   417  	for _, instr := range s.Instructions {
   418  		n += instr.Len()
   419  	}
   420  	return
   421  }
   422  
   423  func (s *FlowStats) MarshalBinary() (data []byte, err error) {
   424  	data = make([]byte, 48)
   425  	n := 0
   426  
   427  	binary.BigEndian.PutUint16(data[n:], s.Length)
   428  	n += 2
   429  	data[n] = s.TableId
   430  	n += 1
   431  	data[n] = s.pad
   432  	n += 1
   433  
   434  	binary.BigEndian.PutUint32(data[n:], s.DurationSec)
   435  	n += 4
   436  	binary.BigEndian.PutUint32(data[n:], s.DurationNSec)
   437  	n += 4
   438  	binary.BigEndian.PutUint16(data[n:], s.Priority)
   439  	n += 2
   440  	binary.BigEndian.PutUint16(data[n:], s.IdleTimeout)
   441  	n += 2
   442  	binary.BigEndian.PutUint16(data[n:], s.HardTimeout)
   443  	n += 2
   444  	binary.BigEndian.PutUint16(data[n:], s.Flags)
   445  	n += 2
   446  	copy(data[n:], s.pad2)
   447  	n += len(s.pad2)
   448  	binary.BigEndian.PutUint64(data[n:], s.Cookie)
   449  	n += 8
   450  	binary.BigEndian.PutUint64(data[n:], s.PacketCount)
   451  	n += 8
   452  	binary.BigEndian.PutUint64(data[n:], s.ByteCount)
   453  	n += 8
   454  
   455  	b, err := s.Match.MarshalBinary()
   456  	data = append(data, b...)
   457  	n += len(b)
   458  
   459  	for _, instr := range s.Instructions {
   460  		b, err = instr.MarshalBinary()
   461  		data = append(data, b...)
   462  		n += len(b)
   463  	}
   464  	return
   465  }
   466  
   467  func (s *FlowStats) UnmarshalBinary(data []byte) error {
   468  	n := 0
   469  	s.Length = binary.BigEndian.Uint16(data[n:])
   470  	n += 2
   471  	s.TableId = data[n]
   472  	n += 1
   473  	s.pad = data[n]
   474  	n += 1
   475  	s.DurationSec = binary.BigEndian.Uint32(data[n:])
   476  	n += 4
   477  	s.DurationNSec = binary.BigEndian.Uint32(data[n:])
   478  	n += 4
   479  	s.Priority = binary.BigEndian.Uint16(data[n:])
   480  	n += 2
   481  	s.IdleTimeout = binary.BigEndian.Uint16(data[n:])
   482  	n += 2
   483  	s.HardTimeout = binary.BigEndian.Uint16(data[n:])
   484  	n += 2
   485  	s.Flags = binary.BigEndian.Uint16(data[n:])
   486  	n += 2
   487  	copy(s.pad2, data[n:n+4])
   488  	n += 4
   489  	s.Cookie = binary.BigEndian.Uint64(data[n:])
   490  	n += 8
   491  	s.PacketCount = binary.BigEndian.Uint64(data[n:])
   492  	n += 8
   493  	s.ByteCount = binary.BigEndian.Uint64(data[n:])
   494  	n += 8
   495  	err := s.Match.UnmarshalBinary(data[n:])
   496  	n += int(s.Match.Len())
   497  
   498  	for n < int(s.Length) {
   499  		instr := DecodeInstr(data[n:])
   500  		s.Instructions = append(s.Instructions, instr)
   501  		n += int(instr.Len())
   502  	}
   503  	return err
   504  }
   505  
   506  // ofp_aggregate_stats_request 1.3
   507  type AggregateStatsRequest struct {
   508  	TableId    uint8
   509  	pad        []byte // 3 bytes
   510  	OutPort    uint32
   511  	OutGroup   uint32
   512  	pad2       []byte // 4 bytes
   513  	Cookie     uint64
   514  	CookieMask uint64
   515  	Match
   516  }
   517  
   518  func NewAggregateStatsRequest() *AggregateStatsRequest {
   519  	a := new(AggregateStatsRequest)
   520  	a.pad = make([]byte, 3)
   521  	a.pad2 = make([]byte, 4)
   522  	a.Match = *NewMatch()
   523  
   524  	return a
   525  }
   526  
   527  func (s *AggregateStatsRequest) Len() (n uint16) {
   528  	return s.Match.Len() + 32
   529  }
   530  
   531  func (s *AggregateStatsRequest) MarshalBinary() (data []byte, err error) {
   532  	data = make([]byte, 32)
   533  	n := 0
   534  	data[n] = s.TableId
   535  	n += 1
   536  	copy(data[n:], s.pad)
   537  	n += 3
   538  	binary.BigEndian.PutUint32(data[n:], s.OutPort)
   539  	n += 4
   540  	binary.BigEndian.PutUint32(data[n:], s.OutGroup)
   541  	n += 4
   542  	copy(data[n:], s.pad2)
   543  	n += 4
   544  	binary.BigEndian.PutUint64(data[n:], s.Cookie)
   545  	n += 8
   546  	binary.BigEndian.PutUint64(data[n:], s.CookieMask)
   547  	n += 8
   548  
   549  	b, err := s.Match.MarshalBinary()
   550  	data = append(data, b...)
   551  	return
   552  }
   553  
   554  func (s *AggregateStatsRequest) UnmarshalBinary(data []byte) error {
   555  	n := 0
   556  	s.TableId = data[n]
   557  	n += 1
   558  	copy(s.pad, data[n:n+3])
   559  	n += 3
   560  	s.OutPort = binary.BigEndian.Uint32(data[n:])
   561  	n += 4
   562  	s.OutGroup = binary.BigEndian.Uint32(data[n:])
   563  	n += 4
   564  	copy(s.pad2, data[n:n+4])
   565  	n += 4
   566  	s.Cookie = binary.BigEndian.Uint64(data[n:])
   567  	n += 8
   568  	s.CookieMask = binary.BigEndian.Uint64(data[n:])
   569  	n += 8
   570  
   571  	s.Match.UnmarshalBinary(data[n:])
   572  	n += int(s.Match.Len())
   573  	return nil
   574  }
   575  
   576  // ofp_aggregate_stats_reply 1.3
   577  type AggregateStats struct {
   578  	PacketCount uint64
   579  	ByteCount   uint64
   580  	FlowCount   uint32
   581  	pad         []uint8 // Size 4
   582  }
   583  
   584  func NewAggregateStats() *AggregateStats {
   585  	s := new(AggregateStats)
   586  	s.pad = make([]byte, 4)
   587  	return s
   588  }
   589  
   590  func (s *AggregateStats) Len() (n uint16) {
   591  	return 24
   592  }
   593  
   594  func (s *AggregateStats) MarshalBinary() (data []byte, err error) {
   595  	data = make([]byte, int(s.Len()))
   596  	n := 0
   597  	binary.BigEndian.PutUint64(data[n:], s.PacketCount)
   598  	n += 8
   599  	binary.BigEndian.PutUint64(data[n:], s.ByteCount)
   600  	n += 8
   601  	binary.BigEndian.PutUint32(data[n:], s.FlowCount)
   602  	n += 4
   603  	copy(data[n:], s.pad)
   604  	n += 4
   605  	return
   606  }
   607  
   608  func (s *AggregateStats) UnmarshalBinary(data []byte) error {
   609  	n := 0
   610  	s.PacketCount = binary.BigEndian.Uint64(data[n:])
   611  	n += 8
   612  	s.ByteCount = binary.BigEndian.Uint64(data[n:])
   613  	n += 8
   614  	s.FlowCount = binary.BigEndian.Uint32(data[n:])
   615  	n += 4
   616  	copy(s.pad, data[n:])
   617  	return nil
   618  }
   619  
   620  // FIXME: Everything below this needs to be changed for ofp1.3
   621  // ofp_table_stats 1.0
   622  type TableStats struct {
   623  	TableId      uint8
   624  	pad          []uint8 // Size 3
   625  	Name         []byte  // Size MAX_TABLE_NAME_LEN
   626  	Wildcards    uint32
   627  	MaxEntries   uint32
   628  	ActiveCount  uint32
   629  	LookupCount  uint64
   630  	MatchedCount uint64
   631  }
   632  
   633  func NewTableStats() *TableStats {
   634  	s := new(TableStats)
   635  	s.pad = make([]byte, 3)
   636  	s.Name = make([]byte, MAX_TABLE_NAME_LEN)
   637  	return s
   638  }
   639  
   640  func (s *TableStats) Len() (n uint16) {
   641  	return 4 + MAX_TABLE_NAME_LEN + 28
   642  }
   643  
   644  func (s *TableStats) MarshalBinary() (data []byte, err error) {
   645  	data = make([]byte, int(s.Len()))
   646  	n := 0
   647  	data[n] = s.TableId
   648  	n += 1
   649  	copy(data[n:], s.pad)
   650  	n += len(s.pad)
   651  	copy(data[n:], s.Name)
   652  	n += len(s.Name)
   653  	binary.BigEndian.PutUint32(data[n:], s.Wildcards)
   654  	n += 4
   655  	binary.BigEndian.PutUint32(data[n:], s.MaxEntries)
   656  	n += 4
   657  	binary.BigEndian.PutUint32(data[n:], s.ActiveCount)
   658  	n += 4
   659  	binary.BigEndian.PutUint64(data[n:], s.LookupCount)
   660  	n += 8
   661  	binary.BigEndian.PutUint64(data[n:], s.MatchedCount)
   662  	n += 8
   663  	return
   664  }
   665  
   666  func (s *TableStats) UnmarshalBinary(data []byte) error {
   667  	n := 0
   668  	s.TableId = data[0]
   669  	n += 1
   670  	copy(s.pad, data[n:])
   671  	n += len(s.pad)
   672  	copy(s.Name, data[n:])
   673  	n += len(s.Name)
   674  	s.Wildcards = binary.BigEndian.Uint32(data[n:])
   675  	n += 4
   676  	s.MaxEntries = binary.BigEndian.Uint32(data[n:])
   677  	n += 4
   678  	s.ActiveCount = binary.BigEndian.Uint32(data[n:])
   679  	n += 4
   680  	s.LookupCount = binary.BigEndian.Uint64(data[n:])
   681  	n += 8
   682  	s.MatchedCount = binary.BigEndian.Uint64(data[n:])
   683  	n += 8
   684  	return nil
   685  }
   686  
   687  const (
   688  	MAX_TABLE_NAME_LEN = 32
   689  )
   690  
   691  // ofp_port_stats_request 1.0
   692  type PortStatsRequest struct {
   693  	PortNo uint16
   694  	pad    []uint8 // Size 6
   695  }
   696  
   697  func NewPortStatsRequest() *PortStatsRequest {
   698  	p := new(PortStatsRequest)
   699  	p.pad = make([]byte, 6)
   700  	return p
   701  }
   702  
   703  func (s *PortStatsRequest) Len() (n uint16) {
   704  	return 8
   705  }
   706  
   707  func (s *PortStatsRequest) MarshalBinary() (data []byte, err error) {
   708  	data = make([]byte, int(s.Len()))
   709  	n := 0
   710  	binary.BigEndian.PutUint16(data[n:], s.PortNo)
   711  	n += 2
   712  	copy(data[n:], s.pad)
   713  	n += len(s.pad)
   714  	return
   715  }
   716  
   717  func (s *PortStatsRequest) UnmarshalBinary(data []byte) error {
   718  	n := 0
   719  	s.PortNo = binary.BigEndian.Uint16(data[n:])
   720  	n += 2
   721  	copy(s.pad, data[n:])
   722  	n += len(s.pad)
   723  	return nil
   724  }
   725  
   726  // ofp_port_stats 1.0
   727  type PortStats struct {
   728  	PortNo     uint16
   729  	pad        []uint8 // Size 6
   730  	RxPackets  uint64
   731  	TxPackets  uint64
   732  	RxBytes    uint64
   733  	TxBytes    uint64
   734  	RxDropped  uint64
   735  	TxDropped  uint64
   736  	RxErrors   uint64
   737  	TxErrors   uint64
   738  	RxFrameErr uint64
   739  	RxOverErr  uint64
   740  	RxCRCErr   uint64
   741  	Collisions uint64
   742  }
   743  
   744  func NewPortStats() *PortStats {
   745  	p := new(PortStats)
   746  	p.pad = make([]byte, 6)
   747  	return p
   748  }
   749  
   750  func (s *PortStats) Len() (n uint16) {
   751  	return 104
   752  }
   753  
   754  func (s *PortStats) MarshalBinary() (data []byte, err error) {
   755  	data = make([]byte, int(s.Len()))
   756  	n := 0
   757  	binary.BigEndian.PutUint16(data[n:], s.PortNo)
   758  	n += 2
   759  	copy(data[n:], s.pad)
   760  	n += len(s.pad)
   761  	binary.BigEndian.PutUint64(data[n:], s.RxPackets)
   762  	n += 8
   763  	binary.BigEndian.PutUint64(data[n:], s.TxPackets)
   764  	n += 8
   765  	binary.BigEndian.PutUint64(data[n:], s.RxBytes)
   766  	n += 8
   767  	binary.BigEndian.PutUint64(data[n:], s.TxBytes)
   768  	n += 8
   769  	binary.BigEndian.PutUint64(data[n:], s.RxDropped)
   770  	n += 8
   771  	binary.BigEndian.PutUint64(data[n:], s.TxDropped)
   772  	n += 8
   773  	binary.BigEndian.PutUint64(data[n:], s.RxErrors)
   774  	n += 8
   775  	binary.BigEndian.PutUint64(data[n:], s.TxErrors)
   776  	n += 8
   777  	binary.BigEndian.PutUint64(data[n:], s.RxFrameErr)
   778  	n += 8
   779  	binary.BigEndian.PutUint64(data[n:], s.RxOverErr)
   780  	n += 8
   781  	binary.BigEndian.PutUint64(data[n:], s.RxCRCErr)
   782  	n += 8
   783  	binary.BigEndian.PutUint64(data[n:], s.Collisions)
   784  	n += 8
   785  	return
   786  }
   787  
   788  func (s *PortStats) UnmarshalBinary(data []byte) error {
   789  	n := 0
   790  	s.PortNo = binary.BigEndian.Uint16(data[n:])
   791  	n += 2
   792  	copy(s.pad, data[n:])
   793  	n += len(s.pad)
   794  	s.RxPackets = binary.BigEndian.Uint64(data[n:])
   795  	n += 8
   796  	s.TxPackets = binary.BigEndian.Uint64(data[n:])
   797  	n += 8
   798  	s.RxBytes = binary.BigEndian.Uint64(data[n:])
   799  	n += 8
   800  	s.TxBytes = binary.BigEndian.Uint64(data[n:])
   801  	n += 8
   802  	s.RxDropped = binary.BigEndian.Uint64(data[n:])
   803  	n += 8
   804  	s.TxDropped = binary.BigEndian.Uint64(data[n:])
   805  	n += 8
   806  	s.RxErrors = binary.BigEndian.Uint64(data[n:])
   807  	n += 8
   808  	s.TxErrors = binary.BigEndian.Uint64(data[n:])
   809  	n += 8
   810  	s.RxFrameErr = binary.BigEndian.Uint64(data[n:])
   811  	n += 8
   812  	s.RxOverErr = binary.BigEndian.Uint64(data[n:])
   813  	n += 8
   814  	s.RxCRCErr = binary.BigEndian.Uint64(data[n:])
   815  	n += 8
   816  	s.Collisions = binary.BigEndian.Uint64(data[n:])
   817  	n += 8
   818  	return nil
   819  }
   820  
   821  // ofp_queue_stats_request 1.0
   822  type QueueStatsRequest struct {
   823  	PortNo  uint16
   824  	pad     []uint8 // Size 2
   825  	QueueId uint32
   826  }
   827  
   828  func NewQueueStatsRequest() *QueueStatsRequest {
   829  	q := new(QueueStatsRequest)
   830  	q.pad = make([]byte, 2)
   831  	return q
   832  }
   833  
   834  func (s *QueueStatsRequest) Len() (n uint16) {
   835  	return 8
   836  }
   837  
   838  func (s *QueueStatsRequest) MarshalBinary() (data []byte, err error) {
   839  	data = make([]byte, int(s.Len()))
   840  	n := 0
   841  	binary.BigEndian.PutUint16(data[n:], s.PortNo)
   842  	n += 2
   843  	copy(data[n:], s.pad)
   844  	n += 2
   845  	binary.BigEndian.PutUint32(data[n:], s.QueueId)
   846  	n += 4
   847  	return
   848  }
   849  
   850  func (s *QueueStatsRequest) UnmarshalBinary(data []byte) error {
   851  	n := 0
   852  	s.PortNo = binary.BigEndian.Uint16(data[n:])
   853  	n += 2
   854  	copy(s.pad, data[n:])
   855  	n += 2
   856  	s.QueueId = binary.BigEndian.Uint32(data[n:])
   857  	return nil
   858  }
   859  
   860  // ofp_queue_stats 1.0
   861  type QueueStats struct {
   862  	PortNo    uint16
   863  	pad       []uint8 // Size 2
   864  	QueueId   uint32
   865  	TxBytes   uint64
   866  	TxPackets uint64
   867  	TxErrors  uint64
   868  }
   869  
   870  func (s *QueueStats) Len() (n uint16) {
   871  	return 32
   872  }
   873  
   874  func (s *QueueStats) MarshalBinary() (data []byte, err error) {
   875  	data = make([]byte, 32)
   876  	n := 0
   877  
   878  	binary.BigEndian.PutUint16(data[n:], s.PortNo)
   879  	n += 2
   880  	copy(data[n:], s.pad)
   881  	n += 2
   882  	binary.BigEndian.PutUint32(data[n:], s.QueueId)
   883  	n += 4
   884  	binary.BigEndian.PutUint64(data[n:], s.TxBytes)
   885  	n += 8
   886  	binary.BigEndian.PutUint64(data[n:], s.TxPackets)
   887  	n += 8
   888  	binary.BigEndian.PutUint64(data[n:], s.TxErrors)
   889  	n += 8
   890  	return
   891  }
   892  
   893  func (s *QueueStats) UnmarshalBinary(data []byte) error {
   894  	n := 0
   895  	s.PortNo = binary.BigEndian.Uint16(data[n:])
   896  	n += 2
   897  	copy(s.pad, data[n:])
   898  	n += len(s.pad)
   899  	s.QueueId = binary.BigEndian.Uint32(data[n:])
   900  	n += 4
   901  	s.TxBytes = binary.BigEndian.Uint64(data[n:])
   902  	n += 8
   903  	s.TxPackets = binary.BigEndian.Uint64(data[n:])
   904  	n += 8
   905  	s.TxErrors = binary.BigEndian.Uint64(data[n:])
   906  	n += 8
   907  	return nil
   908  }
   909  
   910  // ofp_port_status
   911  type PortStatus struct {
   912  	common.Header
   913  	Reason uint8
   914  	pad    []uint8 // Size 7
   915  	Desc   PhyPort
   916  }
   917  
   918  func NewPortStatus() *PortStatus {
   919  	p := new(PortStatus)
   920  	p.Header = NewOfp13Header()
   921  	p.pad = make([]byte, 7)
   922  	return p
   923  }
   924  
   925  func (p *PortStatus) Len() (n uint16) {
   926  	n = p.Header.Len()
   927  	n += 8
   928  	n += p.Desc.Len()
   929  	return
   930  }
   931  
   932  func (s *PortStatus) MarshalBinary() (data []byte, err error) {
   933  	s.Header.Length = s.Len()
   934  	data, err = s.Header.MarshalBinary()
   935  
   936  	b := make([]byte, 8)
   937  	n := 0
   938  	b[0] = s.Reason
   939  	n += 1
   940  	copy(b[n:], s.pad)
   941  	data = append(data, b...)
   942  
   943  	b, err = s.Desc.MarshalBinary()
   944  	data = append(data, b...)
   945  	return
   946  }
   947  
   948  func (s *PortStatus) UnmarshalBinary(data []byte) error {
   949  	err := s.Header.UnmarshalBinary(data)
   950  	n := int(s.Header.Len())
   951  
   952  	s.Reason = data[n]
   953  	n += 1
   954  	copy(s.pad, data[n:])
   955  	n += len(s.pad)
   956  
   957  	err = s.Desc.UnmarshalBinary(data[n:])
   958  	return err
   959  }
   960  
   961  // ofp_port_reason 1.0
   962  const (
   963  	PR_ADD = iota
   964  	PR_DELETE
   965  	PR_MODIFY
   966  )