Skip to content

Commit 41e3a0e

Browse files
committed
Add meter mod
Signed-off-by: wgrayson <[email protected]>
1 parent 27e68f0 commit 41e3a0e

File tree

1 file changed

+261
-0
lines changed

1 file changed

+261
-0
lines changed

openflow13/meter.go

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

0 commit comments

Comments
 (0)