]> git.proxmox.com Git - ovs.git/blame - ofproto/ofproto-dpif-rid.h
bond: Remove bond_hash_src.
[ovs.git] / ofproto / ofproto-dpif-rid.h
CommitLineData
f5374617 1/*
290835f9 2 * Copyright (c) 2014, 2015, 2016 Nicira, Inc.
f5374617
AZ
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
17#ifndef OFPROTO_DPIF_RID_H
18#define OFPROTO_DPIF_RID_H
19
20#include <stddef.h>
21#include <stdint.h>
22
e672ff9b 23#include "cmap.h"
29bae541 24#include "ofproto-dpif-mirror.h"
b598f214
BW
25#include "openvswitch/list.h"
26#include "openvswitch/ofp-actions.h"
e672ff9b 27#include "ovs-thread.h"
290835f9 28#include "uuid.h"
e672ff9b
JR
29
30struct ofproto_dpif;
31struct rule;
f5374617
AZ
32
33/*
1d361a81
BP
34 * Freezing and recirculation
35 * ==========================
36 *
37 * Freezing is a technique for halting and checkpointing packet translation in
38 * a way that it can be restarted again later. This file has a couple of data
39 * structures related to freezing in general; their names begin with "frozen".
40 *
41 * Recirculation is the use of freezing to allow a frame to re-enter the
42 * datapath packet processing path to achieve more flexible packet processing,
43 * such as modifying header fields after MPLS POP action and selecting a slave
44 * port for bond ports.
e672ff9b 45 *
e672ff9b
JR
46 *
47 * Data path and user space interface
48 * -----------------------------------
49 *
50 * Recirculation uses two uint32_t fields, recirc_id and dp_hash, and a RECIRC
59781952
JR
51 * action. recirc_id is used to select the next packet processing steps among
52 * multiple instances of recirculation. When a packet initially enters the
53 * datapath it is assigned with recirc_id 0, which indicates no recirculation.
54 * Recirc_ids are managed by the user space, opaque to the datapath.
e672ff9b 55 *
59781952
JR
56 * On the other hand, dp_hash can only be computed by the datapath, opaque to
57 * the user space, as the datapath is free to choose the hashing algorithm
58 * without informing user space about it. The dp_hash value should be
59 * wildcarded for newly received packets. HASH action specifies whether the
60 * hash is computed, and if computed, how many fields are to be included in the
61 * hash computation. The computed hash value is stored into the dp_hash field
62 * prior to recirculation.
e672ff9b
JR
63 *
64 * The RECIRC action sets the recirc_id field and then reprocesses the packet
59781952
JR
65 * as if it was received again on the same input port. RECIRC action works
66 * like a function call; actions listed after the RECIRC action will be
67 * executed after recirculation. RECIRC action can be nested, but datapath
68 * implementation limits the number of nested recirculations to prevent
69 * unreasonable nesting depth or infinite loop.
e672ff9b
JR
70 *
71 * User space recirculation context
72 * ---------------------------------
f5374617 73 *
59781952
JR
74 * Recirculation is usually hidden from the OpenFlow controllers. Action
75 * translation code deduces when recirculation is necessary and issues a
76 * datapath recirculation action. All OpenFlow actions to be performed after
e672ff9b
JR
77 * recirculation are derived from the OpenFlow pipeline and are stored with the
78 * recirculation ID. When the OpenFlow tables are changed in a way affecting
79 * the recirculation flows, new recirculation ID with new metadata and actions
80 * is allocated and the old one is timed out.
f5374617 81 *
e672ff9b
JR
82 * Recirculation ID pool
83 * ----------------------
f5374617 84 *
59781952
JR
85 * Recirculation ID needs to be unique for all datapaths. Recirculation ID
86 * pool keeps track of recirculation ids and stores OpenFlow pipeline
87 * translation context so that flow processing may continue after
88 * recirculation.
e672ff9b
JR
89 *
90 * A Recirculation ID can be any uint32_t value, except for that the value 0 is
91 * reserved for 'no recirculation' case.
f5374617
AZ
92 *
93 * Thread-safety
e672ff9b 94 * --------------
f5374617
AZ
95 *
96 * All APIs are thread safe.
f5374617 97 */
e672ff9b
JR
98
99/* Metadata for restoring pipeline context after recirculation. Helpers
100 * are inlined below to keep them together with the definition for easier
101 * updates. */
2482b0b0 102BUILD_ASSERT_DECL(FLOW_WC_SEQ == 39);
e672ff9b 103
1d361a81 104struct frozen_metadata {
e672ff9b 105 /* Metadata in struct flow. */
59781952 106 const struct flow_tnl *tunnel; /* Encapsulating tunnel parameters. */
e672ff9b
JR
107 ovs_be64 metadata; /* OpenFlow Metadata. */
108 uint64_t regs[FLOW_N_XREGS]; /* Registers. */
109 ofp_port_t in_port; /* Incoming port. */
e672ff9b
JR
110};
111
112static inline void
1d361a81 113frozen_metadata_from_flow(struct frozen_metadata *md,
e672ff9b
JR
114 const struct flow *flow)
115{
116 memset(md, 0, sizeof *md);
59781952 117 md->tunnel = &flow->tunnel;
e672ff9b
JR
118 md->metadata = flow->metadata;
119 memcpy(md->regs, flow->regs, sizeof md->regs);
120 md->in_port = flow->in_port.ofp_port;
e672ff9b
JR
121}
122
123static inline void
1d361a81 124frozen_metadata_to_flow(const struct frozen_metadata *md,
e672ff9b
JR
125 struct flow *flow)
126{
ffe4c74f 127 if (md->tunnel && flow_tnl_dst_is_set(md->tunnel)) {
59781952
JR
128 flow->tunnel = *md->tunnel;
129 } else {
130 memset(&flow->tunnel, 0, sizeof flow->tunnel);
131 }
e672ff9b
JR
132 flow->metadata = md->metadata;
133 memcpy(flow->regs, md->regs, sizeof flow->regs);
134 flow->in_port.ofp_port = md->in_port;
e672ff9b
JR
135}
136
1d361a81
BP
137/* State that flow translation can save, to restore when translation
138 * resumes. */
139struct frozen_state {
140 /* Initial table for processing when thawing. */
e672ff9b
JR
141 uint8_t table_id;
142
1d361a81
BP
143 /* Pipeline context for processing when thawing. */
144 struct uuid ofproto_uuid; /* Bridge to resume from. */
145 struct frozen_metadata metadata; /* Flow metadata. */
84cf3c1f
JR
146 uint8_t *stack; /* Stack if any. */
147 size_t stack_size;
29bae541 148 mirror_mask_t mirrors; /* Mirrors already output. */
1d361a81 149 bool conntracked; /* Conntrack occurred prior to freeze. */
e672ff9b 150
1d361a81 151 /* Actions to be translated when thawing. */
417509fa
BP
152 struct ofpact *ofpacts;
153 size_t ofpacts_len; /* Size of 'ofpacts', in bytes. */
154 struct ofpact *action_set;
155 size_t action_set_len; /* Size of 'action_set', in bytes. */
2082425c
BP
156};
157
158/* This maps a recirculation ID to saved state that flow translation can
159 * restore when recirculation occurs. */
160struct recirc_id_node {
161 /* Index data. */
162 struct ovs_list exp_node OVS_GUARDED;
163 struct cmap_node id_node;
164 struct cmap_node metadata_node;
165 uint32_t id;
166 uint32_t hash;
167 struct ovs_refcount refcount;
168
169 /* Saved state.
170 *
171 * This state should not be modified after inserting a node in the pool,
172 * hence the 'const' to emphasize that. */
1d361a81 173 const struct frozen_state state;
59781952
JR
174
175 /* Storage for tunnel metadata. */
176 struct flow_tnl state_metadata_tunnel;
e672ff9b
JR
177};
178
e672ff9b
JR
179/* This is only used for bonds and will go away when bonds implementation is
180 * updated to use this mechanism instead of internal rules. */
181uint32_t recirc_alloc_id(struct ofproto_dpif *);
182
1d361a81
BP
183uint32_t recirc_alloc_id_ctx(const struct frozen_state *);
184uint32_t recirc_find_id(const struct frozen_state *);
e672ff9b
JR
185void recirc_free_id(uint32_t recirc_id);
186void recirc_free_ofproto(struct ofproto_dpif *, const char *ofproto_name);
187
188const struct recirc_id_node *recirc_id_node_find(uint32_t recirc_id);
e6bc8e74 189bool recirc_id_node_find_and_ref(uint32_t id);
e672ff9b 190
29b1ea3f 191static inline struct recirc_id_node *
1d361a81 192recirc_id_node_from_state(const struct frozen_state *state)
29b1ea3f
BP
193{
194 return CONTAINER_OF(state, struct recirc_id_node, state);
195}
196
e672ff9b
JR
197static inline bool recirc_id_node_try_ref_rcu(const struct recirc_id_node *n_)
198{
199 struct recirc_id_node *node = CONST_CAST(struct recirc_id_node *, n_);
200
201 return node ? ovs_refcount_try_ref_rcu(&node->refcount) : false;
202}
203
204void recirc_id_node_unref(const struct recirc_id_node *);
205
206void recirc_run(void);
207
fbf5d6ec
JR
208/* Recirculation IDs on which references are held. */
209struct recirc_refs {
210 unsigned n_recircs;
211 union {
212 uint32_t recirc[2]; /* When n_recircs == 1 or 2 */
213 uint32_t *recircs; /* When 'n_recircs' > 2 */
214 };
215};
216
217#define RECIRC_REFS_EMPTY_INITIALIZER ((struct recirc_refs) \
218 { 0, { { 0, 0 } } })
219/* Helpers to abstract the recirculation union away. */
220static inline void
221recirc_refs_init(struct recirc_refs *rr)
222{
223 *rr = RECIRC_REFS_EMPTY_INITIALIZER;
224}
225
226static inline void
227recirc_refs_add(struct recirc_refs *rr, uint32_t id)
228{
229 if (OVS_LIKELY(rr->n_recircs < ARRAY_SIZE(rr->recirc))) {
230 rr->recirc[rr->n_recircs++] = id;
231 } else {
232 if (rr->n_recircs == ARRAY_SIZE(rr->recirc)) {
233 uint32_t *recircs = xmalloc(sizeof rr->recirc + sizeof id);
234
235 memcpy(recircs, rr->recirc, sizeof rr->recirc);
236 rr->recircs = recircs;
237 } else {
238 rr->recircs = xrealloc(rr->recircs,
239 (rr->n_recircs + 1) * sizeof id);
240 }
241 rr->recircs[rr->n_recircs++] = id;
242 }
243}
244
245static inline void
246recirc_refs_swap(struct recirc_refs *a, struct recirc_refs *b)
247{
248 struct recirc_refs tmp;
249
250 tmp = *a;
251 *a = *b;
252 *b = tmp;
253}
254
255static inline void
256recirc_refs_unref(struct recirc_refs *rr)
257{
258 if (OVS_LIKELY(rr->n_recircs <= ARRAY_SIZE(rr->recirc))) {
259 for (int i = 0; i < rr->n_recircs; i++) {
260 recirc_free_id(rr->recirc[i]);
261 }
262 } else {
263 for (int i = 0; i < rr->n_recircs; i++) {
264 recirc_free_id(rr->recircs[i]);
265 }
266 free(rr->recircs);
267 }
268 rr->n_recircs = 0;
269}
270
f5374617 271#endif