Rich Lane | 2226ae7 | 2013-12-15 13:48:29 -0800 | [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 | :: include('_copyright.c') |
| 28 | #include <loci/loci.h> |
| 29 | #include <loci/of_object.h> |
| 30 | #include "loci_log.h" |
| 31 | #include "loci_int.h" |
| 32 | |
| 33 | /* Flow stats entry setup for all versions */ |
| 34 | |
| 35 | static int |
| 36 | flow_stats_entry_setup_from_flow_add_common(of_flow_stats_entry_t *obj, |
| 37 | of_flow_add_t *flow_add, |
| 38 | of_object_t *effects, |
| 39 | int entry_match_offset, |
| 40 | int add_match_offset) |
| 41 | { |
| 42 | int entry_len, add_len; |
| 43 | of_wire_buffer_t *wbuf; |
| 44 | int abs_offset; |
| 45 | int delta; |
| 46 | uint16_t val16; |
| 47 | uint64_t cookie; |
| 48 | of_octets_t match_octets; |
| 49 | |
| 50 | /* Transfer the match underlying object from add to stats entry */ |
| 51 | wbuf = OF_OBJECT_TO_WBUF(obj); |
| 52 | entry_len = _WIRE_MATCH_PADDED_LEN(obj, entry_match_offset); |
| 53 | add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset); |
| 54 | |
| 55 | match_octets.bytes = add_len; |
| 56 | match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset); |
| 57 | |
| 58 | /* Copy data into flow entry */ |
| 59 | abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, entry_match_offset); |
| 60 | of_wire_buffer_replace_data(wbuf, abs_offset, entry_len, |
| 61 | match_octets.data, add_len); |
| 62 | |
| 63 | /* Not scalar, update lengths if needed */ |
| 64 | delta = add_len - entry_len; |
| 65 | if (delta != 0) { |
| 66 | /* Update parent(s) */ |
| 67 | of_object_parent_length_update((of_object_t *)obj, delta); |
| 68 | } |
| 69 | |
| 70 | of_flow_add_cookie_get(flow_add, &cookie); |
| 71 | of_flow_stats_entry_cookie_set(obj, cookie); |
| 72 | |
| 73 | of_flow_add_priority_get(flow_add, &val16); |
| 74 | of_flow_stats_entry_priority_set(obj, val16); |
| 75 | |
| 76 | of_flow_add_idle_timeout_get(flow_add, &val16); |
| 77 | of_flow_stats_entry_idle_timeout_set(obj, val16); |
| 78 | |
| 79 | of_flow_add_hard_timeout_get(flow_add, &val16); |
| 80 | of_flow_stats_entry_hard_timeout_set(obj, val16); |
| 81 | |
| 82 | /* Effects may come from different places */ |
| 83 | if (effects != NULL) { |
| 84 | if (obj->version == OF_VERSION_1_0) { |
| 85 | OF_TRY(of_flow_stats_entry_actions_set(obj, |
| 86 | (of_list_action_t *)effects)); |
| 87 | } else { |
| 88 | OF_TRY(of_flow_stats_entry_instructions_set(obj, |
| 89 | (of_list_instruction_t *)effects)); |
| 90 | } |
| 91 | } else { |
| 92 | if (obj->version == OF_VERSION_1_0) { |
| 93 | of_list_action_t actions; |
| 94 | of_flow_add_actions_bind(flow_add, &actions); |
| 95 | OF_TRY(of_flow_stats_entry_actions_set(obj, &actions)); |
| 96 | } else { |
| 97 | of_list_instruction_t instructions; |
| 98 | of_flow_add_instructions_bind(flow_add, &instructions); |
| 99 | OF_TRY(of_flow_stats_entry_instructions_set(obj, &instructions)); |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | return OF_ERROR_NONE; |
| 104 | } |
| 105 | |
| 106 | /* Flow removed setup for all versions */ |
| 107 | |
| 108 | static int |
| 109 | flow_removed_setup_from_flow_add_common(of_flow_removed_t *obj, |
| 110 | of_flow_add_t *flow_add, |
| 111 | int removed_match_offset, |
| 112 | int add_match_offset) |
| 113 | { |
| 114 | int add_len, removed_len; |
| 115 | of_wire_buffer_t *wbuf; |
| 116 | int abs_offset; |
| 117 | int delta; |
| 118 | uint16_t val16; |
| 119 | uint64_t cookie; |
| 120 | of_octets_t match_octets; |
| 121 | |
| 122 | /* Transfer the match underlying object from add to removed obj */ |
| 123 | wbuf = OF_OBJECT_TO_WBUF(obj); |
| 124 | removed_len = _WIRE_MATCH_PADDED_LEN(obj, removed_match_offset); |
| 125 | add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset); |
| 126 | |
| 127 | match_octets.bytes = add_len; |
| 128 | match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset); |
| 129 | |
| 130 | /* Copy data into flow removed */ |
| 131 | abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, removed_match_offset); |
| 132 | of_wire_buffer_replace_data(wbuf, abs_offset, removed_len, |
| 133 | match_octets.data, add_len); |
| 134 | |
| 135 | /* Not scalar, update lengths if needed */ |
| 136 | delta = add_len - removed_len; |
| 137 | if (delta != 0) { |
| 138 | /* Update parent(s) */ |
| 139 | of_object_parent_length_update((of_object_t *)obj, delta); |
| 140 | } |
| 141 | |
| 142 | of_flow_add_cookie_get(flow_add, &cookie); |
| 143 | of_flow_removed_cookie_set(obj, cookie); |
| 144 | |
| 145 | of_flow_add_priority_get(flow_add, &val16); |
| 146 | of_flow_removed_priority_set(obj, val16); |
| 147 | |
| 148 | of_flow_add_idle_timeout_get(flow_add, &val16); |
| 149 | of_flow_removed_idle_timeout_set(obj, val16); |
| 150 | |
| 151 | if (obj->version >= OF_VERSION_1_2) { |
| 152 | of_flow_add_hard_timeout_get(flow_add, &val16); |
| 153 | of_flow_removed_hard_timeout_set(obj, val16); |
| 154 | } |
| 155 | |
| 156 | return OF_ERROR_NONE; |
| 157 | } |
| 158 | |
| 159 | /* Set up a flow removed message from the original add */ |
| 160 | |
| 161 | int |
| 162 | of_flow_removed_setup_from_flow_add(of_flow_removed_t *obj, |
| 163 | of_flow_add_t *flow_add) |
| 164 | { |
| 165 | switch (obj->version) { |
| 166 | case OF_VERSION_1_0: |
| 167 | return flow_removed_setup_from_flow_add_common(obj, flow_add, |
| 168 | 8, 8); |
| 169 | break; |
| 170 | case OF_VERSION_1_1: |
| 171 | case OF_VERSION_1_2: |
| 172 | case OF_VERSION_1_3: |
| 173 | return flow_removed_setup_from_flow_add_common(obj, flow_add, |
| 174 | 48, 48); |
| 175 | break; |
| 176 | default: |
| 177 | return OF_ERROR_VERSION; |
| 178 | break; |
| 179 | } |
| 180 | |
| 181 | return OF_ERROR_NONE; |
| 182 | } |
| 183 | |
| 184 | |
| 185 | /* Set up a packet in message from the original add */ |
| 186 | |
| 187 | int |
| 188 | of_packet_in_setup_from_flow_add(of_packet_in_t *obj, |
| 189 | of_flow_add_t *flow_add) |
| 190 | { |
| 191 | int add_len, pkt_in_len; |
| 192 | of_wire_buffer_t *wbuf; |
| 193 | int abs_offset; |
| 194 | int delta; |
| 195 | const int pkt_in_match_offset = 16; |
| 196 | const int add_match_offset = 48; |
| 197 | of_octets_t match_octets; |
| 198 | |
| 199 | if (obj->version < OF_VERSION_1_2) { |
| 200 | /* Nothing to be done before OF 1.2 */ |
| 201 | return OF_ERROR_NONE; |
| 202 | } |
| 203 | |
| 204 | /* Transfer match struct from flow add to packet in object */ |
| 205 | wbuf = OF_OBJECT_TO_WBUF(obj); |
| 206 | pkt_in_len = _WIRE_MATCH_PADDED_LEN(obj, pkt_in_match_offset); |
| 207 | add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset); |
| 208 | |
| 209 | match_octets.bytes = add_len; |
| 210 | match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset); |
| 211 | |
| 212 | /* Copy data into pkt_in msg */ |
| 213 | abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, pkt_in_match_offset); |
| 214 | of_wire_buffer_replace_data(wbuf, abs_offset, pkt_in_len, |
| 215 | match_octets.data, add_len); |
| 216 | |
| 217 | /* Not scalar, update lengths if needed */ |
| 218 | delta = add_len - pkt_in_len; |
| 219 | if (delta != 0) { |
| 220 | /* Update parent(s) */ |
| 221 | of_object_parent_length_update((of_object_t *)obj, delta); |
| 222 | } |
| 223 | |
| 224 | return OF_ERROR_NONE; |
| 225 | } |
| 226 | |
| 227 | /* Set up a stats entry from the original add */ |
| 228 | |
| 229 | int |
| 230 | of_flow_stats_entry_setup_from_flow_add(of_flow_stats_entry_t *obj, |
| 231 | of_flow_add_t *flow_add, |
| 232 | of_object_t *effects) |
| 233 | { |
| 234 | switch (obj->version) { |
| 235 | case OF_VERSION_1_0: |
| 236 | return flow_stats_entry_setup_from_flow_add_common(obj, flow_add, |
| 237 | effects, 4, 8); |
| 238 | break; |
| 239 | case OF_VERSION_1_1: |
| 240 | case OF_VERSION_1_2: |
| 241 | case OF_VERSION_1_3: |
| 242 | return flow_stats_entry_setup_from_flow_add_common(obj, flow_add, |
| 243 | effects, 48, 48); |
| 244 | break; |
| 245 | default: |
| 246 | return OF_ERROR_VERSION; |
| 247 | } |
| 248 | |
| 249 | return OF_ERROR_NONE; |
| 250 | } |