blob: 0b0bf1592a6b9d01d7ba8f358e693ff886f4d759 [file] [log] [blame]
Rich Lanea06d0c32013-03-25 08:52:03 -07001:: # Copyright 2013, Big Switch Networks, Inc.
2:: #
3:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
4:: # the following special exception:
5:: #
6:: # LOXI Exception
7:: #
8:: # As a special exception to the terms of the EPL, you may distribute libraries
9:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
10:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
11:: # from the LoxiGen Libraries and the notice provided below is (i) included in
12:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
13:: # documentation for the LoxiGen Libraries, if distributed in binary form.
14:: #
15:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
16:: #
17:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
18:: # a copy of the EPL at:
19:: #
20:: # http://www.eclipse.org/legal/epl-v10.html
21:: #
22:: # Unless required by applicable law or agreed to in writing, software
23:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25:: # EPL for the specific language governing permissions and limitations
26:: # under the EPL.
27::
Rich Laned983aa52013-06-13 11:48:37 -070028:: include('_copyright.c')
Rich Lanea06d0c32013-03-25 08:52:03 -070029
30/****************************************************************
31 *
32 * Functions related to mapping wire values to object types
33 * and lengths
34 *
35 ****************************************************************/
36
37#include <loci/loci.h>
38#include <loci/of_message.h>
39
Rich Laneef7b9942013-11-18 16:29:28 -080040#define OF_INSTRUCTION_EXPERIMENTER_ID_OFFSET 4
41#define OF_INSTRUCTION_EXPERIMENTER_SUBTYPE_OFFSET 8
42
Rich Lanec0e20ff2013-12-15 23:40:31 -080043${legacy_code}
44
Rich Lanea06d0c32013-03-25 08:52:03 -070045/****************************************************************
46 * Top level OpenFlow message length functions
47 ****************************************************************/
48
49/**
50 * Get the length of a message object as reported on the wire
51 * @param obj The object to check
52 * @param bytes (out) Where the length is stored
53 * @returns OF_ERROR_ code
54 */
55void
56of_object_message_wire_length_get(of_object_t *obj, int *bytes)
57{
Rich Lanee57f0432014-02-19 10:31:53 -080058 LOCI_ASSERT(OF_OBJECT_TO_WBUF(obj) != NULL);
59 // LOCI_ASSERT(obj is message)
Rich Lanea06d0c32013-03-25 08:52:03 -070060 *bytes = of_message_length_get(OF_OBJECT_TO_MESSAGE(obj));
61}
62
63/**
64 * Set the length of a message object as reported on the wire
65 * @param obj The object to check
66 * @param bytes The new length of the object
67 * @returns OF_ERROR_ code
68 */
69void
70of_object_message_wire_length_set(of_object_t *obj, int bytes)
71{
Rich Lanee57f0432014-02-19 10:31:53 -080072 LOCI_ASSERT(OF_OBJECT_TO_WBUF(obj) != NULL);
73 // LOCI_ASSERT(obj is message)
Rich Lanea06d0c32013-03-25 08:52:03 -070074 of_message_length_set(OF_OBJECT_TO_MESSAGE(obj), bytes);
75}
76
77/****************************************************************
78 * TLV16 type/length functions
79 ****************************************************************/
80
81/**
82 * Many objects are TLVs and use uint16 for the type and length values
83 * stored on the wire at the beginning of the buffer.
84 */
85#define TLV16_WIRE_TYPE_OFFSET 0
86#define TLV16_WIRE_LENGTH_OFFSET 2
87
88/**
89 * Get the length field from the wire for a standard TLV
90 * object that uses uint16 for both type and length.
91 * @param obj The object being referenced
92 * @param bytes (out) Where to store the length
93 */
94
95void
96of_tlv16_wire_length_get(of_object_t *obj, int *bytes)
97{
98 uint16_t val16;
99 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800100 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700101
102 of_wire_buffer_u16_get(wbuf,
103 OF_OBJECT_ABSOLUTE_OFFSET(obj, TLV16_WIRE_LENGTH_OFFSET), &val16);
104 *bytes = val16;
105}
106
107/**
108 * Set the length field in the wire buffer for a standard TLV
109 * object that uses uint16 for both type and length.
110 * @param obj The object being referenced
111 * @param bytes The length value to use
112 */
113
114void
115of_tlv16_wire_length_set(of_object_t *obj, int bytes)
116{
117 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800118 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700119
120 of_wire_buffer_u16_set(wbuf,
121 OF_OBJECT_ABSOLUTE_OFFSET(obj, TLV16_WIRE_LENGTH_OFFSET), bytes);
122}
123
Rich Lane713d9282013-12-30 15:21:35 -0800124
Rich Lanea06d0c32013-03-25 08:52:03 -0700125/****************************************************************
126 * OXM type/length functions.
127 ****************************************************************/
128
129/* Where does the OXM type-length header lie in the buffer */
130#define OXM_HDR_OFFSET 0
131
132/**
133 * Get the OXM header (type-length fields) from the wire buffer
134 * associated with an OXM object
135 *
136 * Will return if error; set hdr to the OXM header
137 */
138
139#define _GET_OXM_TYPE_LEN(obj, tl_p, wbuf) do { \
140 wbuf = OF_OBJECT_TO_WBUF(obj); \
Rich Lanee57f0432014-02-19 10:31:53 -0800141 LOCI_ASSERT(wbuf != NULL); \
Rich Lanea06d0c32013-03-25 08:52:03 -0700142 of_wire_buffer_u32_get(wbuf, \
143 OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), (tl_p)); \
144 } while (0)
145
146#define _SET_OXM_TYPE_LEN(obj, tl_p, wbuf) do { \
147 wbuf = OF_OBJECT_TO_WBUF(obj); \
Rich Lanee57f0432014-02-19 10:31:53 -0800148 LOCI_ASSERT(wbuf != NULL); \
Rich Lanea06d0c32013-03-25 08:52:03 -0700149 of_wire_buffer_u32_set(wbuf, \
150 OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), (tl_p)); \
151 } while (0)
152
153/**
154 * Get the length of an OXM object from the wire buffer
155 * @param obj The object whose wire buffer is an OXM type
156 * @param bytes (out) Where length is stored
157 */
158
159void
160of_oxm_wire_length_get(of_object_t *obj, int *bytes)
161{
162 uint32_t type_len;
163 of_wire_buffer_t *wbuf;
164
165 _GET_OXM_TYPE_LEN(obj, &type_len, wbuf);
166 *bytes = OF_OXM_LENGTH_GET(type_len);
167}
168
Rich Lanea06d0c32013-03-25 08:52:03 -0700169#define OF_U16_LEN_LENGTH_OFFSET 0
170
171/**
172 * Get the wire length for an object with a uint16 length as first member
173 * @param obj The object being referenced
174 * @param bytes Pointer to location to store length
175 */
176void
177of_u16_len_wire_length_get(of_object_t *obj, int *bytes)
178{
179 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
180 uint16_t u16;
181
Rich Lanee57f0432014-02-19 10:31:53 -0800182 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700183
184 of_wire_buffer_u16_get(wbuf,
185 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_U16_LEN_LENGTH_OFFSET),
186 &u16);
187
188 *bytes = u16;
189}
190
191/**
192 * Set the wire length for an object with a uint16 length as first member
193 * @param obj The object being referenced
194 * @param bytes The length of the object
195 */
196
197void
198of_u16_len_wire_length_set(of_object_t *obj, int bytes)
199{
200 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800201 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700202
Rich Lanee57f0432014-02-19 10:31:53 -0800203 /* LOCI_ASSERT(obj is u16-len entry) */
Rich Lanea06d0c32013-03-25 08:52:03 -0700204
205 of_wire_buffer_u16_set(wbuf,
206 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_U16_LEN_LENGTH_OFFSET),
207 bytes);
208}
209
210
211#define OF_PACKET_QUEUE_LENGTH_OFFSET(ver) \
212 (((ver) >= OF_VERSION_1_2) ? 8 : 4)
213
214/**
215 * Get the wire length for a packet queue object
216 * @param obj The object being referenced
217 * @param bytes Pointer to location to store length
218 *
219 * The length is a uint16 at the offset indicated above
220 */
221void
222of_packet_queue_wire_length_get(of_object_t *obj, int *bytes)
223{
224 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
225 uint16_t u16;
226 int offset;
227
Rich Lanee57f0432014-02-19 10:31:53 -0800228 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700229
Rich Lanee57f0432014-02-19 10:31:53 -0800230 /* LOCI_ASSERT(obj is packet queue obj) */
Rich Lanea06d0c32013-03-25 08:52:03 -0700231 offset = OF_PACKET_QUEUE_LENGTH_OFFSET(obj->version);
232 of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, offset),
233 &u16);
234
235 *bytes = u16;
236}
237
238/**
239 * Set the wire length for a 1.2 packet queue object
240 * @param obj The object being referenced
241 * @param bytes The length of the object
242 *
243 * The length is a uint16 at the offset indicated above
244 */
245
246void
247of_packet_queue_wire_length_set(of_object_t *obj, int bytes)
248{
249 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
250 int offset;
251
Rich Lanee57f0432014-02-19 10:31:53 -0800252 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700253
Rich Lanee57f0432014-02-19 10:31:53 -0800254 /* LOCI_ASSERT(obj is packet queue obj) */
Rich Lanea06d0c32013-03-25 08:52:03 -0700255 offset = OF_PACKET_QUEUE_LENGTH_OFFSET(obj->version);
256 of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, offset),
257 bytes);
258}
259
260/**
261 * Get the wire length for a meter band stats list
262 * @param obj The object being referenced
263 * @param bytes Pointer to location to store length
264 *
265 * Must a meter_stats object as a parent
266 */
267
268void
269of_list_meter_band_stats_wire_length_get(of_object_t *obj, int *bytes)
270{
Rich Lanee57f0432014-02-19 10:31:53 -0800271 LOCI_ASSERT(obj->parent != NULL);
272 LOCI_ASSERT(obj->parent->object_id == OF_METER_STATS);
Rich Lanea06d0c32013-03-25 08:52:03 -0700273
274 /* We're counting on the parent being properly initialized already.
275 * The length is stored in a uint16 at offset 4 of the parent.
276 */
277 *bytes = obj->parent->length - OF_OBJECT_FIXED_LENGTH(obj->parent);
278}
279
280#define OF_METER_STATS_LENGTH_OFFSET 4
281
282/**
283 * Get/set the wire length for a meter stats object
284 * @param obj The object being referenced
285 * @param bytes Pointer to location to store length
286 *
287 * It's almost a TLV....
288 */
289
290void
291of_meter_stats_wire_length_get(of_object_t *obj, int *bytes)
292{
293 uint16_t val16;
294 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800295 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700296 of_wire_buffer_u16_get(wbuf,
297 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET),
298 &val16);
299 *bytes = val16;
300}
301
302void
303of_meter_stats_wire_length_set(of_object_t *obj, int bytes)
304{
305 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800306 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700307
308 of_wire_buffer_u16_set(wbuf,
309 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET), bytes);
310}
311
Rich Lane353a79f2013-11-13 10:39:56 -0800312int
313of_experimenter_stats_request_to_object_id(uint32_t experimenter, uint32_t subtype, int ver)
314{
315 switch (experimenter) {
316 case OF_EXPERIMENTER_ID_BSN:
317 switch (subtype) {
318 case 1: return OF_BSN_LACP_STATS_REQUEST;
Rich Lane713d9282013-12-30 15:21:35 -0800319 case 2: return OF_BSN_GENTABLE_ENTRY_DESC_STATS_REQUEST;
320 case 3: return OF_BSN_GENTABLE_ENTRY_STATS_REQUEST;
321 case 4: return OF_BSN_GENTABLE_DESC_STATS_REQUEST;
322 case 5: return OF_BSN_GENTABLE_BUCKET_STATS_REQUEST;
Wilson Ng45386fb2013-12-03 13:46:42 -0800323 case 6: return OF_BSN_SWITCH_PIPELINE_STATS_REQUEST;
Rich Lane713d9282013-12-30 15:21:35 -0800324 case 7: return OF_BSN_GENTABLE_STATS_REQUEST;
xinwu54ceaca2013-12-04 17:02:27 -0800325 case 8: return OF_BSN_PORT_COUNTER_STATS_REQUEST;
326 case 9: return OF_BSN_VLAN_COUNTER_STATS_REQUEST;
Rich Lane013dea02014-02-05 13:44:13 -0800327 case 10: return OF_BSN_FLOW_CHECKSUM_BUCKET_STATS_REQUEST;
328 case 11: return OF_BSN_TABLE_CHECKSUM_STATS_REQUEST;
Rich Lanec9461f12014-03-18 15:25:59 -0700329 case 12: return OF_BSN_DEBUG_COUNTER_STATS_REQUEST;
330 case 13: return OF_BSN_DEBUG_COUNTER_DESC_STATS_REQUEST;
Rich Lane353a79f2013-11-13 10:39:56 -0800331 }
332 }
333 return OF_OBJECT_INVALID;
334}
335
336int
337of_experimenter_stats_reply_to_object_id(uint32_t experimenter, uint32_t subtype, int ver)
338{
339 switch (experimenter) {
340 case OF_EXPERIMENTER_ID_BSN:
341 switch (subtype) {
342 case 1: return OF_BSN_LACP_STATS_REPLY;
Rich Lane713d9282013-12-30 15:21:35 -0800343 case 2: return OF_BSN_GENTABLE_ENTRY_DESC_STATS_REPLY;
344 case 3: return OF_BSN_GENTABLE_ENTRY_STATS_REPLY;
345 case 4: return OF_BSN_GENTABLE_DESC_STATS_REPLY;
346 case 5: return OF_BSN_GENTABLE_BUCKET_STATS_REPLY;
Wilson Ng45386fb2013-12-03 13:46:42 -0800347 case 6: return OF_BSN_SWITCH_PIPELINE_STATS_REPLY;
Rich Lane713d9282013-12-30 15:21:35 -0800348 case 7: return OF_BSN_GENTABLE_STATS_REPLY;
xinwu54ceaca2013-12-04 17:02:27 -0800349 case 8: return OF_BSN_PORT_COUNTER_STATS_REPLY;
350 case 9: return OF_BSN_VLAN_COUNTER_STATS_REPLY;
Rich Lane013dea02014-02-05 13:44:13 -0800351 case 10: return OF_BSN_FLOW_CHECKSUM_BUCKET_STATS_REPLY;
352 case 11: return OF_BSN_TABLE_CHECKSUM_STATS_REPLY;
Rich Lanec9461f12014-03-18 15:25:59 -0700353 case 12: return OF_BSN_DEBUG_COUNTER_STATS_REPLY;
354 case 13: return OF_BSN_DEBUG_COUNTER_DESC_STATS_REPLY;
Rich Lane353a79f2013-11-13 10:39:56 -0800355 }
356 }
357 return OF_OBJECT_INVALID;
358}