blob: 3fcf024ba30cbfa649a81335effdc6c9a310d490 [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 Lanec0e20ff2013-12-15 23:40:31 -080040${legacy_code}
41
Rich Lanea06d0c32013-03-25 08:52:03 -070042/****************************************************************
43 * Top level OpenFlow message length functions
44 ****************************************************************/
45
46/**
47 * Get the length of a message object as reported on the wire
48 * @param obj The object to check
49 * @param bytes (out) Where the length is stored
50 * @returns OF_ERROR_ code
51 */
52void
53of_object_message_wire_length_get(of_object_t *obj, int *bytes)
54{
Rich Lanee57f0432014-02-19 10:31:53 -080055 LOCI_ASSERT(OF_OBJECT_TO_WBUF(obj) != NULL);
56 // LOCI_ASSERT(obj is message)
Rich Lanea06d0c32013-03-25 08:52:03 -070057 *bytes = of_message_length_get(OF_OBJECT_TO_MESSAGE(obj));
58}
59
60/**
61 * Set the length of a message object as reported on the wire
62 * @param obj The object to check
63 * @param bytes The new length of the object
64 * @returns OF_ERROR_ code
65 */
66void
67of_object_message_wire_length_set(of_object_t *obj, int bytes)
68{
Rich Lanee57f0432014-02-19 10:31:53 -080069 LOCI_ASSERT(OF_OBJECT_TO_WBUF(obj) != NULL);
70 // LOCI_ASSERT(obj is message)
Rich Lanea06d0c32013-03-25 08:52:03 -070071 of_message_length_set(OF_OBJECT_TO_MESSAGE(obj), bytes);
72}
73
74/****************************************************************
75 * TLV16 type/length functions
76 ****************************************************************/
77
78/**
79 * Many objects are TLVs and use uint16 for the type and length values
80 * stored on the wire at the beginning of the buffer.
81 */
82#define TLV16_WIRE_TYPE_OFFSET 0
83#define TLV16_WIRE_LENGTH_OFFSET 2
84
85/**
86 * Get the length field from the wire for a standard TLV
87 * object that uses uint16 for both type and length.
88 * @param obj The object being referenced
89 * @param bytes (out) Where to store the length
90 */
91
92void
93of_tlv16_wire_length_get(of_object_t *obj, int *bytes)
94{
95 uint16_t val16;
96 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -080097 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -070098
99 of_wire_buffer_u16_get(wbuf,
100 OF_OBJECT_ABSOLUTE_OFFSET(obj, TLV16_WIRE_LENGTH_OFFSET), &val16);
101 *bytes = val16;
102}
103
104/**
105 * Set the length field in the wire buffer for a standard TLV
106 * object that uses uint16 for both type and length.
107 * @param obj The object being referenced
108 * @param bytes The length value to use
109 */
110
111void
112of_tlv16_wire_length_set(of_object_t *obj, int bytes)
113{
114 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800115 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700116
117 of_wire_buffer_u16_set(wbuf,
118 OF_OBJECT_ABSOLUTE_OFFSET(obj, TLV16_WIRE_LENGTH_OFFSET), bytes);
119}
120
Rich Lane713d9282013-12-30 15:21:35 -0800121
Rich Lanea06d0c32013-03-25 08:52:03 -0700122/****************************************************************
123 * OXM type/length functions.
124 ****************************************************************/
125
126/* Where does the OXM type-length header lie in the buffer */
127#define OXM_HDR_OFFSET 0
128
129/**
130 * Get the OXM header (type-length fields) from the wire buffer
131 * associated with an OXM object
132 *
133 * Will return if error; set hdr to the OXM header
134 */
135
136#define _GET_OXM_TYPE_LEN(obj, tl_p, wbuf) do { \
137 wbuf = OF_OBJECT_TO_WBUF(obj); \
Rich Lanee57f0432014-02-19 10:31:53 -0800138 LOCI_ASSERT(wbuf != NULL); \
Rich Lanea06d0c32013-03-25 08:52:03 -0700139 of_wire_buffer_u32_get(wbuf, \
140 OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), (tl_p)); \
141 } while (0)
142
143#define _SET_OXM_TYPE_LEN(obj, tl_p, wbuf) do { \
144 wbuf = OF_OBJECT_TO_WBUF(obj); \
Rich Lanee57f0432014-02-19 10:31:53 -0800145 LOCI_ASSERT(wbuf != NULL); \
Rich Lanea06d0c32013-03-25 08:52:03 -0700146 of_wire_buffer_u32_set(wbuf, \
147 OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), (tl_p)); \
148 } while (0)
149
150/**
151 * Get the length of an OXM object from the wire buffer
152 * @param obj The object whose wire buffer is an OXM type
153 * @param bytes (out) Where length is stored
154 */
155
156void
157of_oxm_wire_length_get(of_object_t *obj, int *bytes)
158{
159 uint32_t type_len;
160 of_wire_buffer_t *wbuf;
161
162 _GET_OXM_TYPE_LEN(obj, &type_len, wbuf);
163 *bytes = OF_OXM_LENGTH_GET(type_len);
164}
165
Rich Lanea06d0c32013-03-25 08:52:03 -0700166#define OF_U16_LEN_LENGTH_OFFSET 0
167
168/**
169 * Get the wire length for an object with a uint16 length as first member
170 * @param obj The object being referenced
171 * @param bytes Pointer to location to store length
172 */
173void
174of_u16_len_wire_length_get(of_object_t *obj, int *bytes)
175{
176 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
177 uint16_t u16;
178
Rich Lanee57f0432014-02-19 10:31:53 -0800179 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700180
181 of_wire_buffer_u16_get(wbuf,
182 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_U16_LEN_LENGTH_OFFSET),
183 &u16);
184
185 *bytes = u16;
186}
187
188/**
189 * Set the wire length for an object with a uint16 length as first member
190 * @param obj The object being referenced
191 * @param bytes The length of the object
192 */
193
194void
195of_u16_len_wire_length_set(of_object_t *obj, int bytes)
196{
197 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800198 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700199
Rich Lanee57f0432014-02-19 10:31:53 -0800200 /* LOCI_ASSERT(obj is u16-len entry) */
Rich Lanea06d0c32013-03-25 08:52:03 -0700201
202 of_wire_buffer_u16_set(wbuf,
203 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_U16_LEN_LENGTH_OFFSET),
204 bytes);
205}
206
207
208#define OF_PACKET_QUEUE_LENGTH_OFFSET(ver) \
209 (((ver) >= OF_VERSION_1_2) ? 8 : 4)
210
211/**
212 * Get the wire length for a packet queue object
213 * @param obj The object being referenced
214 * @param bytes Pointer to location to store length
215 *
216 * The length is a uint16 at the offset indicated above
217 */
218void
219of_packet_queue_wire_length_get(of_object_t *obj, int *bytes)
220{
221 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
222 uint16_t u16;
223 int offset;
224
Rich Lanee57f0432014-02-19 10:31:53 -0800225 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700226
Rich Lanee57f0432014-02-19 10:31:53 -0800227 /* LOCI_ASSERT(obj is packet queue obj) */
Rich Lanea06d0c32013-03-25 08:52:03 -0700228 offset = OF_PACKET_QUEUE_LENGTH_OFFSET(obj->version);
229 of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, offset),
230 &u16);
231
232 *bytes = u16;
233}
234
235/**
236 * Set the wire length for a 1.2 packet queue object
237 * @param obj The object being referenced
238 * @param bytes The length of the object
239 *
240 * The length is a uint16 at the offset indicated above
241 */
242
243void
244of_packet_queue_wire_length_set(of_object_t *obj, int bytes)
245{
246 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
247 int offset;
248
Rich Lanee57f0432014-02-19 10:31:53 -0800249 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700250
Rich Lanee57f0432014-02-19 10:31:53 -0800251 /* LOCI_ASSERT(obj is packet queue obj) */
Rich Lanea06d0c32013-03-25 08:52:03 -0700252 offset = OF_PACKET_QUEUE_LENGTH_OFFSET(obj->version);
253 of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, offset),
254 bytes);
255}
256
257/**
258 * Get the wire length for a meter band stats list
259 * @param obj The object being referenced
260 * @param bytes Pointer to location to store length
261 *
262 * Must a meter_stats object as a parent
263 */
264
265void
266of_list_meter_band_stats_wire_length_get(of_object_t *obj, int *bytes)
267{
Rich Lanee57f0432014-02-19 10:31:53 -0800268 LOCI_ASSERT(obj->parent != NULL);
269 LOCI_ASSERT(obj->parent->object_id == OF_METER_STATS);
Rich Lanea06d0c32013-03-25 08:52:03 -0700270
271 /* We're counting on the parent being properly initialized already.
272 * The length is stored in a uint16 at offset 4 of the parent.
273 */
274 *bytes = obj->parent->length - OF_OBJECT_FIXED_LENGTH(obj->parent);
275}
276
277#define OF_METER_STATS_LENGTH_OFFSET 4
278
279/**
280 * Get/set the wire length for a meter stats object
281 * @param obj The object being referenced
282 * @param bytes Pointer to location to store length
283 *
284 * It's almost a TLV....
285 */
286
287void
288of_meter_stats_wire_length_get(of_object_t *obj, int *bytes)
289{
290 uint16_t val16;
291 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800292 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700293 of_wire_buffer_u16_get(wbuf,
294 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET),
295 &val16);
296 *bytes = val16;
297}
298
299void
300of_meter_stats_wire_length_set(of_object_t *obj, int bytes)
301{
302 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800303 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700304
305 of_wire_buffer_u16_set(wbuf,
306 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET), bytes);
307}
Rich Lane127860e2014-10-14 11:03:49 -0700308
309/**
310 * Get the wire length for a port desc object
311 * @param obj The object being referenced
312 * @param bytes Pointer to location to store length
313 *
314 * The length is only present for OF 1.4+.
315 */
316void
317of_port_desc_wire_length_get(of_object_t *obj, int *bytes)
318{
319 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
320 uint16_t u16;
321
322 LOCI_ASSERT(wbuf != NULL);
323
324 if (obj->version >= OF_VERSION_1_4) {
325 of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 4),
326 &u16);
327 *bytes = u16;
328 } else {
329 *bytes = OF_OBJECT_FIXED_LENGTH(obj);
330 }
331}
332
333/**
334 * Set the wire length for a port desc object
335 * @param obj The object being referenced
336 * @param bytes The length of the object
337 *
338 * The length is only present for OF 1.4+.
339 */
340
341void
342of_port_desc_wire_length_set(of_object_t *obj, int bytes)
343{
344 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
345 LOCI_ASSERT(wbuf != NULL);
346
347 if (obj->version >= OF_VERSION_1_4) {
348 of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 4),
349 bytes);
350 } else {
351 LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
352 }
353}
354
355/**
356 * Get the wire length for a port stats_entry object
357 * @param obj The object being referenced
358 * @param bytes Pointer to location to store length
359 *
360 * The length is only present for OF 1.4+.
361 */
362void
363of_port_stats_entry_wire_length_get(of_object_t *obj, int *bytes)
364{
365 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
366 uint16_t u16;
367
368 LOCI_ASSERT(wbuf != NULL);
369
370 if (obj->version >= OF_VERSION_1_4) {
371 of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
372 &u16);
373 *bytes = u16;
374 } else {
375 *bytes = OF_OBJECT_FIXED_LENGTH(obj);
376 }
377}
378
379/**
380 * Set the wire length for a port stats_entry object
381 * @param obj The object being referenced
382 * @param bytes The length of the object
383 *
384 * The length is only present for OF 1.4+.
385 */
386
387void
388of_port_stats_entry_wire_length_set(of_object_t *obj, int bytes)
389{
390 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
391 LOCI_ASSERT(wbuf != NULL);
392
393 if (obj->version >= OF_VERSION_1_4) {
394 of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
395 bytes);
396 } else {
397 LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
398 }
399}
400
401/**
402 * Get the wire length for a queue stats_entry object
403 * @param obj The object being referenced
404 * @param bytes Pointer to location to store length
405 *
406 * The length is only present for OF 1.4+.
407 */
408void
409of_queue_stats_entry_wire_length_get(of_object_t *obj, int *bytes)
410{
411 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
412 uint16_t u16;
413
414 LOCI_ASSERT(wbuf != NULL);
415
416 if (obj->version >= OF_VERSION_1_4) {
417 of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
418 &u16);
419 *bytes = u16;
420 } else {
421 *bytes = OF_OBJECT_FIXED_LENGTH(obj);
422 }
423}
424
425/**
426 * Set the wire length for a queue stats_entry object
427 * @param obj The object being referenced
428 * @param bytes The length of the object
429 *
430 * The length is only present for OF 1.4+.
431 */
432
433void
434of_queue_stats_entry_wire_length_set(of_object_t *obj, int bytes)
435{
436 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
437 LOCI_ASSERT(wbuf != NULL);
438
439 if (obj->version >= OF_VERSION_1_4) {
440 of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
441 bytes);
442 } else {
443 LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
444 }
445}
Rich Lane7329b542014-10-17 18:30:13 -0700446
447/**
448 * Get the wire length for a queue_desc object
449 * @param obj The object being referenced
450 * @param bytes Pointer to location to store length
451 */
452void
453of_queue_desc_wire_length_get(of_object_t *obj, int *bytes)
454{
455 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
456 uint16_t u16;
457
458 LOCI_ASSERT(wbuf != NULL);
459
460 of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 8), &u16);
461 *bytes = u16;
462}
463
464/**
465 * Set the wire length for a queue_desc object
466 * @param obj The object being referenced
467 * @param bytes The length of the object
468 */
469
470void
471of_queue_desc_wire_length_set(of_object_t *obj, int bytes)
472{
473 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
474 LOCI_ASSERT(wbuf != NULL);
475
476 of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 8), bytes);
477}