]>
Commit | Line | Data |
---|---|---|
f25d0cf3 | 1 | /* |
72fe7578 | 2 | * Copyright (c) 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. |
f25d0cf3 BP |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at: | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
b598f214 BW |
17 | #ifndef OPENVSWITCH_OFP_ACTIONS_H |
18 | #define OPENVSWITCH_OFP_ACTIONS_H 1 | |
f25d0cf3 | 19 | |
7fdb60a7 | 20 | #include <stddef.h> |
f25d0cf3 | 21 | #include <stdint.h> |
f25d0cf3 BP |
22 | #include "openflow/openflow.h" |
23 | #include "openflow/nicira-ext.h" | |
b598f214 | 24 | #include "openvswitch/meta-flow.h" |
e03c096d | 25 | #include "openvswitch/ofp-errors.h" |
0d71302e | 26 | #include "openvswitch/ofp-protocol.h" |
f25d0cf3 | 27 | #include "openvswitch/types.h" |
f839892a | 28 | #include "openvswitch/ofp-ed-props.h" |
f25d0cf3 | 29 | |
ec30ca5f BP |
30 | #ifdef __cplusplus |
31 | extern "C" { | |
32 | #endif | |
33 | ||
aafee638 YHW |
34 | struct vl_mff_map; |
35 | ||
f25d0cf3 BP |
36 | /* List of OVS abstracted actions. |
37 | * | |
38 | * This macro is used directly only internally by this header, but the list is | |
39 | * still of interest to developers. | |
40 | * | |
08d1e234 | 41 | * Each OFPACT invocation has the following parameters: |
f25d0cf3 BP |
42 | * |
43 | * 1. <ENUM>, used below in the enum definition of OFPACT_<ENUM>, and | |
44 | * elsewhere. | |
45 | * | |
46 | * 2. <STRUCT> corresponding to a structure "struct <STRUCT>", that must be | |
47 | * defined below. This structure must be an abstract definition of the | |
48 | * action. Its first member must have type "struct ofpact" and name | |
49 | * "ofpact". It may be fixed length or end with a flexible array member | |
50 | * (e.g. "int member[];"). | |
51 | * | |
52 | * 3. <MEMBER>, which has one of two possible values: | |
53 | * | |
54 | * - If "struct <STRUCT>" is fixed-length, it must be "ofpact". | |
55 | * | |
56 | * - If "struct <STRUCT>" is variable-length, it must be the name of the | |
57 | * flexible array member. | |
08d1e234 BP |
58 | * |
59 | * 4. <NAME>, a quoted string that gives the name of the action, for use in | |
60 | * parsing actions from text. | |
f25d0cf3 | 61 | */ |
08d1e234 BP |
62 | #define OFPACTS \ |
63 | /* Output. */ \ | |
64 | OFPACT(OUTPUT, ofpact_output, ofpact, "output") \ | |
65 | OFPACT(GROUP, ofpact_group, ofpact, "group") \ | |
bdcad671 | 66 | OFPACT(CONTROLLER, ofpact_controller, userdata, "controller") \ |
08d1e234 BP |
67 | OFPACT(ENQUEUE, ofpact_enqueue, ofpact, "enqueue") \ |
68 | OFPACT(OUTPUT_REG, ofpact_output_reg, ofpact, "output_reg") \ | |
69 | OFPACT(BUNDLE, ofpact_bundle, slaves, "bundle") \ | |
70 | \ | |
71 | /* Header changes. */ \ | |
72 | OFPACT(SET_FIELD, ofpact_set_field, ofpact, "set_field") \ | |
73 | OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact, "set_vlan_vid") \ | |
74 | OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact, "set_vlan_pcp") \ | |
75 | OFPACT(STRIP_VLAN, ofpact_null, ofpact, "strip_vlan") \ | |
f0fb825a | 76 | OFPACT(PUSH_VLAN, ofpact_push_vlan, ofpact, "push_vlan") \ |
08d1e234 BP |
77 | OFPACT(SET_ETH_SRC, ofpact_mac, ofpact, "mod_dl_src") \ |
78 | OFPACT(SET_ETH_DST, ofpact_mac, ofpact, "mod_dl_dst") \ | |
79 | OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact, "mod_nw_src") \ | |
80 | OFPACT(SET_IPV4_DST, ofpact_ipv4, ofpact, "mod_nw_dst") \ | |
81 | OFPACT(SET_IP_DSCP, ofpact_dscp, ofpact, "mod_nw_tos") \ | |
82 | OFPACT(SET_IP_ECN, ofpact_ecn, ofpact, "mod_nw_ecn") \ | |
83 | OFPACT(SET_IP_TTL, ofpact_ip_ttl, ofpact, "mod_nw_ttl") \ | |
84 | OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact, "mod_tp_src") \ | |
85 | OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact, "mod_tp_dst") \ | |
86 | OFPACT(REG_MOVE, ofpact_reg_move, ofpact, "move") \ | |
08d1e234 BP |
87 | OFPACT(STACK_PUSH, ofpact_stack, ofpact, "push") \ |
88 | OFPACT(STACK_POP, ofpact_stack, ofpact, "pop") \ | |
89 | OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids, "dec_ttl") \ | |
90 | OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact, "set_mpls_label") \ | |
91 | OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact, "set_mpls_tc") \ | |
92 | OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact, "set_mpls_ttl") \ | |
93 | OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact, "dec_mpls_ttl") \ | |
94 | OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact, "push_mpls") \ | |
95 | OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact, "pop_mpls") \ | |
491e05c2 | 96 | OFPACT(DEC_NSH_TTL, ofpact_null, ofpact, "dec_nsh_ttl") \ |
08d1e234 | 97 | \ |
f839892a JS |
98 | /* Generic encap & decap */ \ |
99 | OFPACT(ENCAP, ofpact_encap, props, "encap") \ | |
100 | OFPACT(DECAP, ofpact_decap, ofpact, "decap") \ | |
101 | \ | |
08d1e234 BP |
102 | /* Metadata. */ \ |
103 | OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact, "set_tunnel") \ | |
104 | OFPACT(SET_QUEUE, ofpact_queue, ofpact, "set_queue") \ | |
105 | OFPACT(POP_QUEUE, ofpact_null, ofpact, "pop_queue") \ | |
106 | OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact, "fin_timeout") \ | |
107 | \ | |
108 | /* Flow table interaction. */ \ | |
109 | OFPACT(RESUBMIT, ofpact_resubmit, ofpact, "resubmit") \ | |
110 | OFPACT(LEARN, ofpact_learn, specs, "learn") \ | |
18080541 | 111 | OFPACT(CONJUNCTION, ofpact_conjunction, ofpact, "conjunction") \ |
08d1e234 BP |
112 | \ |
113 | /* Arithmetic. */ \ | |
114 | OFPACT(MULTIPATH, ofpact_multipath, ofpact, "multipath") \ | |
115 | \ | |
116 | /* Other. */ \ | |
117 | OFPACT(NOTE, ofpact_note, data, "note") \ | |
118 | OFPACT(EXIT, ofpact_null, ofpact, "exit") \ | |
119 | OFPACT(SAMPLE, ofpact_sample, ofpact, "sample") \ | |
e672ff9b | 120 | OFPACT(UNROLL_XLATE, ofpact_unroll_xlate, ofpact, "unroll_xlate") \ |
07659514 | 121 | OFPACT(CT, ofpact_conntrack, ofpact, "ct") \ |
72fe7578 | 122 | OFPACT(CT_CLEAR, ofpact_null, ofpact, "ct_clear") \ |
9ac0aada | 123 | OFPACT(NAT, ofpact_nat, ofpact, "nat") \ |
aaca4fe0 | 124 | OFPACT(OUTPUT_TRUNC, ofpact_output_trunc,ofpact, "output_trunc") \ |
7ae62a67 | 125 | OFPACT(CLONE, ofpact_nest, actions, "clone") \ |
08d1e234 | 126 | \ |
d4abaff5 BP |
127 | /* Debugging actions. \ |
128 | * \ | |
129 | * These are intentionally undocumented, subject to change, and \ | |
130 | * only accepted if ovs-vswitchd is started with --enable-dummy. */ \ | |
131 | OFPACT(DEBUG_RECIRC, ofpact_null, ofpact, "debug_recirc") \ | |
a934a3dd | 132 | OFPACT(DEBUG_SLOW, ofpact_null, ofpact, "debug_slow") \ |
d4abaff5 | 133 | \ |
08d1e234 BP |
134 | /* Instructions. */ \ |
135 | OFPACT(METER, ofpact_meter, ofpact, "meter") \ | |
136 | OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact, "clear_actions") \ | |
0763bf08 | 137 | OFPACT(WRITE_ACTIONS, ofpact_nest, actions, "write_actions") \ |
08d1e234 BP |
138 | OFPACT(WRITE_METADATA, ofpact_metadata, ofpact, "write_metadata") \ |
139 | OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact, "goto_table") | |
f25d0cf3 BP |
140 | |
141 | /* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */ | |
142 | enum OVS_PACKED_ENUM ofpact_type { | |
08d1e234 | 143 | #define OFPACT(ENUM, STRUCT, MEMBER, NAME) OFPACT_##ENUM, |
f25d0cf3 | 144 | OFPACTS |
08d1e234 | 145 | #undef OFPACT |
f25d0cf3 BP |
146 | }; |
147 | ||
08d1e234 | 148 | /* Define N_OFPACTS to the number of types of ofpacts. */ |
f25d0cf3 | 149 | enum { |
08d1e234 BP |
150 | #define OFPACT(ENUM, STRUCT, MEMBER, NAME) + 1 |
151 | N_OFPACTS = OFPACTS | |
152 | #undef OFPACT | |
f25d0cf3 BP |
153 | }; |
154 | ||
155 | /* Header for an action. | |
156 | * | |
157 | * Each action is a structure "struct ofpact_*" that begins with "struct | |
158 | * ofpact", usually followed by other data that describes the action. Actions | |
2ac3c572 BP |
159 | * are padded out to a multiple of OFPACT_ALIGNTO bytes in length. |
160 | * | |
c2d936a4 | 161 | * The 'raw' member is special: |
2ac3c572 BP |
162 | * |
163 | * - Most "struct ofpact"s correspond to one particular kind of OpenFlow | |
164 | * action, at least in a given OpenFlow version. For example, | |
165 | * OFPACT_SET_VLAN_VID corresponds to OFPAT10_SET_VLAN_VID in OpenFlow | |
166 | * 1.0. | |
167 | * | |
c2d936a4 | 168 | * For such actions, the 'raw' member is not meaningful and generally |
2ac3c572 BP |
169 | * should be zero. |
170 | * | |
171 | * - A few "struct ofpact"s correspond to multiple OpenFlow actions. For | |
172 | * example, OFPACT_SET_TUNNEL can be NXAST_SET_TUNNEL or | |
173 | * NXAST_SET_TUNNEL64. In these cases, if the "struct ofpact" originated | |
174 | * from OpenFlow, then we want to make sure that, if it gets translated | |
175 | * back to OpenFlow later, it is translated back to the same action type. | |
7c9afefd SF |
176 | * (Otherwise, we'd violate the promise made in the topics/design doc, in |
177 | * the "Action Reproduction" section.) | |
2ac3c572 | 178 | * |
c2d936a4 BP |
179 | * For such actions, the 'raw' member should be the "enum ofp_raw_action" |
180 | * originally extracted from the OpenFlow action. (If the action didn't | |
181 | * originate from OpenFlow, then setting 'raw' to zero should be fine: | |
182 | * code to translate the ofpact to OpenFlow must tolerate this case.) | |
2ac3c572 | 183 | */ |
6b2b63d0 | 184 | struct ofpact { |
80a73e71 BP |
185 | /* We want the space advantage of an 8-bit type here on every |
186 | * implementation, without giving up the advantage of having a useful type | |
187 | * on implementations that support packed enums. */ | |
188 | #ifdef HAVE_PACKED_ENUM | |
f25d0cf3 | 189 | enum ofpact_type type; /* OFPACT_*. */ |
80a73e71 BP |
190 | #else |
191 | uint8_t type; /* OFPACT_* */ | |
192 | #endif | |
193 | ||
c2d936a4 | 194 | uint8_t raw; /* Original type when added, if any. */ |
f25d0cf3 BP |
195 | uint16_t len; /* Length of the action, in bytes, including |
196 | * struct ofpact, excluding padding. */ | |
197 | }; | |
6b2b63d0 JR |
198 | BUILD_ASSERT_DECL(sizeof(struct ofpact) == 4); |
199 | ||
200 | /* Alignment. */ | |
201 | #define OFPACT_ALIGNTO 8 | |
202 | #define OFPACT_ALIGN(SIZE) ROUND_UP(SIZE, OFPACT_ALIGNTO) | |
7b512955 | 203 | #define OFPACT_PADDED_MEMBERS(MEMBERS) PADDED_MEMBERS(OFPACT_ALIGNTO, MEMBERS) |
9193d145 | 204 | |
4f20179d | 205 | /* Returns the ofpact following 'ofpact'. */ |
f25d0cf3 BP |
206 | static inline struct ofpact * |
207 | ofpact_next(const struct ofpact *ofpact) | |
208 | { | |
9965bc0b BP |
209 | return ALIGNED_CAST(struct ofpact *, |
210 | (uint8_t *) ofpact + OFPACT_ALIGN(ofpact->len)); | |
f25d0cf3 BP |
211 | } |
212 | ||
4f20179d BP |
213 | struct ofpact *ofpact_next_flattened(const struct ofpact *); |
214 | ||
f25d0cf3 BP |
215 | static inline struct ofpact * |
216 | ofpact_end(const struct ofpact *ofpacts, size_t ofpacts_len) | |
217 | { | |
9965bc0b | 218 | return ALIGNED_CAST(struct ofpact *, (uint8_t *) ofpacts + ofpacts_len); |
f25d0cf3 BP |
219 | } |
220 | ||
feee58b9 AZ |
221 | static inline bool |
222 | ofpact_last(const struct ofpact *a, const struct ofpact *ofpacts, | |
223 | size_t ofpact_len) | |
224 | { | |
225 | return ofpact_next(a) == ofpact_end(ofpacts, ofpact_len); | |
226 | } | |
227 | ||
cc099268 JR |
228 | static inline const struct ofpact * |
229 | ofpact_find_type_flattened(const struct ofpact *a, enum ofpact_type type, | |
230 | const struct ofpact * const end) | |
231 | { | |
232 | while (a < end) { | |
233 | if (a->type == type) { | |
234 | return a; | |
235 | } | |
236 | a = ofpact_next_flattened(a); | |
237 | } | |
238 | return NULL; | |
239 | } | |
240 | ||
241 | #define OFPACT_FIND_TYPE_FLATTENED(A, TYPE, END) \ | |
242 | ofpact_get_##TYPE##_nullable( \ | |
243 | ofpact_find_type_flattened(A, OFPACT_##TYPE, END)) | |
244 | ||
f25d0cf3 BP |
245 | /* Assigns POS to each ofpact, in turn, in the OFPACTS_LEN bytes of ofpacts |
246 | * starting at OFPACTS. */ | |
247 | #define OFPACT_FOR_EACH(POS, OFPACTS, OFPACTS_LEN) \ | |
248 | for ((POS) = (OFPACTS); (POS) < ofpact_end(OFPACTS, OFPACTS_LEN); \ | |
249 | (POS) = ofpact_next(POS)) | |
4f20179d BP |
250 | |
251 | /* Assigns POS to each ofpact, in turn, in the OFPACTS_LEN bytes of ofpacts | |
252 | * starting at OFPACTS. | |
253 | * | |
254 | * For ofpacts that contain nested ofpacts, this visits each of the inner | |
255 | * ofpacts as well. */ | |
256 | #define OFPACT_FOR_EACH_FLATTENED(POS, OFPACTS, OFPACTS_LEN) \ | |
257 | for ((POS) = (OFPACTS); (POS) < ofpact_end(OFPACTS, OFPACTS_LEN); \ | |
258 | (POS) = ofpact_next_flattened(POS)) | |
cc099268 JR |
259 | |
260 | #define OFPACT_FOR_EACH_TYPE_FLATTENED(POS, TYPE, OFPACTS, OFPACTS_LEN) \ | |
261 | for ((POS) = OFPACT_FIND_TYPE_FLATTENED(OFPACTS, TYPE, \ | |
262 | ofpact_end(OFPACTS, OFPACTS_LEN)); \ | |
263 | (POS); \ | |
264 | (POS) = OFPACT_FIND_TYPE_FLATTENED( \ | |
265 | ofpact_next_flattened(&(POS)->ofpact), TYPE, \ | |
266 | ofpact_end(OFPACTS, OFPACTS_LEN))) | |
f25d0cf3 BP |
267 | \f |
268 | /* Action structure for each OFPACT_*. */ | |
269 | ||
b19e8793 | 270 | /* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT, OFPACT_CLEAR_ACTIONS. |
f25d0cf3 | 271 | * |
7bcb1506 | 272 | * Used for OFPAT10_STRIP_VLAN, NXAST_POP_QUEUE, NXAST_EXIT, |
8e61c110 | 273 | * OFPAT11_POP_VLAN, OFPIT11_CLEAR_ACTIONS. |
f25d0cf3 BP |
274 | * |
275 | * Action structure for actions that do not have any extra data beyond the | |
276 | * action type. */ | |
277 | struct ofpact_null { | |
278 | struct ofpact ofpact; | |
279 | }; | |
280 | ||
281 | /* OFPACT_OUTPUT. | |
282 | * | |
283 | * Used for OFPAT10_OUTPUT. */ | |
284 | struct ofpact_output { | |
285 | struct ofpact ofpact; | |
4e022ec0 | 286 | ofp_port_t port; /* Output port. */ |
f25d0cf3 BP |
287 | uint16_t max_len; /* Max send len, for port OFPP_CONTROLLER. */ |
288 | }; | |
289 | ||
206ddb9a JP |
290 | #define NX_CTLR_NO_METER 0 |
291 | ||
f25d0cf3 BP |
292 | /* OFPACT_CONTROLLER. |
293 | * | |
294 | * Used for NXAST_CONTROLLER. */ | |
295 | struct ofpact_controller { | |
6335d074 BP |
296 | OFPACT_PADDED_MEMBERS( |
297 | struct ofpact ofpact; | |
298 | uint16_t max_len; /* Max length to send to controller. */ | |
299 | uint16_t controller_id; /* Controller ID to send packet-in. */ | |
300 | enum ofp_packet_in_reason reason; /* Reason to put in packet-in. */ | |
bdcad671 | 301 | |
6335d074 BP |
302 | /* If true, this action freezes packet traversal of the OpenFlow |
303 | * tables and adds a continuation to the packet-in message, that | |
304 | * a controller can use to resume that traversal. */ | |
305 | bool pause; | |
77ab5fd2 | 306 | |
6335d074 BP |
307 | /* Arbitrary data to include in the packet-in message (currently, |
308 | * only in NXT_PACKET_IN2). */ | |
309 | uint16_t userdata_len; | |
206ddb9a JP |
310 | |
311 | /* Meter to which this controller action should be associated. | |
312 | * If requested, this will override a "controller" virtual meter. | |
313 | * A value of NX_CTLR_NO_METER means no meter is requested. */ | |
314 | uint32_t meter_id; | |
315 | uint32_t provider_meter_id; | |
6335d074 BP |
316 | ); |
317 | uint8_t userdata[0]; | |
f25d0cf3 BP |
318 | }; |
319 | ||
320 | /* OFPACT_ENQUEUE. | |
321 | * | |
322 | * Used for OFPAT10_ENQUEUE. */ | |
323 | struct ofpact_enqueue { | |
324 | struct ofpact ofpact; | |
4e022ec0 | 325 | ofp_port_t port; |
f25d0cf3 BP |
326 | uint32_t queue; |
327 | }; | |
328 | ||
329 | /* OFPACT_OUTPUT_REG. | |
330 | * | |
331 | * Used for NXAST_OUTPUT_REG. */ | |
332 | struct ofpact_output_reg { | |
333 | struct ofpact ofpact; | |
f25d0cf3 | 334 | uint16_t max_len; |
dc723c44 | 335 | struct mf_subfield src; |
f25d0cf3 BP |
336 | }; |
337 | ||
aaca4fe0 WT |
338 | /* OFPACT_OUTPUT_TRUNC. |
339 | * | |
340 | * Used for NXAST_OUTPUT_TRUNC. */ | |
341 | struct ofpact_output_trunc { | |
342 | struct ofpact ofpact; | |
343 | ofp_port_t port; /* Output port. */ | |
344 | uint32_t max_len; /* Max send len. */ | |
345 | }; | |
346 | ||
c2d936a4 BP |
347 | /* Bundle slave choice algorithm to apply. |
348 | * | |
349 | * In the descriptions below, 'slaves' is the list of possible slaves in the | |
350 | * order they appear in the OpenFlow action. */ | |
351 | enum nx_bd_algorithm { | |
352 | /* Chooses the first live slave listed in the bundle. | |
353 | * | |
354 | * O(n_slaves) performance. */ | |
355 | NX_BD_ALG_ACTIVE_BACKUP = 0, | |
356 | ||
357 | /* Highest Random Weight. | |
358 | * | |
359 | * for i in [0,n_slaves): | |
360 | * weights[i] = hash(flow, i) | |
361 | * slave = { slaves[i] such that weights[i] >= weights[j] for all j != i } | |
362 | * | |
363 | * Redistributes 1/n_slaves of traffic when a slave's liveness changes. | |
364 | * O(n_slaves) performance. | |
365 | * | |
366 | * Uses the 'fields' and 'basis' parameters. */ | |
367 | NX_BD_ALG_HRW = 1 | |
368 | }; | |
369 | ||
f25d0cf3 BP |
370 | /* OFPACT_BUNDLE. |
371 | * | |
372 | * Used for NXAST_BUNDLE. */ | |
373 | struct ofpact_bundle { | |
374 | struct ofpact ofpact; | |
375 | ||
376 | /* Slave choice algorithm to apply to hash value. */ | |
377 | enum nx_bd_algorithm algorithm; | |
378 | ||
379 | /* What fields to hash and how. */ | |
380 | enum nx_hash_fields fields; | |
381 | uint16_t basis; /* Universal hash parameter. */ | |
382 | ||
383 | struct mf_subfield dst; | |
384 | ||
385 | /* Slaves for output. */ | |
386 | unsigned int n_slaves; | |
4e022ec0 | 387 | ofp_port_t slaves[]; |
f25d0cf3 BP |
388 | }; |
389 | ||
390 | /* OFPACT_SET_VLAN_VID. | |
391 | * | |
ca287d20 JR |
392 | * We keep track if vlan was present at action validation time to avoid a |
393 | * PUSH_VLAN when translating to OpenFlow 1.1+. | |
394 | * | |
395 | * We also keep the originating OFPUTIL action code in ofpact.compat. | |
396 | * | |
397 | * Used for OFPAT10_SET_VLAN_VID and OFPAT11_SET_VLAN_VID. */ | |
f25d0cf3 BP |
398 | struct ofpact_vlan_vid { |
399 | struct ofpact ofpact; | |
400 | uint16_t vlan_vid; /* VLAN VID in low 12 bits, 0 in other bits. */ | |
ca287d20 JR |
401 | bool push_vlan_if_needed; /* OF 1.0 semantics if true. */ |
402 | bool flow_has_vlan; /* VLAN present at action validation time? */ | |
f25d0cf3 BP |
403 | }; |
404 | ||
405 | /* OFPACT_SET_VLAN_PCP. | |
406 | * | |
ca287d20 JR |
407 | * We keep track if vlan was present at action validation time to avoid a |
408 | * PUSH_VLAN when translating to OpenFlow 1.1+. | |
409 | * | |
410 | * We also keep the originating OFPUTIL action code in ofpact.compat. | |
411 | * | |
412 | * Used for OFPAT10_SET_VLAN_PCP and OFPAT11_SET_VLAN_PCP. */ | |
f25d0cf3 BP |
413 | struct ofpact_vlan_pcp { |
414 | struct ofpact ofpact; | |
415 | uint8_t vlan_pcp; /* VLAN PCP in low 3 bits, 0 in other bits. */ | |
ca287d20 JR |
416 | bool push_vlan_if_needed; /* OF 1.0 semantics if true. */ |
417 | bool flow_has_vlan; /* VLAN present at action validation time? */ | |
f25d0cf3 BP |
418 | }; |
419 | ||
f0fb825a EG |
420 | /* OFPACT_PUSH_VLAN. |
421 | * | |
422 | * Used for OFPAT11_PUSH_VLAN. */ | |
423 | struct ofpact_push_vlan { | |
424 | struct ofpact ofpact; | |
425 | ovs_be16 ethertype; | |
426 | }; | |
427 | ||
f25d0cf3 BP |
428 | /* OFPACT_SET_ETH_SRC, OFPACT_SET_ETH_DST. |
429 | * | |
430 | * Used for OFPAT10_SET_DL_SRC, OFPAT10_SET_DL_DST. */ | |
431 | struct ofpact_mac { | |
432 | struct ofpact ofpact; | |
74ff3298 | 433 | struct eth_addr mac; |
f25d0cf3 BP |
434 | }; |
435 | ||
436 | /* OFPACT_SET_IPV4_SRC, OFPACT_SET_IPV4_DST. | |
437 | * | |
438 | * Used for OFPAT10_SET_NW_SRC, OFPAT10_SET_NW_DST. */ | |
439 | struct ofpact_ipv4 { | |
440 | struct ofpact ofpact; | |
441 | ovs_be32 ipv4; | |
442 | }; | |
443 | ||
04f01c24 | 444 | /* OFPACT_SET_IP_DSCP. |
f25d0cf3 BP |
445 | * |
446 | * Used for OFPAT10_SET_NW_TOS. */ | |
447 | struct ofpact_dscp { | |
448 | struct ofpact ofpact; | |
449 | uint8_t dscp; /* DSCP in high 6 bits, rest ignored. */ | |
450 | }; | |
451 | ||
ff14eb7a JR |
452 | /* OFPACT_SET_IP_ECN. |
453 | * | |
454 | * Used for OFPAT11_SET_NW_ECN. */ | |
455 | struct ofpact_ecn { | |
456 | struct ofpact ofpact; | |
457 | uint8_t ecn; /* ECN in low 2 bits, rest ignored. */ | |
458 | }; | |
459 | ||
0c20dbe4 JR |
460 | /* OFPACT_SET_IP_TTL. |
461 | * | |
462 | * Used for OFPAT11_SET_NW_TTL. */ | |
463 | struct ofpact_ip_ttl { | |
464 | struct ofpact ofpact; | |
465 | uint8_t ttl; | |
466 | }; | |
467 | ||
f25d0cf3 BP |
468 | /* OFPACT_SET_L4_SRC_PORT, OFPACT_SET_L4_DST_PORT. |
469 | * | |
470 | * Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */ | |
471 | struct ofpact_l4_port { | |
472 | struct ofpact ofpact; | |
1e7db674 JR |
473 | uint16_t port; /* TCP, UDP or SCTP port number. */ |
474 | uint8_t flow_ip_proto; /* IP proto from corresponding match, or 0 */ | |
f25d0cf3 BP |
475 | }; |
476 | ||
477 | /* OFPACT_REG_MOVE. | |
478 | * | |
479 | * Used for NXAST_REG_MOVE. */ | |
480 | struct ofpact_reg_move { | |
481 | struct ofpact ofpact; | |
482 | struct mf_subfield src; | |
483 | struct mf_subfield dst; | |
484 | }; | |
485 | ||
bb9c57d6 | 486 | /* OFPACT_STACK_PUSH, OFPACT_STACK_POP. |
bd85dac1 AZ |
487 | * |
488 | * Used for NXAST_STACK_PUSH and NXAST_STACK_POP. */ | |
489 | struct ofpact_stack { | |
490 | struct ofpact ofpact; | |
491 | struct mf_subfield subfield; | |
492 | }; | |
493 | ||
b2dd70be JR |
494 | /* OFPACT_SET_FIELD. |
495 | * | |
7eb4b1f1 | 496 | * Used for NXAST_REG_LOAD and OFPAT12_SET_FIELD. */ |
b2dd70be | 497 | struct ofpact_set_field { |
128684a6 JR |
498 | OFPACT_PADDED_MEMBERS( |
499 | struct ofpact ofpact; | |
500 | bool flow_has_vlan; /* VLAN present at action validation time. */ | |
501 | const struct mf_field *field; | |
502 | ); | |
503 | union mf_value value[]; /* Significant value bytes followed by | |
504 | * significant mask bytes. */ | |
b2dd70be | 505 | }; |
128684a6 JR |
506 | BUILD_ASSERT_DECL(offsetof(struct ofpact_set_field, value) |
507 | % OFPACT_ALIGNTO == 0); | |
508 | BUILD_ASSERT_DECL(offsetof(struct ofpact_set_field, value) | |
509 | == sizeof(struct ofpact_set_field)); | |
510 | ||
511 | /* Use macro to not have to deal with constness. */ | |
512 | #define ofpact_set_field_mask(SF) \ | |
513 | ALIGNED_CAST(union mf_value *, \ | |
514 | (uint8_t *)(SF)->value + (SF)->field->n_bytes) | |
b2dd70be | 515 | |
b02475c5 SH |
516 | /* OFPACT_PUSH_VLAN/MPLS/PBB |
517 | * | |
518 | * Used for NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */ | |
519 | struct ofpact_push_mpls { | |
520 | struct ofpact ofpact; | |
521 | ovs_be16 ethertype; | |
522 | }; | |
523 | ||
524 | /* OFPACT_POP_MPLS | |
525 | * | |
526 | * Used for NXAST_POP_MPLS, OFPAT11_POP_MPLS.. */ | |
527 | struct ofpact_pop_mpls { | |
528 | struct ofpact ofpact; | |
529 | ovs_be16 ethertype; | |
530 | }; | |
531 | ||
f25d0cf3 BP |
532 | /* OFPACT_SET_TUNNEL. |
533 | * | |
534 | * Used for NXAST_SET_TUNNEL, NXAST_SET_TUNNEL64. */ | |
535 | struct ofpact_tunnel { | |
536 | struct ofpact ofpact; | |
537 | uint64_t tun_id; | |
538 | }; | |
539 | ||
540 | /* OFPACT_SET_QUEUE. | |
541 | * | |
542 | * Used for NXAST_SET_QUEUE. */ | |
543 | struct ofpact_queue { | |
544 | struct ofpact ofpact; | |
545 | uint32_t queue_id; | |
546 | }; | |
547 | ||
548 | /* OFPACT_FIN_TIMEOUT. | |
549 | * | |
550 | * Used for NXAST_FIN_TIMEOUT. */ | |
551 | struct ofpact_fin_timeout { | |
552 | struct ofpact ofpact; | |
553 | uint16_t fin_idle_timeout; | |
554 | uint16_t fin_hard_timeout; | |
555 | }; | |
556 | ||
4cceacb9 JS |
557 | /* OFPACT_WRITE_METADATA. |
558 | * | |
559 | * Used for NXAST_WRITE_METADATA. */ | |
560 | struct ofpact_metadata { | |
561 | struct ofpact ofpact; | |
562 | ovs_be64 metadata; | |
563 | ovs_be64 mask; | |
564 | }; | |
565 | ||
638a19b0 JR |
566 | /* OFPACT_METER. |
567 | * | |
568 | * Used for OFPIT13_METER. */ | |
569 | struct ofpact_meter { | |
570 | struct ofpact ofpact; | |
571 | uint32_t meter_id; | |
076caa2f | 572 | uint32_t provider_meter_id; |
638a19b0 JR |
573 | }; |
574 | ||
7ae62a67 | 575 | /* OFPACT_WRITE_ACTIONS, OFPACT_CLONE. |
7fdb60a7 | 576 | * |
7ae62a67 | 577 | * Used for OFPIT11_WRITE_ACTIONS, NXAST_CLONE. */ |
7fdb60a7 | 578 | struct ofpact_nest { |
9193d145 | 579 | OFPACT_PADDED_MEMBERS(struct ofpact ofpact;); |
7fdb60a7 SH |
580 | struct ofpact actions[]; |
581 | }; | |
93904c85 | 582 | BUILD_ASSERT_DECL(offsetof(struct ofpact_nest, actions) % OFPACT_ALIGNTO == 0); |
c2d936a4 BP |
583 | BUILD_ASSERT_DECL(offsetof(struct ofpact_nest, actions) |
584 | == sizeof(struct ofpact_nest)); | |
7fdb60a7 | 585 | |
4b1a2aef BP |
586 | static inline size_t |
587 | ofpact_nest_get_action_len(const struct ofpact_nest *on) | |
588 | { | |
589 | return on->ofpact.len - offsetof(struct ofpact_nest, actions); | |
590 | } | |
591 | ||
07659514 JS |
592 | /* Bits for 'flags' in struct nx_action_conntrack. |
593 | * | |
594 | * If NX_CT_F_COMMIT is set, then the connection entry is moved from the | |
a76a37ef JR |
595 | * unconfirmed to confirmed list in the tracker. |
596 | * If NX_CT_F_FORCE is set, in addition to NX_CT_F_COMMIT, then the conntrack | |
597 | * entry is replaced with a new one in case the original direction of the | |
598 | * existing entry is opposite of the current packet direction. | |
599 | */ | |
07659514 JS |
600 | enum nx_conntrack_flags { |
601 | NX_CT_F_COMMIT = 1 << 0, | |
a76a37ef | 602 | NX_CT_F_FORCE = 1 << 1, |
07659514 JS |
603 | }; |
604 | ||
605 | /* Magic value for struct nx_action_conntrack 'recirc_table' field, to specify | |
606 | * that the packet should not be recirculated. */ | |
607 | #define NX_CT_RECIRC_NONE OFPTT_ALL | |
608 | ||
58e3dd5a | 609 | #if !defined(IPPORT_FTP) |
9f02d70c | 610 | #define IPPORT_FTP 21 |
58e3dd5a YT |
611 | #endif |
612 | ||
40c7b2fc JS |
613 | #if !defined(IPPORT_TFTP) |
614 | #define IPPORT_TFTP 69 | |
615 | #endif | |
616 | ||
07659514 JS |
617 | /* OFPACT_CT. |
618 | * | |
619 | * Used for NXAST_CT. */ | |
620 | struct ofpact_conntrack { | |
9193d145 BP |
621 | OFPACT_PADDED_MEMBERS( |
622 | struct ofpact ofpact; | |
623 | uint16_t flags; | |
624 | uint16_t zone_imm; | |
625 | struct mf_subfield zone_src; | |
626 | uint16_t alg; | |
627 | uint8_t recirc_table; | |
628 | ); | |
c7e69808 | 629 | struct ofpact actions[0]; |
07659514 | 630 | }; |
8e53fe8c JS |
631 | BUILD_ASSERT_DECL(offsetof(struct ofpact_conntrack, actions) |
632 | % OFPACT_ALIGNTO == 0); | |
633 | BUILD_ASSERT_DECL(offsetof(struct ofpact_conntrack, actions) | |
634 | == sizeof(struct ofpact_conntrack)); | |
635 | ||
636 | static inline size_t | |
637 | ofpact_ct_get_action_len(const struct ofpact_conntrack *oc) | |
638 | { | |
639 | return oc->ofpact.len - offsetof(struct ofpact_conntrack, actions); | |
640 | } | |
07659514 | 641 | |
7fdb60a7 SH |
642 | void ofpacts_execute_action_set(struct ofpbuf *action_list, |
643 | const struct ofpbuf *action_set); | |
644 | ||
9ac0aada JR |
645 | /* Bits for 'flags' in struct nx_action_nat. |
646 | */ | |
647 | enum nx_nat_flags { | |
ae8b9260 | 648 | NX_NAT_F_SRC = 1 << 0, /* Mutually exclusive with NX_NAT_F_DST. */ |
9ac0aada JR |
649 | NX_NAT_F_DST = 1 << 1, |
650 | NX_NAT_F_PERSISTENT = 1 << 2, | |
ae8b9260 | 651 | NX_NAT_F_PROTO_HASH = 1 << 3, /* Mutually exclusive with PROTO_RANDOM. */ |
9ac0aada | 652 | NX_NAT_F_PROTO_RANDOM = 1 << 4, |
ae8b9260 | 653 | NX_NAT_F_MASK = (NX_NAT_F_SRC | NX_NAT_F_DST | NX_NAT_F_PERSISTENT | NX_NAT_F_PROTO_HASH | NX_NAT_F_PROTO_RANDOM) |
9ac0aada JR |
654 | }; |
655 | ||
656 | /* OFPACT_NAT. | |
657 | * | |
658 | * Used for NXAST_NAT. */ | |
659 | struct ofpact_nat { | |
660 | struct ofpact ofpact; | |
661 | uint8_t range_af; /* AF_UNSPEC, AF_INET, or AF_INET6 */ | |
662 | uint16_t flags; /* NX_NAT_F_* */ | |
663 | struct { | |
664 | struct { | |
665 | uint16_t min; | |
666 | uint16_t max; | |
667 | } proto; | |
668 | union { | |
669 | struct { | |
670 | ovs_be32 min; | |
671 | ovs_be32 max; | |
672 | } ipv4; | |
673 | struct { | |
674 | struct in6_addr min; | |
675 | struct in6_addr max; | |
676 | } ipv6; | |
677 | } addr; | |
678 | } range; | |
679 | }; | |
680 | ||
681 | ||
f25d0cf3 BP |
682 | /* OFPACT_RESUBMIT. |
683 | * | |
2cd20955 | 684 | * Used for NXAST_RESUBMIT, NXAST_RESUBMIT_TABLE, NXAST_RESUBMIT_TABLE_CT. */ |
f25d0cf3 BP |
685 | struct ofpact_resubmit { |
686 | struct ofpact ofpact; | |
4e022ec0 | 687 | ofp_port_t in_port; |
f25d0cf3 | 688 | uint8_t table_id; |
2cd20955 JR |
689 | bool with_ct_orig; /* Resubmit with Conntrack original direction tuple |
690 | * fields in place of IP header fields. */ | |
f25d0cf3 BP |
691 | }; |
692 | ||
c2d936a4 BP |
693 | /* Bits for 'flags' in struct nx_action_learn. |
694 | * | |
695 | * If NX_LEARN_F_SEND_FLOW_REM is set, then the learned flows will have their | |
696 | * OFPFF_SEND_FLOW_REM flag set. | |
697 | * | |
4c71600d DDP |
698 | * If NX_LEARN_F_WRITE_RESULT is set, then the actions will write whether the |
699 | * learn operation succeded on a bit. If the learn is successful the bit will | |
700 | * be set, otherwise (e.g. if the limit is hit) the bit will be unset. | |
701 | * | |
c2d936a4 BP |
702 | * If NX_LEARN_F_DELETE_LEARNED is set, then removing this action will delete |
703 | * all the flows from the learn action's 'table_id' that have the learn | |
704 | * action's 'cookie'. Important points: | |
705 | * | |
706 | * - The deleted flows include those created by this action, those created | |
707 | * by other learn actions with the same 'table_id' and 'cookie', those | |
708 | * created by flow_mod requests by a controller in the specified table | |
709 | * with the specified cookie, and those created through any other | |
710 | * means. | |
711 | * | |
712 | * - If multiple flows specify "learn" actions with | |
713 | * NX_LEARN_F_DELETE_LEARNED with the same 'table_id' and 'cookie', then | |
714 | * no deletion occurs until all of those "learn" actions are deleted. | |
715 | * | |
716 | * - Deleting a flow that contains a learn action is the most obvious way | |
717 | * to delete a learn action. Modifying a flow's actions, or replacing it | |
718 | * by a new flow, can also delete a learn action. Finally, replacing a | |
719 | * learn action with NX_LEARN_F_DELETE_LEARNED with a learn action | |
720 | * without that flag also effectively deletes the learn action and can | |
721 | * trigger flow deletion. | |
722 | * | |
723 | * NX_LEARN_F_DELETE_LEARNED was added in Open vSwitch 2.4. */ | |
724 | enum nx_learn_flags { | |
725 | NX_LEARN_F_SEND_FLOW_REM = 1 << 0, | |
726 | NX_LEARN_F_DELETE_LEARNED = 1 << 1, | |
4c71600d | 727 | NX_LEARN_F_WRITE_RESULT = 1 << 2, |
c2d936a4 BP |
728 | }; |
729 | ||
730 | #define NX_LEARN_N_BITS_MASK 0x3ff | |
731 | ||
732 | #define NX_LEARN_SRC_FIELD (0 << 13) /* Copy from field. */ | |
733 | #define NX_LEARN_SRC_IMMEDIATE (1 << 13) /* Copy from immediate value. */ | |
734 | #define NX_LEARN_SRC_MASK (1 << 13) | |
735 | ||
736 | #define NX_LEARN_DST_MATCH (0 << 11) /* Add match criterion. */ | |
737 | #define NX_LEARN_DST_LOAD (1 << 11) /* Add NXAST_REG_LOAD action. */ | |
738 | #define NX_LEARN_DST_OUTPUT (2 << 11) /* Add OFPAT_OUTPUT action. */ | |
739 | #define NX_LEARN_DST_RESERVED (3 << 11) /* Not yet defined. */ | |
740 | #define NX_LEARN_DST_MASK (3 << 11) | |
741 | ||
dfe191d5 JR |
742 | /* Part of struct ofpact_learn, below. */ |
743 | struct ofpact_learn_spec { | |
507a9a16 JR |
744 | OFPACT_PADDED_MEMBERS( |
745 | struct mf_subfield src; /* NX_LEARN_SRC_FIELD only. */ | |
746 | struct mf_subfield dst; /* NX_LEARN_DST_MATCH, | |
747 | * NX_LEARN_DST_LOAD only. */ | |
748 | uint16_t src_type; /* One of NX_LEARN_SRC_*. */ | |
749 | uint16_t dst_type; /* One of NX_LEARN_DST_*. */ | |
750 | uint8_t n_bits; /* Number of bits in source and dest. */ | |
751 | ); | |
752 | /* Followed by 'DIV_ROUND_UP(n_bits, 8)' bytes of immediate data for | |
753 | * match 'dst_type's NX_LEARN_DST_MATCH and NX_LEARN_DST_LOAD when | |
754 | * NX_LEARN_SRC_IMMEDIATE is set in 'src_type', followed by zeroes to align | |
755 | * to OFPACT_ALIGNTO. */ | |
756 | }; | |
757 | BUILD_ASSERT_DECL(sizeof(struct ofpact_learn_spec) % OFPACT_ALIGNTO == 0); | |
758 | ||
759 | static inline const void * | |
760 | ofpact_learn_spec_imm(const struct ofpact_learn_spec *spec) | |
761 | { | |
762 | return spec + 1; | |
763 | } | |
dfe191d5 JR |
764 | |
765 | static inline const struct ofpact_learn_spec * | |
766 | ofpact_learn_spec_next(const struct ofpact_learn_spec *spec) | |
767 | { | |
768 | if (spec->src_type == NX_LEARN_SRC_IMMEDIATE) { | |
507a9a16 JR |
769 | unsigned int n_bytes = OFPACT_ALIGN(DIV_ROUND_UP(spec->n_bits, 8)); |
770 | return ALIGNED_CAST(const struct ofpact_learn_spec *, | |
771 | (const uint8_t *)(spec + 1) + n_bytes); | |
dfe191d5 | 772 | } |
507a9a16 | 773 | return spec + 1; |
dfe191d5 JR |
774 | } |
775 | ||
f25d0cf3 BP |
776 | /* OFPACT_LEARN. |
777 | * | |
778 | * Used for NXAST_LEARN. */ | |
779 | struct ofpact_learn { | |
c65a31e2 BP |
780 | OFPACT_PADDED_MEMBERS( |
781 | struct ofpact ofpact; | |
f25d0cf3 | 782 | |
c65a31e2 BP |
783 | uint16_t idle_timeout; /* Idle time before discarding (seconds). */ |
784 | uint16_t hard_timeout; /* Max time before discarding (seconds). */ | |
785 | uint16_t priority; /* Priority level of flow entry. */ | |
786 | uint8_t table_id; /* Table to insert flow entry. */ | |
787 | enum nx_learn_flags flags; /* NX_LEARN_F_*. */ | |
788 | ovs_be64 cookie; /* Cookie for new flow. */ | |
789 | uint16_t fin_idle_timeout; /* Idle timeout after FIN, if nonzero. */ | |
790 | uint16_t fin_hard_timeout; /* Hard timeout after FIN, if nonzero. */ | |
4c71600d | 791 | /* If the number of flows on 'table_id' with 'cookie' exceeds this, |
1746822c | 792 | * the action will not add a new flow. 0 indicates unlimited. */ |
4c71600d DDP |
793 | uint32_t limit; |
794 | /* Used only if 'flags' has NX_LEARN_F_WRITE_RESULT. If the execution | |
795 | * failed to install a new flow because 'limit' is exceeded, | |
796 | * result_dst will be set to 0, otherwise to 1. */ | |
797 | struct mf_subfield result_dst; | |
c65a31e2 | 798 | ); |
f25d0cf3 | 799 | |
f25d0cf3 BP |
800 | struct ofpact_learn_spec specs[]; |
801 | }; | |
802 | ||
c65a31e2 BP |
803 | static inline const struct ofpact_learn_spec * |
804 | ofpact_learn_spec_end(const struct ofpact_learn *learn) | |
805 | { | |
806 | return ALIGNED_CAST(const struct ofpact_learn_spec *, | |
807 | ofpact_next(&learn->ofpact)); | |
808 | } | |
809 | ||
810 | #define OFPACT_LEARN_SPEC_FOR_EACH(SPEC, LEARN) \ | |
811 | for ((SPEC) = (LEARN)->specs; \ | |
812 | (SPEC) < ofpact_learn_spec_end(LEARN); \ | |
813 | (SPEC) = ofpact_learn_spec_next(SPEC)) | |
814 | ||
c2d936a4 BP |
815 | /* Multipath link choice algorithm to apply. |
816 | * | |
817 | * In the descriptions below, 'n_links' is max_link + 1. */ | |
818 | enum nx_mp_algorithm { | |
819 | /* link = hash(flow) % n_links. | |
820 | * | |
821 | * Redistributes all traffic when n_links changes. O(1) performance. See | |
822 | * RFC 2992. | |
823 | * | |
824 | * Use UINT16_MAX for max_link to get a raw hash value. */ | |
825 | NX_MP_ALG_MODULO_N = 0, | |
826 | ||
827 | /* link = hash(flow) / (MAX_HASH / n_links). | |
828 | * | |
829 | * Redistributes between one-quarter and one-half of traffic when n_links | |
830 | * changes. O(1) performance. See RFC 2992. | |
831 | */ | |
832 | NX_MP_ALG_HASH_THRESHOLD = 1, | |
833 | ||
834 | /* Highest Random Weight. | |
835 | * | |
836 | * for i in [0,n_links): | |
837 | * weights[i] = hash(flow, i) | |
838 | * link = { i such that weights[i] >= weights[j] for all j != i } | |
839 | * | |
840 | * Redistributes 1/n_links of traffic when n_links changes. O(n_links) | |
841 | * performance. If n_links is greater than a threshold (currently 64, but | |
842 | * subject to change), Open vSwitch will substitute another algorithm | |
843 | * automatically. See RFC 2992. */ | |
844 | NX_MP_ALG_HRW = 2, | |
845 | ||
846 | /* Iterative Hash. | |
847 | * | |
848 | * i = 0 | |
849 | * repeat: | |
850 | * i = i + 1 | |
851 | * link = hash(flow, i) % arg | |
852 | * while link > max_link | |
853 | * | |
854 | * Redistributes 1/n_links of traffic when n_links changes. O(1) | |
855 | * performance when arg/max_link is bounded by a constant. | |
856 | * | |
857 | * Redistributes all traffic when arg changes. | |
858 | * | |
859 | * arg must be greater than max_link and for best performance should be no | |
860 | * more than approximately max_link * 2. If arg is outside the acceptable | |
861 | * range, Open vSwitch will automatically substitute the least power of 2 | |
862 | * greater than max_link. | |
863 | * | |
864 | * This algorithm is specific to Open vSwitch. | |
865 | */ | |
866 | NX_MP_ALG_ITER_HASH = 3, | |
867 | }; | |
868 | ||
18080541 BP |
869 | /* OFPACT_CONJUNCTION. |
870 | * | |
871 | * Used for NXAST_CONJUNCTION. */ | |
872 | struct ofpact_conjunction { | |
873 | struct ofpact ofpact; | |
874 | uint8_t clause; | |
875 | uint8_t n_clauses; | |
876 | uint32_t id; | |
877 | }; | |
878 | ||
f25d0cf3 BP |
879 | /* OFPACT_MULTIPATH. |
880 | * | |
881 | * Used for NXAST_MULTIPATH. */ | |
882 | struct ofpact_multipath { | |
883 | struct ofpact ofpact; | |
884 | ||
885 | /* What fields to hash and how. */ | |
886 | enum nx_hash_fields fields; | |
887 | uint16_t basis; /* Universal hash parameter. */ | |
888 | ||
889 | /* Multipath link choice algorithm to apply to hash value. */ | |
890 | enum nx_mp_algorithm algorithm; | |
891 | uint16_t max_link; /* Number of output links, minus 1. */ | |
892 | uint32_t arg; /* Algorithm-specific argument. */ | |
893 | ||
894 | /* Where to store the result. */ | |
895 | struct mf_subfield dst; | |
896 | }; | |
897 | ||
f25d0cf3 BP |
898 | /* OFPACT_NOTE. |
899 | * | |
900 | * Used for NXAST_NOTE. */ | |
901 | struct ofpact_note { | |
902 | struct ofpact ofpact; | |
903 | size_t length; | |
904 | uint8_t data[]; | |
905 | }; | |
906 | ||
4930ea56 BP |
907 | /* Direction of sampled packets. */ |
908 | enum nx_action_sample_direction { | |
909 | /* OVS will attempt to infer the sample's direction based on whether | |
910 | * 'sampling_port' is the packet's output port. This is generally | |
911 | * effective except when sampling happens as part of an output to a patch | |
912 | * port, which doesn't involve a datapath output action. */ | |
913 | NX_ACTION_SAMPLE_DEFAULT, | |
914 | ||
915 | /* Explicit direction. This is useful for sampling packets coming in from | |
916 | * or going out of a patch port, where the direction cannot be inferred. */ | |
917 | NX_ACTION_SAMPLE_INGRESS, | |
918 | NX_ACTION_SAMPLE_EGRESS | |
919 | }; | |
920 | ||
29089a54 RL |
921 | /* OFPACT_SAMPLE. |
922 | * | |
4930ea56 | 923 | * Used for NXAST_SAMPLE, NXAST_SAMPLE2, and NXAST_SAMPLE3. */ |
29089a54 RL |
924 | struct ofpact_sample { |
925 | struct ofpact ofpact; | |
f69f713b | 926 | uint16_t probability; /* Always positive. */ |
29089a54 RL |
927 | uint32_t collector_set_id; |
928 | uint32_t obs_domain_id; | |
929 | uint32_t obs_point_id; | |
f69f713b | 930 | ofp_port_t sampling_port; |
4930ea56 | 931 | enum nx_action_sample_direction direction; |
29089a54 RL |
932 | }; |
933 | ||
c2d967a5 MM |
934 | /* OFPACT_DEC_TTL. |
935 | * | |
7bcb1506 | 936 | * Used for OFPAT11_DEC_NW_TTL, NXAST_DEC_TTL and NXAST_DEC_TTL_CNT_IDS. */ |
c2d967a5 MM |
937 | struct ofpact_cnt_ids { |
938 | struct ofpact ofpact; | |
939 | ||
940 | /* Controller ids. */ | |
941 | unsigned int n_controllers; | |
942 | uint16_t cnt_ids[]; | |
8dd54666 | 943 | }; |
c2d967a5 | 944 | |
097d4939 JR |
945 | /* OFPACT_SET_MPLS_LABEL. |
946 | * | |
947 | * Used for OFPAT11_SET_MPLS_LABEL and NXAST_SET_MPLS_LABEL */ | |
948 | struct ofpact_mpls_label { | |
949 | struct ofpact ofpact; | |
950 | ||
951 | ovs_be32 label; | |
952 | }; | |
953 | ||
954 | /* OFPACT_SET_MPLS_TC. | |
955 | * | |
956 | * Used for OFPAT11_SET_MPLS_TC and NXAST_SET_MPLS_TC */ | |
957 | struct ofpact_mpls_tc { | |
958 | struct ofpact ofpact; | |
959 | ||
960 | uint8_t tc; | |
961 | }; | |
962 | ||
0f3f3c3d SH |
963 | /* OFPACT_SET_MPLS_TTL. |
964 | * | |
097d4939 | 965 | * Used for OFPAT11_SET_MPLS_TTL and NXAST_SET_MPLS_TTL */ |
0f3f3c3d SH |
966 | struct ofpact_mpls_ttl { |
967 | struct ofpact ofpact; | |
968 | ||
969 | uint8_t ttl; | |
970 | }; | |
971 | ||
8dd54666 IY |
972 | /* OFPACT_GOTO_TABLE |
973 | * | |
974 | * Used for OFPIT11_GOTO_TABLE */ | |
975 | struct ofpact_goto_table { | |
976 | struct ofpact ofpact; | |
977 | uint8_t table_id; | |
c2d967a5 MM |
978 | }; |
979 | ||
7395c052 NZ |
980 | /* OFPACT_GROUP. |
981 | * | |
982 | * Used for OFPAT11_GROUP. */ | |
983 | struct ofpact_group { | |
984 | struct ofpact ofpact; | |
985 | uint32_t group_id; | |
986 | }; | |
987 | ||
e672ff9b JR |
988 | /* OFPACT_UNROLL_XLATE. |
989 | * | |
990 | * Used only internally. */ | |
991 | struct ofpact_unroll_xlate { | |
992 | struct ofpact ofpact; | |
993 | ||
994 | /* Metadata in xlate context, visible to controller via PACKET_INs. */ | |
995 | uint8_t rule_table_id; /* 0xFF if none. */ | |
996 | ovs_be64 rule_cookie; /* OVS_BE64_MAX if none. */ | |
997 | }; | |
998 | ||
f839892a JS |
999 | /* OFPACT_ENCAP. |
1000 | * | |
1001 | * Used for NXAST_ENCAP. */ | |
1002 | ||
1003 | struct ofpact_encap { | |
1004 | struct ofpact ofpact; | |
1005 | ovs_be32 new_pkt_type; /* Packet type of the header to add. */ | |
1006 | uint16_t hdr_size; /* New header size in bytes. */ | |
1007 | uint16_t n_props; /* Number of encap properties. */ | |
1008 | struct ofpact_ed_prop props[]; /* Properties in internal format. */ | |
1009 | }; | |
1010 | ||
1011 | /* OFPACT_DECAP. | |
1012 | * | |
1013 | * Used for NXAST_DECAP. */ | |
1014 | struct ofpact_decap { | |
1015 | struct ofpact ofpact; | |
1016 | ||
1017 | /* New packet type. | |
1018 | * | |
1019 | * The special value (0,0xFFFE) "Use next proto" is used to request OVS to | |
1020 | * automatically set the new packet type based on the decap'ed header's | |
1021 | * next protocol. | |
1022 | */ | |
1023 | ovs_be32 new_pkt_type; | |
1024 | }; | |
1025 | ||
f25d0cf3 | 1026 | /* Converting OpenFlow to ofpacts. */ |
e3f8f887 JR |
1027 | enum ofperr ofpacts_pull_openflow_actions(struct ofpbuf *openflow, |
1028 | unsigned int actions_len, | |
1029 | enum ofp_version version, | |
04f48a68 | 1030 | const struct vl_mff_map *, |
5c7c16d8 | 1031 | uint64_t *ofpacts_tlv_bitmap, |
e3f8f887 | 1032 | struct ofpbuf *ofpacts); |
04f48a68 YHW |
1033 | enum ofperr |
1034 | ofpacts_pull_openflow_instructions(struct ofpbuf *openflow, | |
1035 | unsigned int instructions_len, | |
1036 | enum ofp_version version, | |
1037 | const struct vl_mff_map *vl_mff_map, | |
5c7c16d8 | 1038 | uint64_t *ofpacts_tlv_bitmap, |
04f48a68 | 1039 | struct ofpbuf *ofpacts); |
ca287d20 | 1040 | enum ofperr ofpacts_check(struct ofpact[], size_t ofpacts_len, |
67210a55 | 1041 | struct match *, ofp_port_t max_ports, |
ba2fe8e9 BP |
1042 | uint8_t table_id, uint8_t n_tables, |
1043 | enum ofputil_protocol *usable_protocols); | |
1044 | enum ofperr ofpacts_check_consistency(struct ofpact[], size_t ofpacts_len, | |
67210a55 | 1045 | struct match *, ofp_port_t max_ports, |
ba2fe8e9 BP |
1046 | uint8_t table_id, uint8_t n_tables, |
1047 | enum ofputil_protocol usable_protocols); | |
57ad4e9e | 1048 | enum ofperr ofpact_check_output_port(ofp_port_t port, ofp_port_t max_ports); |
f25d0cf3 BP |
1049 | |
1050 | /* Converting ofpacts to OpenFlow. */ | |
e3f8f887 JR |
1051 | size_t ofpacts_put_openflow_actions(const struct ofpact[], size_t ofpacts_len, |
1052 | struct ofpbuf *openflow, enum ofp_version); | |
1053 | void ofpacts_put_openflow_instructions(const struct ofpact[], | |
1054 | size_t ofpacts_len, | |
1055 | struct ofpbuf *openflow, | |
1056 | enum ofp_version ofp_version); | |
f25d0cf3 | 1057 | |
08d1e234 BP |
1058 | /* Sets of supported actions. */ |
1059 | ovs_be32 ofpact_bitmap_to_openflow(uint64_t ofpacts_bitmap, enum ofp_version); | |
1060 | uint64_t ofpact_bitmap_from_openflow(ovs_be32 ofpat_bitmap, enum ofp_version); | |
1061 | void ofpact_bitmap_format(uint64_t ofpacts_bitmap, struct ds *); | |
1062 | ||
f25d0cf3 BP |
1063 | /* Working with ofpacts. */ |
1064 | bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len, | |
4e022ec0 | 1065 | ofp_port_t port); |
7395c052 NZ |
1066 | bool ofpacts_output_to_group(const struct ofpact[], size_t ofpacts_len, |
1067 | uint32_t group_id); | |
f25d0cf3 BP |
1068 | bool ofpacts_equal(const struct ofpact a[], size_t a_len, |
1069 | const struct ofpact b[], size_t b_len); | |
6cc9d77c BP |
1070 | bool ofpacts_equal_stringwise(const struct ofpact a[], size_t a_len, |
1071 | const struct ofpact b[], size_t b_len); | |
28f5311f | 1072 | const struct mf_field *ofpact_get_mf_dst(const struct ofpact *ofpact); |
d6fb622d | 1073 | uint32_t ofpacts_get_meter(const struct ofpact[], size_t ofpacts_len); |
f25d0cf3 | 1074 | |
efefbcae BP |
1075 | /* Formatting ofpacts. */ |
1076 | struct ofpact_format_params { | |
1077 | /* Input. */ | |
1078 | const struct ofputil_port_map *port_map; | |
4bc938cc | 1079 | const struct ofputil_table_map *table_map; |
efefbcae BP |
1080 | |
1081 | /* Output. */ | |
1082 | struct ds *s; | |
1083 | }; | |
50f96b10 | 1084 | void ofpacts_format(const struct ofpact[], size_t ofpacts_len, |
efefbcae BP |
1085 | const struct ofpact_format_params *); |
1086 | const char *ofpact_name(enum ofpact_type); | |
1087 | ||
1088 | /* Parsing ofpacts. */ | |
1089 | struct ofpact_parse_params { | |
1090 | /* Input. */ | |
1091 | const struct ofputil_port_map *port_map; | |
4bc938cc | 1092 | const struct ofputil_table_map *table_map; |
efefbcae BP |
1093 | |
1094 | /* Output. */ | |
1095 | struct ofpbuf *ofpacts; | |
1096 | enum ofputil_protocol *usable_protocols; | |
1097 | }; | |
1098 | char *ofpacts_parse_actions(const char *, const struct ofpact_parse_params *) | |
cab50449 | 1099 | OVS_WARN_UNUSED_RESULT; |
efefbcae BP |
1100 | char *ofpacts_parse_instructions(const char *, |
1101 | const struct ofpact_parse_params *) | |
cab50449 | 1102 | OVS_WARN_UNUSED_RESULT; |
f25d0cf3 BP |
1103 | |
1104 | /* Internal use by the helpers below. */ | |
1105 | void ofpact_init(struct ofpact *, enum ofpact_type, size_t len); | |
1106 | void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len); | |
ce058104 | 1107 | void *ofpact_finish(struct ofpbuf *, struct ofpact *); |
f25d0cf3 BP |
1108 | |
1109 | /* For each OFPACT_<ENUM> with a corresponding struct <STRUCT>, this defines | |
1110 | * the following commonly useful functions: | |
1111 | * | |
1112 | * struct <STRUCT> *ofpact_put_<ENUM>(struct ofpbuf *ofpacts); | |
1113 | * | |
2bd318de | 1114 | * Appends a new 'ofpact', of length OFPACT_<ENUM>_SIZE, to 'ofpacts', |
f25d0cf3 | 1115 | * initializes it with ofpact_init_<ENUM>(), and returns it. Also sets |
9ac0aada | 1116 | * 'ofpacts->header' to the returned action. |
f25d0cf3 BP |
1117 | * |
1118 | * After using this function to add a variable-length action, add the | |
1119 | * elements of the flexible array (e.g. with ofpbuf_put()), then use | |
34abaa3d BP |
1120 | * ofpact_finish() to pad the action to a multiple of OFPACT_ALIGNTO bytes |
1121 | * and update its embedded length field. (Keep in mind the need to refresh | |
1122 | * the structure from 'ofpacts->header' after adding data to 'ofpacts'.) | |
f25d0cf3 BP |
1123 | * |
1124 | * struct <STRUCT> *ofpact_get_<ENUM>(const struct ofpact *ofpact); | |
1125 | * | |
1126 | * Returns 'ofpact' cast to "struct <STRUCT> *". 'ofpact->type' must be | |
1127 | * OFPACT_<ENUM>. | |
1128 | * | |
ce058104 BP |
1129 | * void ofpact_finish_<ENUM>(struct ofpbuf *ofpacts, struct <STRUCT> **ap); |
1130 | * | |
1131 | * Finishes composing variable-length action '*ap' (begun using | |
1132 | * ofpact_put_<NAME>() on 'ofpacts'), by padding the action to a multiple | |
1133 | * of OFPACT_ALIGNTO bytes and updating its embedded length field. | |
1134 | * | |
1135 | * May reallocate 'ofpacts', and so as a convenience automatically updates | |
1136 | * '*ap' to point to the new location. If the caller has other pointers | |
1137 | * within 'ap' or 'ofpacts', it needs to update them manually. | |
1138 | * | |
f25d0cf3 BP |
1139 | * as well as the following more rarely useful definitions: |
1140 | * | |
1141 | * void ofpact_init_<ENUM>(struct <STRUCT> *ofpact); | |
1142 | * | |
1143 | * Initializes the parts of 'ofpact' that identify it as having type | |
2bd318de | 1144 | * OFPACT_<ENUM> and length OFPACT_<ENUM>_SIZE and zeros the rest. |
f25d0cf3 BP |
1145 | * |
1146 | * <ENUM>_SIZE | |
1147 | * | |
2bd318de BP |
1148 | * The size of the action structure. For a fixed-length action, this is |
1149 | * sizeof(struct <STRUCT>) rounded up to a multiple of OFPACT_ALIGNTO. For | |
1150 | * a variable-length action, this is the offset to the variable-length | |
1151 | * part. | |
f25d0cf3 | 1152 | */ |
08d1e234 | 1153 | #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \ |
f25d0cf3 BP |
1154 | BUILD_ASSERT_DECL(offsetof(struct STRUCT, ofpact) == 0); \ |
1155 | \ | |
2bd318de | 1156 | enum { OFPACT_##ENUM##_SIZE \ |
27f141d4 | 1157 | = (offsetof(struct STRUCT, MEMBER) != 0 \ |
f25d0cf3 | 1158 | ? offsetof(struct STRUCT, MEMBER) \ |
2bd318de | 1159 | : OFPACT_ALIGN(sizeof(struct STRUCT))) }; \ |
f25d0cf3 BP |
1160 | \ |
1161 | static inline struct STRUCT * \ | |
1162 | ofpact_get_##ENUM(const struct ofpact *ofpact) \ | |
1163 | { \ | |
cb22974d | 1164 | ovs_assert(ofpact->type == OFPACT_##ENUM); \ |
db5a1019 | 1165 | return ALIGNED_CAST(struct STRUCT *, ofpact); \ |
f25d0cf3 BP |
1166 | } \ |
1167 | \ | |
cc099268 JR |
1168 | static inline struct STRUCT * \ |
1169 | ofpact_get_##ENUM##_nullable(const struct ofpact *ofpact) \ | |
1170 | { \ | |
1171 | ovs_assert(!ofpact || ofpact->type == OFPACT_##ENUM); \ | |
1172 | return ALIGNED_CAST(struct STRUCT *, ofpact); \ | |
1173 | } \ | |
1174 | \ | |
f25d0cf3 BP |
1175 | static inline struct STRUCT * \ |
1176 | ofpact_put_##ENUM(struct ofpbuf *ofpacts) \ | |
1177 | { \ | |
9965bc0b BP |
1178 | return (struct STRUCT *) ofpact_put(ofpacts, OFPACT_##ENUM, \ |
1179 | OFPACT_##ENUM##_SIZE); \ | |
f25d0cf3 BP |
1180 | } \ |
1181 | \ | |
1182 | static inline void \ | |
1183 | ofpact_init_##ENUM(struct STRUCT *ofpact) \ | |
1184 | { \ | |
1185 | ofpact_init(&ofpact->ofpact, OFPACT_##ENUM, \ | |
2bd318de | 1186 | OFPACT_##ENUM##_SIZE); \ |
ce058104 BP |
1187 | } \ |
1188 | \ | |
1189 | static inline void \ | |
1190 | ofpact_finish_##ENUM(struct ofpbuf *ofpbuf, struct STRUCT **ofpactp) \ | |
1191 | { \ | |
1192 | struct ofpact *ofpact = &(*ofpactp)->ofpact; \ | |
1193 | ovs_assert(ofpact->type == OFPACT_##ENUM); \ | |
9965bc0b | 1194 | *ofpactp = (struct STRUCT *) ofpact_finish(ofpbuf, ofpact); \ |
f25d0cf3 BP |
1195 | } |
1196 | OFPACTS | |
08d1e234 | 1197 | #undef OFPACT |
f25d0cf3 | 1198 | |
7eb4b1f1 | 1199 | /* Additional functions for composing ofpacts. */ |
128684a6 JR |
1200 | struct ofpact_set_field *ofpact_put_set_field(struct ofpbuf *ofpacts, |
1201 | const struct mf_field *, | |
1202 | const void *value, | |
1203 | const void *mask); | |
1204 | struct ofpact_set_field *ofpact_put_reg_load(struct ofpbuf *ofpacts, | |
1205 | const struct mf_field *, | |
1206 | const void *value, | |
1207 | const void *mask); | |
1208 | struct ofpact_set_field *ofpact_put_reg_load2(struct ofpbuf *ofpacts, | |
1209 | const struct mf_field *, | |
1210 | const void *value, | |
1211 | const void *mask); | |
7eb4b1f1 | 1212 | |
99c476dc IY |
1213 | /* OpenFlow 1.1 instructions. |
1214 | * The order is sorted in execution order. Not in the value of OFPIT11_xxx. | |
1215 | * It is enforced on parser from text string. | |
1216 | */ | |
a64f0b0f | 1217 | #define OVS_INSTRUCTIONS \ |
638a19b0 JR |
1218 | DEFINE_INST(OFPIT13_METER, \ |
1219 | ofp13_instruction_meter, false, \ | |
1220 | "meter") \ | |
1221 | \ | |
99c476dc IY |
1222 | DEFINE_INST(OFPIT11_APPLY_ACTIONS, \ |
1223 | ofp11_instruction_actions, true, \ | |
1224 | "apply_actions") \ | |
a64f0b0f | 1225 | \ |
99c476dc IY |
1226 | DEFINE_INST(OFPIT11_CLEAR_ACTIONS, \ |
1227 | ofp11_instruction, false, \ | |
1228 | "clear_actions") \ | |
a64f0b0f IY |
1229 | \ |
1230 | DEFINE_INST(OFPIT11_WRITE_ACTIONS, \ | |
1231 | ofp11_instruction_actions, true, \ | |
1232 | "write_actions") \ | |
1233 | \ | |
99c476dc IY |
1234 | DEFINE_INST(OFPIT11_WRITE_METADATA, \ |
1235 | ofp11_instruction_write_metadata, false, \ | |
1236 | "write_metadata") \ | |
a64f0b0f | 1237 | \ |
99c476dc IY |
1238 | DEFINE_INST(OFPIT11_GOTO_TABLE, \ |
1239 | ofp11_instruction_goto_table, false, \ | |
1240 | "goto_table") | |
a64f0b0f IY |
1241 | |
1242 | enum ovs_instruction_type { | |
1243 | #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) OVSINST_##ENUM, | |
1244 | OVS_INSTRUCTIONS | |
1245 | #undef DEFINE_INST | |
1246 | }; | |
1247 | ||
1248 | enum { | |
1249 | #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) + 1 | |
1250 | N_OVS_INSTRUCTIONS = OVS_INSTRUCTIONS | |
1251 | #undef DEFINE_INST | |
1252 | }; | |
1253 | ||
ba0bc9b0 BP |
1254 | const char *ovs_instruction_name_from_type(enum ovs_instruction_type type); |
1255 | int ovs_instruction_type_from_name(const char *name); | |
084c53de BP |
1256 | enum ovs_instruction_type ovs_instruction_type_from_ofpact_type( |
1257 | enum ofpact_type); | |
c0621c39 AW |
1258 | enum ofperr ovs_instruction_type_from_inst_type( |
1259 | enum ovs_instruction_type *instruction_type, const uint16_t inst_type); | |
1260 | ||
8e97815e BP |
1261 | ovs_be32 ovsinst_bitmap_to_openflow(uint32_t ovsinst_bitmap, enum ofp_version); |
1262 | uint32_t ovsinst_bitmap_from_openflow(ovs_be32 ofpit_bitmap, | |
1263 | enum ofp_version); | |
1264 | ||
ec30ca5f BP |
1265 | #ifdef __cplusplus |
1266 | } | |
1267 | #endif | |
1268 | ||
f25d0cf3 | 1269 | #endif /* ofp-actions.h */ |