81a61a2368bb1b99916c09ac6c2fdaf53a9b7c48
[cascardo/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 == 31);
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