]> git.proxmox.com Git - mirror_ovs.git/blob - ofproto/ofproto-dpif-rid.h
tunneling: Allow matching and setting tunnel 'OAM' flag.
[mirror_ovs.git] / ofproto / ofproto-dpif-rid.h
1 /*
2 * Copyright (c) 2014, 2015 Nicira, Inc.
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
23 #include "cmap.h"
24 #include "list.h"
25 #include "ofp-actions.h"
26 #include "ovs-thread.h"
27
28 struct ofproto_dpif;
29 struct rule;
30
31 /*
32 * Recirculation
33 * =============
34 *
35 * Recirculation is a technique to allow a frame to re-enter the datapath
36 * packet processing path for one or multiple times to achieve more flexible
37 * packet processing, such modifying header fields after MPLS POP action and
38 * selecting bond a slave port for bond ports.
39 *
40 * Data path and user space interface
41 * -----------------------------------
42 *
43 * Recirculation uses two uint32_t fields, recirc_id and dp_hash, and a RECIRC
44 * action. The value recirc_id is used to select the next packet processing
45 * steps among multiple instances of recirculation. When a packet initially
46 * enters the data path it is assigned with recirc_id 0, which indicates no
47 * recirculation. Recirc_ids are managed by the user space, opaque to the
48 * data path.
49 *
50 * On the other hand, dp_hash can only be computed by the data path, opaque to
51 * the user space. In fact, user space may not able to recompute the hash
52 * value. The dp_hash value should be wildcarded for a newly received
53 * packet. HASH action specifies whether the hash is computed, and if
54 * computed, how many fields are to be included in the hash computation. The
55 * computed hash value is stored into the dp_hash field prior to recirculation.
56 *
57 * The RECIRC action sets the recirc_id field and then reprocesses the packet
58 * as if it was received on the same input port. RECIRC action works like a
59 * function call; actions listed behind the RECIRC action will be executed
60 * after its execution. RECIRC action can be nested, data path implementation
61 * limits the number of recirculation executed to prevent unreasonable nesting
62 * depth or infinite loop.
63 *
64 * User space recirculation context
65 * ---------------------------------
66 *
67 * Recirculation is hidden from the OpenFlow controllers. Action translation
68 * code deduces when recirculation is necessary and issues a data path
69 * recirculation action. All OpenFlow actions to be performed after
70 * recirculation are derived from the OpenFlow pipeline and are stored with the
71 * recirculation ID. When the OpenFlow tables are changed in a way affecting
72 * the recirculation flows, new recirculation ID with new metadata and actions
73 * is allocated and the old one is timed out.
74 *
75 * Recirculation ID pool
76 * ----------------------
77 *
78 * Recirculation ID needs to be unique for all data paths. Recirculation ID
79 * pool keeps track recirculation ids and stores OpenFlow pipeline translation
80 * context so that flow processing may continue after recirculation.
81 *
82 * A Recirculation ID can be any uint32_t value, except for that the value 0 is
83 * reserved for 'no recirculation' case.
84 *
85 * Thread-safety
86 * --------------
87 *
88 * All APIs are thread safe.
89 */
90
91 /* Metadata for restoring pipeline context after recirculation. Helpers
92 * are inlined below to keep them together with the definition for easier
93 * updates. */
94 BUILD_ASSERT_DECL(FLOW_WC_SEQ == 33);
95
96 struct recirc_metadata {
97 /* Metadata in struct flow. */
98 struct flow_tnl tunnel; /* Encapsulating tunnel parameters. */
99 ovs_be64 metadata; /* OpenFlow Metadata. */
100 uint64_t regs[FLOW_N_XREGS]; /* Registers. */
101 ofp_port_t in_port; /* Incoming port. */
102 ofp_port_t actset_output; /* Output port in action set. */
103 };
104
105 static inline void
106 recirc_metadata_from_flow(struct recirc_metadata *md,
107 const struct flow *flow)
108 {
109 memset(md, 0, sizeof *md);
110 md->tunnel = flow->tunnel;
111 md->metadata = flow->metadata;
112 memcpy(md->regs, flow->regs, sizeof md->regs);
113 md->in_port = flow->in_port.ofp_port;
114 md->actset_output = flow->actset_output;
115 }
116
117 static inline void
118 recirc_metadata_to_flow(const struct recirc_metadata *md,
119 struct flow *flow)
120 {
121 flow->tunnel = md->tunnel;
122 flow->metadata = md->metadata;
123 memcpy(flow->regs, md->regs, sizeof flow->regs);
124 flow->in_port.ofp_port = md->in_port;
125 flow->actset_output = md->actset_output;
126 }
127
128 /* Pool node fields should NOT be modified after placing the node in the pool.
129 */
130 struct recirc_id_node {
131 struct ovs_list exp_node OVS_GUARDED;
132 struct cmap_node id_node;
133 struct cmap_node metadata_node;
134 uint32_t id;
135 uint32_t hash;
136 struct ovs_refcount refcount;
137
138 /* Initial table for post-recirculation processing. */
139 uint8_t table_id;
140
141 /* Pipeline context for post-recirculation processing. */
142 struct ofproto_dpif *ofproto; /* Post-recirculation bridge. */
143 struct recirc_metadata metadata; /* Flow metadata. */
144 struct ofpbuf *stack; /* Stack if any. */
145
146 /* Actions to be translated on recirculation. */
147 uint32_t action_set_len; /* How much of 'ofpacts' consists of an
148 * action set? */
149 uint32_t ofpacts_len; /* Size of 'ofpacts', in bytes. */
150 struct ofpact ofpacts[]; /* Sequence of "struct ofpacts". */
151 };
152
153 void recirc_init(void);
154
155 /* This is only used for bonds and will go away when bonds implementation is
156 * updated to use this mechanism instead of internal rules. */
157 uint32_t recirc_alloc_id(struct ofproto_dpif *);
158
159 uint32_t recirc_alloc_id_ctx(struct ofproto_dpif *, uint8_t table_id,
160 struct recirc_metadata *, struct ofpbuf *stack,
161 uint32_t action_set_len, uint32_t ofpacts_len,
162 const struct ofpact *);
163 uint32_t recirc_find_id(struct ofproto_dpif *, uint8_t table_id,
164 struct recirc_metadata *, struct ofpbuf *stack,
165 uint32_t action_set_len, uint32_t ofpacts_len,
166 const struct ofpact *);
167 void recirc_free_id(uint32_t recirc_id);
168 void recirc_free_ofproto(struct ofproto_dpif *, const char *ofproto_name);
169
170 const struct recirc_id_node *recirc_id_node_find(uint32_t recirc_id);
171
172 static inline bool recirc_id_node_try_ref_rcu(const struct recirc_id_node *n_)
173 {
174 struct recirc_id_node *node = CONST_CAST(struct recirc_id_node *, n_);
175
176 return node ? ovs_refcount_try_ref_rcu(&node->refcount) : false;
177 }
178
179 void recirc_id_node_unref(const struct recirc_id_node *);
180
181 void recirc_run(void);
182
183 #endif