Rich Lane | a06d0c3 | 2013-03-25 08:52:03 -0700 | [diff] [blame] | 1 | :: # 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 Lane | d983aa5 | 2013-06-13 11:48:37 -0700 | [diff] [blame] | 28 | :: include('_copyright.c') |
Rich Lane | a06d0c3 | 2013-03-25 08:52:03 -0700 | [diff] [blame] | 29 | |
| 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 | |
| 40 | typedef 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 |
Rob Vaterlaus | b3f49d9 | 2013-10-01 17:57:31 -0700 | [diff] [blame] | 48 | #define OF_MESSAGE_ERROR_TYPE_OFFSET 8 |
Rich Lane | a06d0c3 | 2013-03-25 08:52:03 -0700 | [diff] [blame] | 49 | #define OF_MESSAGE_STATS_TYPE_OFFSET 8 |
| 50 | #define OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version) ((version) == 1 ? 56 : 25) |
| 51 | |
| 52 | #define OF_MESSAGE_MIN_LENGTH 8 |
| 53 | #define OF_MESSAGE_MIN_STATS_LENGTH (OF_MESSAGE_STATS_TYPE_OFFSET + 2) |
Rob Vaterlaus | b3f49d9 | 2013-10-01 17:57:31 -0700 | [diff] [blame] | 54 | #define OF_MESSAGE_MIN_ERROR_LENGTH (OF_MESSAGE_ERROR_TYPE_OFFSET + 4) |
Rich Lane | a06d0c3 | 2013-03-25 08:52:03 -0700 | [diff] [blame] | 55 | #define OF_MESSAGE_MIN_FLOW_MOD_LENGTH(version) ((version) == 1 ? 57 : 26) |
| 56 | |
| 57 | #define OF_MESSAGE_EXPERIMENTER_ID_OFFSET 8 |
| 58 | #define OF_MESSAGE_EXPERIMENTER_SUBTYPE_OFFSET 12 |
| 59 | #define OF_MESSAGE_EXPERIMENTER_MIN_LENGTH 16 |
| 60 | |
Rich Lane | 353a79f | 2013-11-13 10:39:56 -0800 | [diff] [blame] | 61 | #define OF_MESSAGE_STATS_EXPERIMENTER_ID_OFFSET 16 |
| 62 | #define OF_MESSAGE_STATS_EXPERIMENTER_SUBTYPE_OFFSET 20 |
| 63 | #define OF_MESSAGE_STATS_EXPERIMENTER_MIN_LENGTH 24 |
| 64 | |
Rich Lane | a06d0c3 | 2013-03-25 08:52:03 -0700 | [diff] [blame] | 65 | /** |
| 66 | * The "default" free message function; NULL means use nominal malloc/free |
| 67 | */ |
| 68 | #define OF_MESSAGE_FREE_FUNCTION NULL |
| 69 | |
| 70 | /** |
| 71 | * Map a message to the uint8_t * start of the message |
| 72 | */ |
| 73 | #define OF_MESSAGE_TO_BUFFER(msg) ((uint8_t *)(msg)) |
| 74 | |
| 75 | /** |
| 76 | * Map a uint8_t * to a message object |
| 77 | */ |
| 78 | #define OF_BUFFER_TO_MESSAGE(buf) ((of_message_t)(buf)) |
| 79 | |
| 80 | /**************************************************************** |
| 81 | * |
| 82 | * Message field accessors. |
| 83 | * |
| 84 | * These do no range checking and assume a buffer with sufficient |
| 85 | * length to access the data. These are low level accessors used |
| 86 | * during the parsing and coersion stage of message processing. |
| 87 | * |
| 88 | * Fields include: version, message type, message length, |
| 89 | * transaction id, stats type (now multi-part type), experimenter id, |
| 90 | * experimenter type |
| 91 | * |
| 92 | ****************************************************************/ |
| 93 | |
| 94 | /** |
| 95 | * @brief Get/set version of a message |
| 96 | * @param msg Pointer to the message buffer of sufficient length |
| 97 | * @param version Data for set operation |
| 98 | * @returns get returns version |
| 99 | */ |
| 100 | |
| 101 | static inline of_version_t |
| 102 | of_message_version_get(of_message_t msg) { |
| 103 | return (of_version_t)msg[OF_MESSAGE_VERSION_OFFSET]; |
| 104 | } |
| 105 | |
| 106 | static inline void |
| 107 | of_message_version_set(of_message_t msg, of_version_t version) { |
| 108 | buf_u8_set(msg, (uint8_t)version); |
| 109 | } |
| 110 | |
| 111 | /** |
| 112 | * @brief Get/set OpenFlow type of a message |
| 113 | * @param msg Pointer to the message buffer of sufficient length |
| 114 | * @param value Data for set operation |
| 115 | * @returns get returns message type |
| 116 | */ |
| 117 | |
| 118 | static inline uint8_t |
| 119 | of_message_type_get(of_message_t msg) { |
| 120 | return msg[OF_MESSAGE_TYPE_OFFSET]; |
| 121 | } |
| 122 | |
| 123 | static inline void |
| 124 | of_message_type_set(of_message_t msg, uint8_t value) { |
| 125 | buf_u8_set(msg + OF_MESSAGE_TYPE_OFFSET, value); |
| 126 | } |
| 127 | |
| 128 | /** |
| 129 | * @brief Get/set in-buffer length of a message |
| 130 | * @param msg Pointer to the message buffer of sufficient length |
| 131 | * @param len Data for set operation |
| 132 | * @returns get returns length in host order |
| 133 | */ |
| 134 | |
| 135 | static inline uint16_t |
| 136 | of_message_length_get(of_message_t msg) { |
| 137 | uint16_t val; |
| 138 | buf_u16_get(msg + OF_MESSAGE_LENGTH_OFFSET, &val); |
| 139 | return val; |
| 140 | } |
| 141 | |
| 142 | static inline void |
| 143 | of_message_length_set(of_message_t msg, uint16_t len) { |
| 144 | buf_u16_set(msg + OF_MESSAGE_LENGTH_OFFSET, len); |
| 145 | } |
| 146 | |
| 147 | |
| 148 | /** |
| 149 | * @brief Get/set transaction ID of a message |
| 150 | * @param msg Pointer to the message buffer of sufficient length |
| 151 | * @param xid Data for set operation |
| 152 | * @returns get returns xid in host order |
| 153 | */ |
| 154 | |
| 155 | static inline uint32_t |
| 156 | of_message_xid_get(of_message_t msg) { |
| 157 | uint32_t val; |
| 158 | buf_u32_get(msg + OF_MESSAGE_XID_OFFSET, &val); |
| 159 | return val; |
| 160 | } |
| 161 | |
| 162 | static inline void |
| 163 | of_message_xid_set(of_message_t msg, uint32_t xid) { |
| 164 | buf_u32_set(msg + OF_MESSAGE_XID_OFFSET, xid); |
| 165 | } |
| 166 | |
| 167 | /** |
| 168 | * @brief Get/set stats type of a message |
| 169 | * @param msg Pointer to the message buffer of sufficient length |
| 170 | * @param type Data for set operation |
| 171 | * @returns get returns stats type in host order |
| 172 | */ |
| 173 | |
| 174 | static inline uint16_t |
| 175 | of_message_stats_type_get(of_message_t msg) { |
| 176 | uint16_t val; |
| 177 | buf_u16_get(msg + OF_MESSAGE_STATS_TYPE_OFFSET, &val); |
| 178 | return val; |
| 179 | } |
| 180 | |
| 181 | static inline void |
| 182 | of_message_stats_type_set(of_message_t msg, uint16_t type) { |
| 183 | buf_u16_set(msg + OF_MESSAGE_STATS_TYPE_OFFSET, type); |
| 184 | } |
| 185 | |
Rob Vaterlaus | b3f49d9 | 2013-10-01 17:57:31 -0700 | [diff] [blame] | 186 | /** |
| 187 | * @brief Get/set error type of a message |
| 188 | * @param msg Pointer to the message buffer of sufficient length |
| 189 | * @param type Data for set operation |
| 190 | * @returns get returns error type in host order |
| 191 | */ |
| 192 | |
| 193 | static inline uint16_t |
| 194 | of_message_error_type_get(of_message_t msg) { |
| 195 | uint16_t val; |
| 196 | buf_u16_get(msg + OF_MESSAGE_ERROR_TYPE_OFFSET, &val); |
| 197 | return val; |
| 198 | } |
| 199 | |
| 200 | static inline void |
| 201 | of_message_error_type_set(of_message_t msg, uint16_t type) { |
| 202 | buf_u16_set(msg + OF_MESSAGE_ERROR_TYPE_OFFSET, type); |
| 203 | } |
| 204 | |
Rich Lane | a06d0c3 | 2013-03-25 08:52:03 -0700 | [diff] [blame] | 205 | |
| 206 | /** |
| 207 | * @brief Get/set experimenter ID of a message |
| 208 | * @param msg Pointer to the message buffer of sufficient length |
| 209 | * @param experimenter_id Data for set operation |
| 210 | * @returns get returns experimenter id in host order |
| 211 | */ |
| 212 | |
| 213 | static inline uint32_t |
| 214 | of_message_experimenter_id_get(of_message_t msg) { |
| 215 | uint32_t val; |
| 216 | buf_u32_get(msg + OF_MESSAGE_EXPERIMENTER_ID_OFFSET, &val); |
| 217 | return val; |
| 218 | } |
| 219 | |
| 220 | static inline void |
| 221 | of_message_experimenter_id_set(of_message_t msg, uint32_t experimenter_id) { |
| 222 | buf_u32_set(msg + OF_MESSAGE_EXPERIMENTER_ID_OFFSET, experimenter_id); |
| 223 | } |
| 224 | |
| 225 | |
| 226 | /** |
| 227 | * @brief Get/set experimenter message type (subtype) of a message |
| 228 | * @param msg Pointer to the message buffer of sufficient length |
| 229 | * @param subtype Data for set operation |
| 230 | * @returns get returns experimenter message type in host order |
| 231 | */ |
| 232 | |
| 233 | static inline uint32_t |
| 234 | of_message_experimenter_subtype_get(of_message_t msg) { |
| 235 | uint32_t val; |
| 236 | buf_u32_get(msg + OF_MESSAGE_EXPERIMENTER_SUBTYPE_OFFSET, &val); |
| 237 | return val; |
| 238 | } |
| 239 | |
| 240 | static inline void |
| 241 | of_message_experimenter_subtype_set(of_message_t msg, |
| 242 | uint32_t subtype) { |
| 243 | buf_u32_set(msg + OF_MESSAGE_EXPERIMENTER_SUBTYPE_OFFSET, |
| 244 | subtype); |
| 245 | } |
| 246 | |
| 247 | /** |
| 248 | * Flow mod command changed from 16 to 8 bits on the wire from 1.0 to 1.1 |
| 249 | */ |
| 250 | static inline uint8_t |
| 251 | of_message_flow_mod_command_get(of_message_t msg, of_version_t version) { |
| 252 | uint16_t val16; |
| 253 | uint8_t val8; |
| 254 | |
| 255 | if (version == OF_VERSION_1_0) { |
| 256 | buf_u16_get(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), &val16); |
| 257 | val8 = val16; |
| 258 | } else { |
| 259 | buf_u8_get(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), &val8); |
| 260 | } |
| 261 | return val8; |
| 262 | } |
| 263 | |
| 264 | static inline void |
| 265 | of_message_flow_mod_command_set(of_message_t msg, of_version_t version, |
| 266 | uint8_t command) { |
| 267 | uint16_t val16; |
| 268 | |
| 269 | if (version == OF_VERSION_1_0) { |
| 270 | val16 = command; |
| 271 | buf_u16_set(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), val16); |
| 272 | } else { |
| 273 | buf_u8_set(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), command); |
| 274 | } |
| 275 | } |
| 276 | |
Rich Lane | 353a79f | 2013-11-13 10:39:56 -0800 | [diff] [blame] | 277 | /** |
| 278 | * @brief Get/set stats request/reply experimenter ID of a message |
| 279 | * @param msg Pointer to the message buffer of sufficient length |
| 280 | * @param experimenter_id Data for set operation |
| 281 | * @returns get returns experimenter id in host order |
| 282 | */ |
| 283 | |
| 284 | static inline uint32_t |
| 285 | of_message_stats_experimenter_id_get(of_message_t msg) { |
| 286 | uint32_t val; |
| 287 | buf_u32_get(msg + OF_MESSAGE_STATS_EXPERIMENTER_ID_OFFSET, &val); |
| 288 | return val; |
| 289 | } |
| 290 | |
| 291 | static inline void |
| 292 | of_message_stats_experimenter_id_set(of_message_t msg, uint32_t experimenter_id) { |
| 293 | buf_u32_set(msg + OF_MESSAGE_STATS_EXPERIMENTER_ID_OFFSET, experimenter_id); |
| 294 | } |
| 295 | |
| 296 | /** |
| 297 | * @brief Get/set stats request/reply experimenter subtype of a message |
| 298 | * @param msg Pointer to the message buffer of sufficient length |
| 299 | * @param subtype Data for set operation |
| 300 | * @returns get returns experimenter subtype in host order |
| 301 | */ |
| 302 | |
| 303 | static inline uint32_t |
| 304 | of_message_stats_experimenter_subtype_get(of_message_t msg) { |
| 305 | uint32_t val; |
| 306 | buf_u32_get(msg + OF_MESSAGE_STATS_EXPERIMENTER_SUBTYPE_OFFSET, &val); |
| 307 | return val; |
| 308 | } |
| 309 | |
| 310 | static inline void |
| 311 | of_message_stats_experimenter_subtype_set(of_message_t msg, uint32_t subtype) { |
| 312 | buf_u32_set(msg + OF_MESSAGE_STATS_EXPERIMENTER_SUBTYPE_OFFSET, subtype); |
| 313 | } |
| 314 | |
Rich Lane | a06d0c3 | 2013-03-25 08:52:03 -0700 | [diff] [blame] | 315 | #endif /* _OF_MESSAGE_H_ */ |