Skip to content

Commit 6b49ecc

Browse files
authored
Merge pull request #26 from GraysonWu/meter-action
Add meter mod
2 parents a487e95 + 3a787d9 commit 6b49ecc

File tree

1 file changed

+273
-0
lines changed

1 file changed

+273
-0
lines changed

openflow13/meter.go

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
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_BAND_HEADER_LEN = 12
29+
METER_BAND_LEN = 16
30+
)
31+
32+
type MeterBandHeader struct {
33+
Type uint16 /* One of OFPMBT13_*. */
34+
Length uint16 /* Length in bytes of this band. */
35+
Rate uint32 /* Rate for this band. */
36+
BurstSize uint32 /* Size of bursts. */
37+
}
38+
39+
func NewMeterBandHeader() *MeterBandHeader {
40+
return &MeterBandHeader{
41+
Length: METER_BAND_LEN,
42+
}
43+
}
44+
45+
func (m *MeterBandHeader) Len() (n uint16) {
46+
return METER_BAND_HEADER_LEN
47+
}
48+
49+
func (m *MeterBandHeader) MarshalBinary() (data []byte, err error) {
50+
data = make([]byte, m.Len())
51+
n := 0
52+
binary.BigEndian.PutUint16(data[n:], m.Type)
53+
n += 2
54+
binary.BigEndian.PutUint16(data[n:], m.Length)
55+
n += 2
56+
binary.BigEndian.PutUint32(data[n:], m.Rate)
57+
n += 4
58+
binary.BigEndian.PutUint32(data[n:], m.BurstSize)
59+
60+
return
61+
}
62+
63+
func (m *MeterBandHeader) UnmarshalBinary(data []byte) error {
64+
n := 0
65+
m.Type = binary.BigEndian.Uint16(data[n:])
66+
n += 2
67+
m.Length = binary.BigEndian.Uint16(data[n:])
68+
n += 2
69+
m.Rate = binary.BigEndian.Uint32(data[n:])
70+
n += 4
71+
m.BurstSize = binary.BigEndian.Uint32(data[n:])
72+
73+
return nil
74+
}
75+
76+
type MeterBandDrop struct {
77+
MeterBandHeader /* Type: OFPMBT13_DROP. */
78+
pad [4]uint8
79+
}
80+
81+
func (m *MeterBandDrop) Len() (n uint16) {
82+
return METER_BAND_LEN
83+
}
84+
85+
func (m *MeterBandDrop) MarshalBinary() (data []byte, err error) {
86+
data = make([]byte, m.Len())
87+
n := 0
88+
mbHdrBytes, err := m.MeterBandHeader.MarshalBinary()
89+
if err != nil {
90+
return nil, err
91+
}
92+
copy(data, mbHdrBytes)
93+
n += METER_BAND_HEADER_LEN
94+
return
95+
}
96+
97+
func (m *MeterBandDrop) UnmarshalBinary(data []byte) error {
98+
n := 0
99+
m.MeterBandHeader.UnmarshalBinary(data[n:])
100+
n += int(m.MeterBandHeader.Len())
101+
102+
return nil
103+
}
104+
105+
type MeterBandDSCP struct {
106+
MeterBandHeader /* Type: OFPMBT13_DSCP_REMARK. */
107+
PrecLevel uint8 /* Number of drop precedence level to add. */
108+
pad [3]uint8
109+
}
110+
111+
func (m *MeterBandDSCP) Len() (n uint16) {
112+
return METER_BAND_LEN
113+
}
114+
115+
func (m *MeterBandDSCP) MarshalBinary() (data []byte, err error) {
116+
data = make([]byte, m.Len())
117+
n := 0
118+
mbHdrBytes, err := m.MeterBandHeader.MarshalBinary()
119+
if err != nil {
120+
return nil, err
121+
}
122+
copy(data, mbHdrBytes)
123+
n += METER_BAND_HEADER_LEN
124+
data[n] = m.PrecLevel
125+
return
126+
}
127+
128+
func (m *MeterBandDSCP) UnmarshalBinary(data []byte) error {
129+
n := 0
130+
m.MeterBandHeader.UnmarshalBinary(data[n:])
131+
n += int(m.MeterBandHeader.Len())
132+
m.PrecLevel = data[n]
133+
134+
return nil
135+
}
136+
137+
type MeterBandExperimenter struct {
138+
MeterBandHeader /* Type: OFPMBT13_EXPERIMENTER. */
139+
Experimenter uint32 /* Experimenter ID which takes the same form as in struct ofp_experimenter_header. */
140+
}
141+
142+
func (m *MeterBandExperimenter) Len() (n uint16) {
143+
return METER_BAND_LEN
144+
}
145+
146+
func (m *MeterBandExperimenter) MarshalBinary() (data []byte, err error) {
147+
data = make([]byte, m.Len())
148+
n := 0
149+
mbHdrBytes, err := m.MeterBandHeader.MarshalBinary()
150+
if err != nil {
151+
return nil, err
152+
}
153+
copy(data, mbHdrBytes)
154+
n += METER_BAND_HEADER_LEN
155+
binary.BigEndian.PutUint32(data[n:], m.Experimenter)
156+
return
157+
}
158+
159+
func (m *MeterBandExperimenter) UnmarshalBinary(data []byte) error {
160+
n := 0
161+
m.MeterBandHeader.UnmarshalBinary(data[n:])
162+
n += int(m.MeterBandHeader.Len())
163+
m.Experimenter = binary.BigEndian.Uint32(data[n:])
164+
165+
return nil
166+
}
167+
168+
// MeterMod message
169+
type MeterMod struct {
170+
common.Header
171+
Command uint16 /* One of OFPMC_*. */
172+
Flags uint16 /* Set of OFPMF_*. */
173+
MeterId uint32 /* Meter instance. */
174+
MeterBands []util.Message /* List of MeterBand*. */
175+
}
176+
177+
// Create a new meter mod message
178+
func NewMeterMod() *MeterMod {
179+
m := new(MeterMod)
180+
m.Header = NewOfp13Header()
181+
m.Header.Type = Type_MeterMod
182+
m.MeterBands = make([]util.Message, 0)
183+
return m
184+
}
185+
186+
// Add a meterBand to meter mod
187+
func (m *MeterMod) AddMeterBand(mb util.Message) {
188+
m.MeterBands = append(m.MeterBands, mb)
189+
}
190+
191+
func (m *MeterMod) Len() (n uint16) {
192+
n = m.Header.Len()
193+
n += 8
194+
if m.Command == OFPMC_DELETE {
195+
return
196+
}
197+
198+
for _, b := range m.MeterBands {
199+
n += b.Len()
200+
}
201+
202+
return
203+
}
204+
205+
func (m *MeterMod) MarshalBinary() (data []byte, err error) {
206+
m.Header.Length = m.Len()
207+
data = make([]byte, m.Len())
208+
n := 0
209+
hdrBytes, err := m.Header.MarshalBinary()
210+
if err != nil {
211+
return nil, err
212+
}
213+
copy(data, hdrBytes)
214+
n += int(m.Header.Len())
215+
binary.BigEndian.PutUint16(data[n:], m.Command)
216+
n += 2
217+
binary.BigEndian.PutUint16(data[n:], m.Flags)
218+
n += 2
219+
binary.BigEndian.PutUint32(data[n:], m.MeterId)
220+
n += 4
221+
222+
for _, mb := range m.MeterBands {
223+
mbBytes, err := mb.MarshalBinary()
224+
if err != nil {
225+
return nil, err
226+
}
227+
copy(data[n:], mbBytes)
228+
n += METER_BAND_LEN
229+
log.Debugf("Metermod band: %v", mbBytes)
230+
}
231+
232+
log.Debugf("Metermod(%d): %v", len(data), data)
233+
234+
return
235+
}
236+
237+
func (m *MeterMod) UnmarshalBinary(data []byte) error {
238+
n := 0
239+
m.Header.UnmarshalBinary(data[n:])
240+
n += int(m.Header.Len())
241+
242+
m.Command = binary.BigEndian.Uint16(data[n:])
243+
n += 2
244+
m.Flags = binary.BigEndian.Uint16(data[n:])
245+
n += 2
246+
m.MeterId = binary.BigEndian.Uint32(data[n:])
247+
n += 4
248+
249+
for n < int(m.Header.Length) {
250+
mbh := new(MeterBandHeader)
251+
mbh.UnmarshalBinary(data[n:])
252+
n += int(mbh.Len())
253+
switch mbh.Type {
254+
case OFPMBT13_DROP:
255+
mbDrop := new(MeterBandDrop)
256+
mbDrop.MeterBandHeader = *mbh
257+
m.MeterBands = append(m.MeterBands, mbDrop)
258+
case OFPMBT13_DSCP_REMARK:
259+
mbDscp := new(MeterBandDSCP)
260+
mbDscp.MeterBandHeader = *mbh
261+
mbDscp.PrecLevel = data[n]
262+
m.MeterBands = append(m.MeterBands, mbDscp)
263+
case OFPMBT13_EXPERIMENTER:
264+
mbExp := new(MeterBandExperimenter)
265+
mbExp.MeterBandHeader = *mbh
266+
mbExp.Experimenter = binary.BigEndian.Uint32(data[n:])
267+
m.MeterBands = append(m.MeterBands, mbExp)
268+
}
269+
n += 4
270+
}
271+
272+
return nil
273+
}

0 commit comments

Comments
 (0)