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 | :: |
| 28 | /* Copyright 2013, Big Switch Networks, Inc. */ |
| 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 |
| 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 | |
| 95 | static inline of_version_t |
| 96 | of_message_version_get(of_message_t msg) { |
| 97 | return (of_version_t)msg[OF_MESSAGE_VERSION_OFFSET]; |
| 98 | } |
| 99 | |
| 100 | static inline void |
| 101 | of_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 | |
| 112 | static inline uint8_t |
| 113 | of_message_type_get(of_message_t msg) { |
| 114 | return msg[OF_MESSAGE_TYPE_OFFSET]; |
| 115 | } |
| 116 | |
| 117 | static inline void |
| 118 | of_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 | |
| 129 | static inline uint16_t |
| 130 | of_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 | |
| 136 | static inline void |
| 137 | of_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 | |
| 149 | static inline uint32_t |
| 150 | of_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 | |
| 156 | static inline void |
| 157 | of_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 | |
| 168 | static inline uint16_t |
| 169 | of_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 | |
| 175 | static inline void |
| 176 | of_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 | |
| 188 | static inline uint32_t |
| 189 | of_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 | |
| 195 | static inline void |
| 196 | of_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 | |
| 208 | static inline uint32_t |
| 209 | of_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 | |
| 215 | static inline void |
| 216 | of_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 | */ |
| 225 | static inline uint8_t |
| 226 | of_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 | |
| 239 | static inline void |
| 240 | of_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_ */ |