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

     1  package openflow13
     2  
     3  // This file has all meter related defs
     4  
     5  import (
     6  	"encoding/binary"
     7  
     8  	log "github.com/sirupsen/logrus"
     9  
    10  	"github.com/contiv/libOpenflow/common"
    11  	"github.com/contiv/libOpenflow/util"
    12  )
    13  
    14  const (
    15  	OFPMBT13_DROP         = 1      /* Drop packet. */
    16  	OFPMBT13_DSCP_REMARK  = 2      /* Remark DSCP in the IP header. */
    17  	OFPMBT13_EXPERIMENTER = 0xFFFF /* Experimenter meter band. */
    18  
    19  	OFPMC_ADD    = 0 /* New meter. */
    20  	OFPMC_MODIFY = 1 /* Modify specified meter. */
    21  	OFPMC_DELETE = 2 /* Delete specified meter. */
    22  
    23  	OFPMF13_KBPS  = 0b0001 /* Rate value in kb/s (kilo-bit per second). */
    24  	OFPMF13_PKTPS = 0b0010 /* Rate value in packet/sec. */
    25  	OFPMF13_BURST = 0b0100 /* Do burst size. */
    26  	OFPMF13_STATS = 0b1000 /* Collect statistics. */
    27  
    28  	/* Meter numbering. Flow meters can use any number up to OFPM_MAX. */
    29  	OFPM13_MAX        = 0xffff0000 /* Last usable meter. */
    30  	OFPM13_SLOWPATH   = 0xfffffffd /* Meter for slow datapath. */
    31  	OFPM13_CONTROLLER = 0xfffffffe /* Meter for controller connection. */
    32  	OFPM13_ALL        = 0xffffffff /* Represents all meters for stat requests commands. */
    33  
    34  	METER_BAND_HEADER_LEN = 12
    35  	METER_BAND_LEN        = 16
    36  )
    37  
    38  type MeterBandHeader struct {
    39  	Type      uint16 /* One of OFPMBT13_*. */
    40  	Length    uint16 /* Length in bytes of this band. */
    41  	Rate      uint32 /* Rate for this band. */
    42  	BurstSize uint32 /* Size of bursts. */
    43  }
    44  
    45  func NewMeterBandHeader() *MeterBandHeader {
    46  	return &MeterBandHeader{
    47  		Length: METER_BAND_LEN,
    48  	}
    49  }
    50  
    51  func (m *MeterBandHeader) Len() (n uint16) {
    52  	return METER_BAND_HEADER_LEN
    53  }
    54  
    55  func (m *MeterBandHeader) MarshalBinary() (data []byte, err error) {
    56  	data = make([]byte, m.Len())
    57  	n := 0
    58  	binary.BigEndian.PutUint16(data[n:], m.Type)
    59  	n += 2
    60  	binary.BigEndian.PutUint16(data[n:], m.Length)
    61  	n += 2
    62  	binary.BigEndian.PutUint32(data[n:], m.Rate)
    63  	n += 4
    64  	binary.BigEndian.PutUint32(data[n:], m.BurstSize)
    65  
    66  	return
    67  }
    68  
    69  func (m *MeterBandHeader) UnmarshalBinary(data []byte) error {
    70  	n := 0
    71  	m.Type = binary.BigEndian.Uint16(data[n:])
    72  	n += 2
    73  	m.Length = binary.BigEndian.Uint16(data[n:])
    74  	n += 2
    75  	m.Rate = binary.BigEndian.Uint32(data[n:])
    76  	n += 4
    77  	m.BurstSize = binary.BigEndian.Uint32(data[n:])
    78  
    79  	return nil
    80  }
    81  
    82  type MeterBandDrop struct {
    83  	MeterBandHeader /* Type: OFPMBT13_DROP. */
    84  	pad             [4]uint8
    85  }
    86  
    87  func (m *MeterBandDrop) Len() (n uint16) {
    88  	return METER_BAND_LEN
    89  }
    90  
    91  func (m *MeterBandDrop) MarshalBinary() (data []byte, err error) {
    92  	data = make([]byte, m.Len())
    93  	n := 0
    94  	mbHdrBytes, err := m.MeterBandHeader.MarshalBinary()
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	copy(data, mbHdrBytes)
    99  	n += METER_BAND_HEADER_LEN
   100  	return
   101  }
   102  
   103  func (m *MeterBandDrop) UnmarshalBinary(data []byte) error {
   104  	n := 0
   105  	m.MeterBandHeader.UnmarshalBinary(data[n:])
   106  	n += int(m.MeterBandHeader.Len())
   107  
   108  	return nil
   109  }
   110  
   111  type MeterBandDSCP struct {
   112  	MeterBandHeader       /* Type: OFPMBT13_DSCP_REMARK. */
   113  	PrecLevel       uint8 /* Number of drop precedence level to add. */
   114  	pad             [3]uint8
   115  }
   116  
   117  func (m *MeterBandDSCP) Len() (n uint16) {
   118  	return METER_BAND_LEN
   119  }
   120  
   121  func (m *MeterBandDSCP) MarshalBinary() (data []byte, err error) {
   122  	data = make([]byte, m.Len())
   123  	n := 0
   124  	mbHdrBytes, err := m.MeterBandHeader.MarshalBinary()
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  	copy(data, mbHdrBytes)
   129  	n += METER_BAND_HEADER_LEN
   130  	data[n] = m.PrecLevel
   131  	return
   132  }
   133  
   134  func (m *MeterBandDSCP) UnmarshalBinary(data []byte) error {
   135  	n := 0
   136  	m.MeterBandHeader.UnmarshalBinary(data[n:])
   137  	n += int(m.MeterBandHeader.Len())
   138  	m.PrecLevel = data[n]
   139  
   140  	return nil
   141  }
   142  
   143  type MeterBandExperimenter struct {
   144  	MeterBandHeader        /* Type: OFPMBT13_EXPERIMENTER. */
   145  	Experimenter    uint32 /* Experimenter ID which takes the same form as in struct ofp_experimenter_header. */
   146  }
   147  
   148  func (m *MeterBandExperimenter) Len() (n uint16) {
   149  	return METER_BAND_LEN
   150  }
   151  
   152  func (m *MeterBandExperimenter) MarshalBinary() (data []byte, err error) {
   153  	data = make([]byte, m.Len())
   154  	n := 0
   155  	mbHdrBytes, err := m.MeterBandHeader.MarshalBinary()
   156  	if err != nil {
   157  		return nil, err
   158  	}
   159  	copy(data, mbHdrBytes)
   160  	n += METER_BAND_HEADER_LEN
   161  	binary.BigEndian.PutUint32(data[n:], m.Experimenter)
   162  	return
   163  }
   164  
   165  func (m *MeterBandExperimenter) UnmarshalBinary(data []byte) error {
   166  	n := 0
   167  	m.MeterBandHeader.UnmarshalBinary(data[n:])
   168  	n += int(m.MeterBandHeader.Len())
   169  	m.Experimenter = binary.BigEndian.Uint32(data[n:])
   170  
   171  	return nil
   172  }
   173  
   174  // MeterMod message
   175  type MeterMod struct {
   176  	common.Header
   177  	Command    uint16         /* One of OFPMC_*. */
   178  	Flags      uint16         /* Set of OFPMF_*. */
   179  	MeterId    uint32         /* Meter instance. */
   180  	MeterBands []util.Message /* List of MeterBand*. */
   181  }
   182  
   183  // Create a new meter mod message
   184  func NewMeterMod() *MeterMod {
   185  	m := new(MeterMod)
   186  	m.Header = NewOfp13Header()
   187  	m.Header.Type = Type_MeterMod
   188  	m.MeterBands = make([]util.Message, 0)
   189  	return m
   190  }
   191  
   192  // Add a meterBand to meter mod
   193  func (m *MeterMod) AddMeterBand(mb util.Message) {
   194  	m.MeterBands = append(m.MeterBands, mb)
   195  }
   196  
   197  func (m *MeterMod) Len() (n uint16) {
   198  	n = m.Header.Len()
   199  	n += 8
   200  	if m.Command == OFPMC_DELETE {
   201  		return
   202  	}
   203  
   204  	for _, b := range m.MeterBands {
   205  		n += b.Len()
   206  	}
   207  
   208  	return
   209  }
   210  
   211  func (m *MeterMod) MarshalBinary() (data []byte, err error) {
   212  	m.Header.Length = m.Len()
   213  	data = make([]byte, m.Len())
   214  	n := 0
   215  	hdrBytes, err := m.Header.MarshalBinary()
   216  	if err != nil {
   217  		return nil, err
   218  	}
   219  	copy(data, hdrBytes)
   220  	n += int(m.Header.Len())
   221  	binary.BigEndian.PutUint16(data[n:], m.Command)
   222  	n += 2
   223  	binary.BigEndian.PutUint16(data[n:], m.Flags)
   224  	n += 2
   225  	binary.BigEndian.PutUint32(data[n:], m.MeterId)
   226  	n += 4
   227  
   228  	for _, mb := range m.MeterBands {
   229  		mbBytes, err := mb.MarshalBinary()
   230  		if err != nil {
   231  			return nil, err
   232  		}
   233  		copy(data[n:], mbBytes)
   234  		n += METER_BAND_LEN
   235  		log.Debugf("Metermod band: %v", mbBytes)
   236  	}
   237  
   238  	log.Debugf("Metermod(%d): %v", len(data), data)
   239  
   240  	return
   241  }
   242  
   243  func (m *MeterMod) UnmarshalBinary(data []byte) error {
   244  	n := 0
   245  	m.Header.UnmarshalBinary(data[n:])
   246  	n += int(m.Header.Len())
   247  
   248  	m.Command = binary.BigEndian.Uint16(data[n:])
   249  	n += 2
   250  	m.Flags = binary.BigEndian.Uint16(data[n:])
   251  	n += 2
   252  	m.MeterId = binary.BigEndian.Uint32(data[n:])
   253  	n += 4
   254  
   255  	for n < int(m.Header.Length) {
   256  		mbh := new(MeterBandHeader)
   257  		mbh.UnmarshalBinary(data[n:])
   258  		n += int(mbh.Len())
   259  		switch mbh.Type {
   260  		case OFPMBT13_DROP:
   261  			mbDrop := new(MeterBandDrop)
   262  			mbDrop.MeterBandHeader = *mbh
   263  			m.MeterBands = append(m.MeterBands, mbDrop)
   264  		case OFPMBT13_DSCP_REMARK:
   265  			mbDscp := new(MeterBandDSCP)
   266  			mbDscp.MeterBandHeader = *mbh
   267  			mbDscp.PrecLevel = data[n]
   268  			m.MeterBands = append(m.MeterBands, mbDscp)
   269  		case OFPMBT13_EXPERIMENTER:
   270  			mbExp := new(MeterBandExperimenter)
   271  			mbExp.MeterBandHeader = *mbh
   272  			mbExp.Experimenter = binary.BigEndian.Uint32(data[n:])
   273  			m.MeterBands = append(m.MeterBands, mbExp)
   274  		}
   275  		n += 4
   276  	}
   277  
   278  	return nil
   279  }