blob: 944f6d2514edd2257751bf179701d1d0a6c1c179 [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 * These routines manipulate a low level buffer assuming it holds
32 * an OpenFlow message.
33 */
34
35#if !defined(_OF_MESSAGE_H_)
36#define _OF_MESSAGE_H_
37
38#include <loci/of_buffer.h>
39
40typedef uint8_t *of_message_t;
41
42/* A few key common header offsets */
43#define OF_MESSAGE_VERSION_OFFSET 0
44#define OF_MESSAGE_TYPE_OFFSET 1
45#define OF_MESSAGE_LENGTH_OFFSET 2
46#define OF_MESSAGE_XID_OFFSET 4
47#define OF_MESSAGE_HEADER_LENGTH 8
48#define OF_MESSAGE_STATS_TYPE_OFFSET 8
49#define OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version) ((version) == 1 ? 56 : 25)
50
51#define OF_MESSAGE_MIN_LENGTH 8
52#define OF_MESSAGE_MIN_STATS_LENGTH (OF_MESSAGE_STATS_TYPE_OFFSET + 2)
53#define OF_MESSAGE_MIN_FLOW_MOD_LENGTH(version) ((version) == 1 ? 57 : 26)
54
55#define OF_MESSAGE_EXPERIMENTER_ID_OFFSET 8
56#define OF_MESSAGE_EXPERIMENTER_SUBTYPE_OFFSET 12
57#define OF_MESSAGE_EXPERIMENTER_MIN_LENGTH 16
58
59/**
60 * The "default" free message function; NULL means use nominal malloc/free
61 */
62#define OF_MESSAGE_FREE_FUNCTION NULL
63
64/**
65 * Map a message to the uint8_t * start of the message
66 */
67#define OF_MESSAGE_TO_BUFFER(msg) ((uint8_t *)(msg))
68
69/**
70 * Map a uint8_t * to a message object
71 */
72#define OF_BUFFER_TO_MESSAGE(buf) ((of_message_t)(buf))
73
74/****************************************************************
75 *
76 * Message field accessors.
77 *
78 * These do no range checking and assume a buffer with sufficient
79 * length to access the data. These are low level accessors used
80 * during the parsing and coersion stage of message processing.
81 *
82 * Fields include: version, message type, message length,
83 * transaction id, stats type (now multi-part type), experimenter id,
84 * experimenter type
85 *
86 ****************************************************************/
87
88/**
89 * @brief Get/set version of a message
90 * @param msg Pointer to the message buffer of sufficient length
91 * @param version Data for set operation
92 * @returns get returns version
93 */
94
95static inline of_version_t
96of_message_version_get(of_message_t msg) {
97 return (of_version_t)msg[OF_MESSAGE_VERSION_OFFSET];
98}
99
100static inline void
101of_message_version_set(of_message_t msg, of_version_t version) {
102 buf_u8_set(msg, (uint8_t)version);
103}
104
105/**
106 * @brief Get/set OpenFlow type of a message
107 * @param msg Pointer to the message buffer of sufficient length
108 * @param value Data for set operation
109 * @returns get returns message type
110 */
111
112static inline uint8_t
113of_message_type_get(of_message_t msg) {
114 return msg[OF_MESSAGE_TYPE_OFFSET];
115}
116
117static inline void
118of_message_type_set(of_message_t msg, uint8_t value) {
119 buf_u8_set(msg + OF_MESSAGE_TYPE_OFFSET, value);
120}
121
122/**
123 * @brief Get/set in-buffer length of a message
124 * @param msg Pointer to the message buffer of sufficient length
125 * @param len Data for set operation
126 * @returns get returns length in host order
127 */
128
129static inline uint16_t
130of_message_length_get(of_message_t msg) {
131 uint16_t val;
132 buf_u16_get(msg + OF_MESSAGE_LENGTH_OFFSET, &val);
133 return val;
134}
135
136static inline void
137of_message_length_set(of_message_t msg, uint16_t len) {
138 buf_u16_set(msg + OF_MESSAGE_LENGTH_OFFSET, len);
139}
140
141
142/**
143 * @brief Get/set transaction ID of a message
144 * @param msg Pointer to the message buffer of sufficient length
145 * @param xid Data for set operation
146 * @returns get returns xid in host order
147 */
148
149static inline uint32_t
150of_message_xid_get(of_message_t msg) {
151 uint32_t val;
152 buf_u32_get(msg + OF_MESSAGE_XID_OFFSET, &val);
153 return val;
154}
155
156static inline void
157of_message_xid_set(of_message_t msg, uint32_t xid) {
158 buf_u32_set(msg + OF_MESSAGE_XID_OFFSET, xid);
159}
160
161/**
162 * @brief Get/set stats type of a message
163 * @param msg Pointer to the message buffer of sufficient length
164 * @param type Data for set operation
165 * @returns get returns stats type in host order
166 */
167
168static inline uint16_t
169of_message_stats_type_get(of_message_t msg) {
170 uint16_t val;
171 buf_u16_get(msg + OF_MESSAGE_STATS_TYPE_OFFSET, &val);
172 return val;
173}
174
175static inline void
176of_message_stats_type_set(of_message_t msg, uint16_t type) {
177 buf_u16_set(msg + OF_MESSAGE_STATS_TYPE_OFFSET, type);
178}
179
180
181/**
182 * @brief Get/set experimenter ID of a message
183 * @param msg Pointer to the message buffer of sufficient length
184 * @param experimenter_id Data for set operation
185 * @returns get returns experimenter id in host order
186 */
187
188static inline uint32_t
189of_message_experimenter_id_get(of_message_t msg) {
190 uint32_t val;
191 buf_u32_get(msg + OF_MESSAGE_EXPERIMENTER_ID_OFFSET, &val);
192 return val;
193}
194
195static inline void
196of_message_experimenter_id_set(of_message_t msg, uint32_t experimenter_id) {
197 buf_u32_set(msg + OF_MESSAGE_EXPERIMENTER_ID_OFFSET, experimenter_id);
198}
199
200
201/**
202 * @brief Get/set experimenter message type (subtype) of a message
203 * @param msg Pointer to the message buffer of sufficient length
204 * @param subtype Data for set operation
205 * @returns get returns experimenter message type in host order
206 */
207
208static inline uint32_t
209of_message_experimenter_subtype_get(of_message_t msg) {
210 uint32_t val;
211 buf_u32_get(msg + OF_MESSAGE_EXPERIMENTER_SUBTYPE_OFFSET, &val);
212 return val;
213}
214
215static inline void
216of_message_experimenter_subtype_set(of_message_t msg,
217 uint32_t subtype) {
218 buf_u32_set(msg + OF_MESSAGE_EXPERIMENTER_SUBTYPE_OFFSET,
219 subtype);
220}
221
222/**
223 * Flow mod command changed from 16 to 8 bits on the wire from 1.0 to 1.1
224 */
225static inline uint8_t
226of_message_flow_mod_command_get(of_message_t msg, of_version_t version) {
227 uint16_t val16;
228 uint8_t val8;
229
230 if (version == OF_VERSION_1_0) {
231 buf_u16_get(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), &val16);
232 val8 = val16;
233 } else {
234 buf_u8_get(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), &val8);
235 }
236 return val8;
237}
238
239static inline void
240of_message_flow_mod_command_set(of_message_t msg, of_version_t version,
241 uint8_t command) {
242 uint16_t val16;
243
244 if (version == OF_VERSION_1_0) {
245 val16 = command;
246 buf_u16_set(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), val16);
247 } else {
248 buf_u8_set(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), command);
249 }
250}
251
252#endif /* _OF_MESSAGE_H_ */