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 }