blob: 5f63d29fe711c65392560fad16e236e498a89f75 [file] [log] [blame]
Rich Lane2226ae72013-12-15 13:48:29 -08001:: # 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
35static int
36flow_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
108static int
109flow_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
161int
162of_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
187int
188of_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
229int
230of_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}