blob: ef3f82bf103b4d6473fe0416a38f5f59022cf962 [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
124/**
125 * Get the type field from the wire for a standard TLV object that uses
126 * uint16 for both type and length.
127 * @param obj The object being referenced
128 * @param wire_type (out) Where to store the type
129 */
130
131static void
132of_tlv16_wire_type_get(of_object_t *obj, int *wire_type)
133{
134 uint16_t val16;
135 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
136
137 of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj,
138 TLV16_WIRE_TYPE_OFFSET), &val16);
139
140 *wire_type = val16;
141}
142
143/**
Rich Lanea06d0c32013-03-25 08:52:03 -0700144 * Get the object ID of an extended action
145 * @param obj The object being referenced
146 * @param id Where to store the object ID
147 * @fixme: This should be auto generated
148 *
149 * If unable to map to known extension, set id to generic "experimenter"
150 */
151
152#define OF_ACTION_EXPERIMENTER_ID_OFFSET 4
153#define OF_ACTION_EXPERIMENTER_SUBTYPE_OFFSET 8
154
155
156static void
157extension_action_object_id_get(of_object_t *obj, of_object_id_t *id)
158{
159 uint32_t exp_id;
160 uint8_t *buf;
161
162 *id = OF_ACTION_EXPERIMENTER;
163
164 buf = OF_OBJECT_BUFFER_INDEX(obj, 0);
165
166 buf_u32_get(buf + OF_ACTION_EXPERIMENTER_ID_OFFSET, &exp_id);
167
168 switch (exp_id) {
169 case OF_EXPERIMENTER_ID_BSN: {
170 uint32_t subtype;
171 buf_u32_get(buf + OF_ACTION_EXPERIMENTER_SUBTYPE_OFFSET, &subtype);
172 switch (subtype) {
173 case 1: *id = OF_ACTION_BSN_MIRROR; break;
174 case 2: *id = OF_ACTION_BSN_SET_TUNNEL_DST; break;
175 }
176 break;
177 }
178 case OF_EXPERIMENTER_ID_NICIRA: {
179 uint16_t subtype;
180 buf_u16_get(buf + OF_ACTION_EXPERIMENTER_SUBTYPE_OFFSET, &subtype);
181 switch (subtype) {
182 case 18: *id = OF_ACTION_NICIRA_DEC_TTL; break;
183 }
184 break;
185 }
186 }
187}
188
189/**
Rich Lanea06d0c32013-03-25 08:52:03 -0700190 * Get the object ID of an extended action
191 * @param obj The object being referenced
192 * @param id Where to store the object ID
193 * @fixme: This should be auto generated
194 *
195 * If unable to map to known extension, set id to generic "experimenter"
196 */
197
198static void
199extension_action_id_object_id_get(of_object_t *obj, of_object_id_t *id)
200{
201 uint32_t exp_id;
202 uint8_t *buf;
203
204 *id = OF_ACTION_ID_EXPERIMENTER;
205
206 buf = OF_OBJECT_BUFFER_INDEX(obj, 0);
207
208 buf_u32_get(buf + OF_ACTION_EXPERIMENTER_ID_OFFSET, &exp_id);
209
210 switch (exp_id) {
211 case OF_EXPERIMENTER_ID_BSN: {
212 uint32_t subtype;
213 buf_u32_get(buf + OF_ACTION_EXPERIMENTER_SUBTYPE_OFFSET, &subtype);
214 switch (subtype) {
215 case 1: *id = OF_ACTION_ID_BSN_MIRROR; break;
216 case 2: *id = OF_ACTION_ID_BSN_SET_TUNNEL_DST; break;
217 }
218 break;
219 }
220 case OF_EXPERIMENTER_ID_NICIRA: {
221 uint16_t subtype;
222 buf_u16_get(buf + OF_ACTION_EXPERIMENTER_SUBTYPE_OFFSET, &subtype);
223 switch (subtype) {
224 case 18: *id = OF_ACTION_ID_NICIRA_DEC_TTL; break;
225 }
226 break;
227 }
228 }
229}
230
231
232/**
233 * Get the object ID based on the wire buffer for an action object
234 * @param obj The object being referenced
235 * @param id Where to store the object ID
236 */
237
238
239void
240of_action_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
241{
242 int wire_type;
243
244 of_tlv16_wire_type_get(obj, &wire_type);
245 if (wire_type == OF_EXPERIMENTER_TYPE) {
246 extension_action_object_id_get(obj, id);
247 return;
248 }
249
Rich Lanee57f0432014-02-19 10:31:53 -0800250 LOCI_ASSERT(wire_type >= 0 && wire_type < OF_ACTION_ITEM_COUNT);
Rich Lanea06d0c32013-03-25 08:52:03 -0700251
252 *id = of_action_type_to_id[obj->version][wire_type];
Rich Lanee57f0432014-02-19 10:31:53 -0800253 LOCI_ASSERT(*id != OF_OBJECT_INVALID);
Rich Lanea06d0c32013-03-25 08:52:03 -0700254}
255
256/**
257 * Get the object ID based on the wire buffer for an action ID object
258 * @param obj The object being referenced
259 * @param id Where to store the object ID
260 */
261
262
263void
264of_action_id_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
265{
266 int wire_type;
267
268 of_tlv16_wire_type_get(obj, &wire_type);
269 if (wire_type == OF_EXPERIMENTER_TYPE) {
270 extension_action_id_object_id_get(obj, id);
271 return;
272 }
273
Rich Lanee57f0432014-02-19 10:31:53 -0800274 LOCI_ASSERT(wire_type >= 0 && wire_type < OF_ACTION_ID_ITEM_COUNT);
Rich Lanea06d0c32013-03-25 08:52:03 -0700275
276 *id = of_action_id_type_to_id[obj->version][wire_type];
Rich Lanee57f0432014-02-19 10:31:53 -0800277 LOCI_ASSERT(*id != OF_OBJECT_INVALID);
Rich Lanea06d0c32013-03-25 08:52:03 -0700278}
279
280/**
281 * @fixme to do when we have instruction extensions
282 * See extension_action above
283 */
284
285static int
286extension_instruction_object_id_get(of_object_t *obj, of_object_id_t *id)
287{
Rich Laneef7b9942013-11-18 16:29:28 -0800288 uint32_t exp_id;
289 uint8_t *buf;
Rich Lanea06d0c32013-03-25 08:52:03 -0700290
291 *id = OF_INSTRUCTION_EXPERIMENTER;
292
Rich Laneef7b9942013-11-18 16:29:28 -0800293 buf = OF_OBJECT_BUFFER_INDEX(obj, 0);
294
295 buf_u32_get(buf + OF_INSTRUCTION_EXPERIMENTER_ID_OFFSET, &exp_id);
296
297 switch (exp_id) {
298 case OF_EXPERIMENTER_ID_BSN: {
299 uint32_t subtype;
300 buf_u32_get(buf + OF_INSTRUCTION_EXPERIMENTER_SUBTYPE_OFFSET, &subtype);
301 switch (subtype) {
302 case 0: *id = OF_INSTRUCTION_BSN_DISABLE_SRC_MAC_CHECK; break;
Rich Lanef41bad32014-01-13 13:08:51 -0800303 case 1: *id = OF_INSTRUCTION_BSN_ARP_OFFLOAD; break;
Rich Lanee4113432014-02-04 18:00:03 -0800304 case 2: *id = OF_INSTRUCTION_BSN_DHCP_OFFLOAD; break;
Rich Lane74a983b2014-02-13 17:04:19 -0800305 case 3: *id = OF_INSTRUCTION_BSN_DISABLE_SPLIT_HORIZON_CHECK; break;
Rich Lane86511ba2014-02-26 10:14:57 -0800306 case 4: *id = OF_INSTRUCTION_BSN_PERMIT; break;
307 case 5: *id = OF_INSTRUCTION_BSN_DENY; break;
Rich Laneef7b9942013-11-18 16:29:28 -0800308 }
309 break;
310 }
311 }
312
Rich Lanea06d0c32013-03-25 08:52:03 -0700313 return OF_ERROR_NONE;
314}
315
Jonathan Stout83cedcc2014-03-03 16:38:00 -0500316
317/**
318 * @fixme to do when we have instruction extensions
319 * See extension_action above
320 */
321
Jonathan Stout33d7d412014-03-03 17:23:11 -0500322static int
Jonathan Stout83cedcc2014-03-03 16:38:00 -0500323extension_instruction_id_object_id_get(of_object_t *obj, of_object_id_t *id)
324{
325 uint32_t exp_id;
326 uint8_t *buf;
327
328 *id = OF_INSTRUCTION_ID_EXPERIMENTER;
329
330 buf = OF_OBJECT_BUFFER_INDEX(obj, 0);
331
332 buf_u32_get(buf + OF_INSTRUCTION_EXPERIMENTER_ID_OFFSET, &exp_id);
333
334 switch (exp_id) {
335 case OF_EXPERIMENTER_ID_BSN: {
336 uint32_t subtype;
337 buf_u32_get(buf + OF_INSTRUCTION_EXPERIMENTER_SUBTYPE_OFFSET, &subtype);
338 switch (subtype) {
339 case 0: *id = OF_INSTRUCTION_ID_BSN_DISABLE_SRC_MAC_CHECK; break;
340 case 1: *id = OF_INSTRUCTION_ID_BSN_ARP_OFFLOAD; break;
341 case 2: *id = OF_INSTRUCTION_ID_BSN_DHCP_OFFLOAD; break;
342 case 3: *id = OF_INSTRUCTION_ID_BSN_DISABLE_SPLIT_HORIZON_CHECK; break;
343 case 4: *id = OF_INSTRUCTION_ID_BSN_PERMIT; break;
344 case 5: *id = OF_INSTRUCTION_ID_BSN_DENY; break;
345 }
346 break;
347 }
348 }
349
Jonathan Stout33d7d412014-03-03 17:23:11 -0500350 return OF_ERROR_NONE;
Jonathan Stout83cedcc2014-03-03 16:38:00 -0500351}
352
Rich Lanea06d0c32013-03-25 08:52:03 -0700353/**
354 * Get the object ID based on the wire buffer for an instruction object
355 * @param obj The object being referenced
356 * @param id Where to store the object ID
357 */
358
359void
360of_instruction_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
361{
362 int wire_type;
363
364 of_tlv16_wire_type_get(obj, &wire_type);
365 if (wire_type == OF_EXPERIMENTER_TYPE) {
366 extension_instruction_object_id_get(obj, id);
367 return;
368 }
369
Rich Lanee57f0432014-02-19 10:31:53 -0800370 LOCI_ASSERT(wire_type >= 0 && wire_type < OF_INSTRUCTION_ITEM_COUNT);
Rich Lanea06d0c32013-03-25 08:52:03 -0700371
372 *id = of_instruction_type_to_id[obj->version][wire_type];
Rich Lanee57f0432014-02-19 10:31:53 -0800373 LOCI_ASSERT(*id != OF_OBJECT_INVALID);
Rich Lanea06d0c32013-03-25 08:52:03 -0700374}
375
Jonathan Stout83cedcc2014-03-03 16:38:00 -0500376/**
377 * Get the object ID based on the wire buffer for an instruction ID object
378 * @param obj The object being referenced
379 * @param id Where to store the object ID
380 */
381
382
383void
384of_instruction_id_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
385{
386 int wire_type;
387
388 of_tlv16_wire_type_get(obj, &wire_type);
389 if (wire_type == OF_EXPERIMENTER_TYPE) {
390 extension_instruction_id_object_id_get(obj, id);
391 return;
392 }
393
394 LOCI_ASSERT(wire_type >= 0 && wire_type < OF_INSTRUCTION_ID_ITEM_COUNT);
395
396 *id = of_instruction_id_type_to_id[obj->version][wire_type];
397 LOCI_ASSERT(*id != OF_OBJECT_INVALID);
398}
Rich Lanea06d0c32013-03-25 08:52:03 -0700399
400/**
401 * @fixme to do when we have queue_prop extensions
402 * See extension_action above
403 */
404
405static void
406extension_queue_prop_object_id_get(of_object_t *obj, of_object_id_t *id)
407{
408 (void)obj;
409
410 *id = OF_QUEUE_PROP_EXPERIMENTER;
411}
412
413/**
414 * Get the object ID based on the wire buffer for an queue_prop object
415 * @param obj The object being referenced
416 * @param id Where to store the object ID
417 */
418
419void
420of_queue_prop_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
421{
422 int wire_type;
423
424 of_tlv16_wire_type_get(obj, &wire_type);
425 if (wire_type == OF_EXPERIMENTER_TYPE) {
426 extension_queue_prop_object_id_get(obj, id);
427 return;
428 }
429
Rich Lanee57f0432014-02-19 10:31:53 -0800430 LOCI_ASSERT(wire_type >= 0 && wire_type < OF_QUEUE_PROP_ITEM_COUNT);
Rich Lanea06d0c32013-03-25 08:52:03 -0700431
432 *id = of_queue_prop_type_to_id[obj->version][wire_type];
Rich Lanee57f0432014-02-19 10:31:53 -0800433 LOCI_ASSERT(*id != OF_OBJECT_INVALID);
Rich Lanea06d0c32013-03-25 08:52:03 -0700434}
435
436
437/**
Rich Lanea06d0c32013-03-25 08:52:03 -0700438 * Table feature property object ID determination
439 *
440 * @param obj The object being referenced
441 * @param id Where to store the object ID
442 */
443
444void
445of_table_feature_prop_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
446{
447 int wire_type;
448
449 of_tlv16_wire_type_get(obj, &wire_type);
Jonathan Stout0131f132014-02-14 17:06:19 -0500450 *id = of_table_feature_prop_to_object_id(wire_type, obj->version);
Rich Lanea06d0c32013-03-25 08:52:03 -0700451}
452
453/**
454 * Get the object ID based on the wire buffer for meter_band object
455 * @param obj The object being referenced
456 * @param id Where to store the object ID
457 */
458
459void
460of_meter_band_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
461{
462 int wire_type;
463
464 of_tlv16_wire_type_get(obj, &wire_type);
465 if (wire_type == OF_EXPERIMENTER_TYPE) {
466 *id = OF_METER_BAND_EXPERIMENTER;
467 return;
468 }
469
Rich Lanee57f0432014-02-19 10:31:53 -0800470 LOCI_ASSERT(wire_type >= 0 && wire_type < OF_METER_BAND_ITEM_COUNT);
Rich Lanea06d0c32013-03-25 08:52:03 -0700471
472 *id = of_meter_band_type_to_id[obj->version][wire_type];
Rich Lanee57f0432014-02-19 10:31:53 -0800473 LOCI_ASSERT(*id != OF_OBJECT_INVALID);
Rich Lanea06d0c32013-03-25 08:52:03 -0700474}
475
476/**
477 * Get the object ID based on the wire buffer for a hello_elem object
478 * @param obj The object being referenced
479 * @param id Where to store the object ID
480 */
481
482void
483of_hello_elem_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
484{
485 int wire_type;
486
487 of_tlv16_wire_type_get(obj, &wire_type);
Rich Lanee57f0432014-02-19 10:31:53 -0800488 LOCI_ASSERT(wire_type >= 0 && wire_type < OF_HELLO_ELEM_ITEM_COUNT);
Rich Lanea06d0c32013-03-25 08:52:03 -0700489 *id = of_hello_elem_type_to_id[obj->version][wire_type];
Rich Lanee57f0432014-02-19 10:31:53 -0800490 LOCI_ASSERT(*id != OF_OBJECT_INVALID);
Rich Lanea06d0c32013-03-25 08:52:03 -0700491}
492
Rich Lane713d9282013-12-30 15:21:35 -0800493/**
494 * Get the object ID based on the wire buffer for a bsn_tlv object
495 * @param obj The object being referenced
496 * @param id Where to store the object ID
497 */
498
499void
500of_bsn_tlv_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
501{
502 int wire_type;
503
504 of_tlv16_wire_type_get(obj, &wire_type);
Rich Lanee57f0432014-02-19 10:31:53 -0800505 LOCI_ASSERT(wire_type >= 0 && wire_type < OF_BSN_TLV_ITEM_COUNT);
Rich Lane713d9282013-12-30 15:21:35 -0800506 *id = of_bsn_tlv_type_to_id[obj->version][wire_type];
Rich Lanee57f0432014-02-19 10:31:53 -0800507 LOCI_ASSERT(*id != OF_OBJECT_INVALID);
Rich Lane713d9282013-12-30 15:21:35 -0800508}
509
Rich Lanea06d0c32013-03-25 08:52:03 -0700510/****************************************************************
511 * OXM type/length functions.
512 ****************************************************************/
513
514/* Where does the OXM type-length header lie in the buffer */
515#define OXM_HDR_OFFSET 0
516
517/**
518 * Get the OXM header (type-length fields) from the wire buffer
519 * associated with an OXM object
520 *
521 * Will return if error; set hdr to the OXM header
522 */
523
524#define _GET_OXM_TYPE_LEN(obj, tl_p, wbuf) do { \
525 wbuf = OF_OBJECT_TO_WBUF(obj); \
Rich Lanee57f0432014-02-19 10:31:53 -0800526 LOCI_ASSERT(wbuf != NULL); \
Rich Lanea06d0c32013-03-25 08:52:03 -0700527 of_wire_buffer_u32_get(wbuf, \
528 OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), (tl_p)); \
529 } while (0)
530
531#define _SET_OXM_TYPE_LEN(obj, tl_p, wbuf) do { \
532 wbuf = OF_OBJECT_TO_WBUF(obj); \
Rich Lanee57f0432014-02-19 10:31:53 -0800533 LOCI_ASSERT(wbuf != NULL); \
Rich Lanea06d0c32013-03-25 08:52:03 -0700534 of_wire_buffer_u32_set(wbuf, \
535 OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), (tl_p)); \
536 } while (0)
537
538/**
539 * Get the length of an OXM object from the wire buffer
540 * @param obj The object whose wire buffer is an OXM type
541 * @param bytes (out) Where length is stored
542 */
543
544void
545of_oxm_wire_length_get(of_object_t *obj, int *bytes)
546{
547 uint32_t type_len;
548 of_wire_buffer_t *wbuf;
549
550 _GET_OXM_TYPE_LEN(obj, &type_len, wbuf);
551 *bytes = OF_OXM_LENGTH_GET(type_len);
552}
553
554/**
Rich Lanea06d0c32013-03-25 08:52:03 -0700555 * Get the object ID of an OXM object based on the wire buffer type
556 * @param obj The object whose wire buffer is an OXM type
557 * @param id (out) Where the ID is stored
558 */
559
560void
561of_oxm_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
562{
563 uint32_t type_len;
Rich Lanea06d0c32013-03-25 08:52:03 -0700564 of_wire_buffer_t *wbuf;
565
566 _GET_OXM_TYPE_LEN(obj, &type_len, wbuf);
Rich Laned8d29c92013-09-24 13:46:42 -0700567 *id = of_oxm_to_object_id(type_len, obj->version);
Rich Lanea06d0c32013-03-25 08:52:03 -0700568}
569
Rich Lanea06d0c32013-03-25 08:52:03 -0700570#define OF_U16_LEN_LENGTH_OFFSET 0
571
572/**
573 * Get the wire length for an object with a uint16 length as first member
574 * @param obj The object being referenced
575 * @param bytes Pointer to location to store length
576 */
577void
578of_u16_len_wire_length_get(of_object_t *obj, int *bytes)
579{
580 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
581 uint16_t u16;
582
Rich Lanee57f0432014-02-19 10:31:53 -0800583 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700584
585 of_wire_buffer_u16_get(wbuf,
586 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_U16_LEN_LENGTH_OFFSET),
587 &u16);
588
589 *bytes = u16;
590}
591
592/**
593 * Set the wire length for an object with a uint16 length as first member
594 * @param obj The object being referenced
595 * @param bytes The length of the object
596 */
597
598void
599of_u16_len_wire_length_set(of_object_t *obj, int bytes)
600{
601 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800602 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700603
Rich Lanee57f0432014-02-19 10:31:53 -0800604 /* LOCI_ASSERT(obj is u16-len entry) */
Rich Lanea06d0c32013-03-25 08:52:03 -0700605
606 of_wire_buffer_u16_set(wbuf,
607 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_U16_LEN_LENGTH_OFFSET),
608 bytes);
609}
610
611
612#define OF_PACKET_QUEUE_LENGTH_OFFSET(ver) \
613 (((ver) >= OF_VERSION_1_2) ? 8 : 4)
614
615/**
616 * Get the wire length for a packet queue object
617 * @param obj The object being referenced
618 * @param bytes Pointer to location to store length
619 *
620 * The length is a uint16 at the offset indicated above
621 */
622void
623of_packet_queue_wire_length_get(of_object_t *obj, int *bytes)
624{
625 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
626 uint16_t u16;
627 int offset;
628
Rich Lanee57f0432014-02-19 10:31:53 -0800629 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700630
Rich Lanee57f0432014-02-19 10:31:53 -0800631 /* LOCI_ASSERT(obj is packet queue obj) */
Rich Lanea06d0c32013-03-25 08:52:03 -0700632 offset = OF_PACKET_QUEUE_LENGTH_OFFSET(obj->version);
633 of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, offset),
634 &u16);
635
636 *bytes = u16;
637}
638
639/**
640 * Set the wire length for a 1.2 packet queue object
641 * @param obj The object being referenced
642 * @param bytes The length of the object
643 *
644 * The length is a uint16 at the offset indicated above
645 */
646
647void
648of_packet_queue_wire_length_set(of_object_t *obj, int bytes)
649{
650 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
651 int offset;
652
Rich Lanee57f0432014-02-19 10:31:53 -0800653 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700654
Rich Lanee57f0432014-02-19 10:31:53 -0800655 /* LOCI_ASSERT(obj is packet queue obj) */
Rich Lanea06d0c32013-03-25 08:52:03 -0700656 offset = OF_PACKET_QUEUE_LENGTH_OFFSET(obj->version);
657 of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, offset),
658 bytes);
659}
660
661/**
662 * Get the wire length for a meter band stats list
663 * @param obj The object being referenced
664 * @param bytes Pointer to location to store length
665 *
666 * Must a meter_stats object as a parent
667 */
668
669void
670of_list_meter_band_stats_wire_length_get(of_object_t *obj, int *bytes)
671{
Rich Lanee57f0432014-02-19 10:31:53 -0800672 LOCI_ASSERT(obj->parent != NULL);
673 LOCI_ASSERT(obj->parent->object_id == OF_METER_STATS);
Rich Lanea06d0c32013-03-25 08:52:03 -0700674
675 /* We're counting on the parent being properly initialized already.
676 * The length is stored in a uint16 at offset 4 of the parent.
677 */
678 *bytes = obj->parent->length - OF_OBJECT_FIXED_LENGTH(obj->parent);
679}
680
681#define OF_METER_STATS_LENGTH_OFFSET 4
682
683/**
684 * Get/set the wire length for a meter stats object
685 * @param obj The object being referenced
686 * @param bytes Pointer to location to store length
687 *
688 * It's almost a TLV....
689 */
690
691void
692of_meter_stats_wire_length_get(of_object_t *obj, int *bytes)
693{
694 uint16_t val16;
695 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800696 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700697 of_wire_buffer_u16_get(wbuf,
698 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET),
699 &val16);
700 *bytes = val16;
701}
702
703void
704of_meter_stats_wire_length_set(of_object_t *obj, int bytes)
705{
706 of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
Rich Lanee57f0432014-02-19 10:31:53 -0800707 LOCI_ASSERT(wbuf != NULL);
Rich Lanea06d0c32013-03-25 08:52:03 -0700708
709 of_wire_buffer_u16_set(wbuf,
710 OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET), bytes);
711}
712
713/*
714 * Non-message extension push wire values
715 */
716
717int
718of_extension_object_wire_push(of_object_t *obj)
719{
720 of_action_bsn_mirror_t *action_mirror;
721 of_action_id_bsn_mirror_t *action_id_mirror;
722 of_action_bsn_set_tunnel_dst_t *action_set_tunnel_dst;
723 of_action_id_bsn_set_tunnel_dst_t *action_id_set_tunnel_dst;
724 of_action_nicira_dec_ttl_t *action_nicira_dec_ttl;
725 of_action_id_nicira_dec_ttl_t *action_id_nicira_dec_ttl;
726
727 /* Push exp type, subtype */
728 switch (obj->object_id) {
729 case OF_ACTION_BSN_MIRROR:
730 action_mirror = (of_action_bsn_mirror_t *)obj;
731 of_action_bsn_mirror_experimenter_set(action_mirror,
732 OF_EXPERIMENTER_ID_BSN);
733 of_action_bsn_mirror_subtype_set(action_mirror, 1);
734 break;
735 case OF_ACTION_ID_BSN_MIRROR:
736 action_id_mirror = (of_action_id_bsn_mirror_t *)obj;
737 of_action_id_bsn_mirror_experimenter_set(action_id_mirror,
738 OF_EXPERIMENTER_ID_BSN);
739 of_action_id_bsn_mirror_subtype_set(action_id_mirror, 1);
740 break;
741 case OF_ACTION_BSN_SET_TUNNEL_DST:
742 action_set_tunnel_dst = (of_action_bsn_set_tunnel_dst_t *)obj;
743 of_action_bsn_set_tunnel_dst_experimenter_set(action_set_tunnel_dst,
744 OF_EXPERIMENTER_ID_BSN);
745 of_action_bsn_set_tunnel_dst_subtype_set(action_set_tunnel_dst, 2);
746 break;
747 case OF_ACTION_ID_BSN_SET_TUNNEL_DST:
748 action_id_set_tunnel_dst = (of_action_id_bsn_set_tunnel_dst_t *)obj;
749 of_action_id_bsn_set_tunnel_dst_experimenter_set(action_id_set_tunnel_dst,
750 OF_EXPERIMENTER_ID_BSN);
751 of_action_id_bsn_set_tunnel_dst_subtype_set(action_id_set_tunnel_dst, 2);
752 break;
753 case OF_ACTION_NICIRA_DEC_TTL:
754 action_nicira_dec_ttl = (of_action_nicira_dec_ttl_t *)obj;
755 of_action_nicira_dec_ttl_experimenter_set(action_nicira_dec_ttl,
756 OF_EXPERIMENTER_ID_NICIRA);
757 of_action_nicira_dec_ttl_subtype_set(action_nicira_dec_ttl, 18);
758 break;
759 case OF_ACTION_ID_NICIRA_DEC_TTL:
760 action_id_nicira_dec_ttl = (of_action_id_nicira_dec_ttl_t *)obj;
761 of_action_id_nicira_dec_ttl_experimenter_set(action_id_nicira_dec_ttl,
762 OF_EXPERIMENTER_ID_NICIRA);
763 of_action_id_nicira_dec_ttl_subtype_set(action_id_nicira_dec_ttl, 18);
764 break;
765 default:
766 break;
767 }
768
769 return OF_ERROR_NONE;
770}
Rich Lane353a79f2013-11-13 10:39:56 -0800771
772int
773of_experimenter_stats_request_to_object_id(uint32_t experimenter, uint32_t subtype, int ver)
774{
775 switch (experimenter) {
776 case OF_EXPERIMENTER_ID_BSN:
777 switch (subtype) {
778 case 1: return OF_BSN_LACP_STATS_REQUEST;
Rich Lane713d9282013-12-30 15:21:35 -0800779 case 2: return OF_BSN_GENTABLE_ENTRY_DESC_STATS_REQUEST;
780 case 3: return OF_BSN_GENTABLE_ENTRY_STATS_REQUEST;
781 case 4: return OF_BSN_GENTABLE_DESC_STATS_REQUEST;
782 case 5: return OF_BSN_GENTABLE_BUCKET_STATS_REQUEST;
Wilson Ng45386fb2013-12-03 13:46:42 -0800783 case 6: return OF_BSN_SWITCH_PIPELINE_STATS_REQUEST;
Rich Lane713d9282013-12-30 15:21:35 -0800784 case 7: return OF_BSN_GENTABLE_STATS_REQUEST;
xinwu54ceaca2013-12-04 17:02:27 -0800785 case 8: return OF_BSN_PORT_COUNTER_STATS_REQUEST;
786 case 9: return OF_BSN_VLAN_COUNTER_STATS_REQUEST;
Rich Lane013dea02014-02-05 13:44:13 -0800787 case 10: return OF_BSN_FLOW_CHECKSUM_BUCKET_STATS_REQUEST;
788 case 11: return OF_BSN_TABLE_CHECKSUM_STATS_REQUEST;
Rich Lane353a79f2013-11-13 10:39:56 -0800789 }
790 }
791 return OF_OBJECT_INVALID;
792}
793
794int
795of_experimenter_stats_reply_to_object_id(uint32_t experimenter, uint32_t subtype, int ver)
796{
797 switch (experimenter) {
798 case OF_EXPERIMENTER_ID_BSN:
799 switch (subtype) {
800 case 1: return OF_BSN_LACP_STATS_REPLY;
Rich Lane713d9282013-12-30 15:21:35 -0800801 case 2: return OF_BSN_GENTABLE_ENTRY_DESC_STATS_REPLY;
802 case 3: return OF_BSN_GENTABLE_ENTRY_STATS_REPLY;
803 case 4: return OF_BSN_GENTABLE_DESC_STATS_REPLY;
804 case 5: return OF_BSN_GENTABLE_BUCKET_STATS_REPLY;
Wilson Ng45386fb2013-12-03 13:46:42 -0800805 case 6: return OF_BSN_SWITCH_PIPELINE_STATS_REPLY;
Rich Lane713d9282013-12-30 15:21:35 -0800806 case 7: return OF_BSN_GENTABLE_STATS_REPLY;
xinwu54ceaca2013-12-04 17:02:27 -0800807 case 8: return OF_BSN_PORT_COUNTER_STATS_REPLY;
808 case 9: return OF_BSN_VLAN_COUNTER_STATS_REPLY;
Rich Lane013dea02014-02-05 13:44:13 -0800809 case 10: return OF_BSN_FLOW_CHECKSUM_BUCKET_STATS_REPLY;
810 case 11: return OF_BSN_TABLE_CHECKSUM_STATS_REPLY;
Rich Lane353a79f2013-11-13 10:39:56 -0800811 }
812 }
813 return OF_OBJECT_INVALID;
814}