]>
Commit | Line | Data |
---|---|---|
6a4d3ab5 | 1 | /* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. |
9583bc14 EJ |
2 | * |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at: | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. */ | |
14 | ||
15 | #ifndef OFPROTO_DPIF_H | |
16 | #define OFPROTO_DPIF_H 1 | |
17 | ||
18 | #include <stdint.h> | |
19 | ||
003ce655 | 20 | #include "fail-open.h" |
9583bc14 | 21 | #include "hmapx.h" |
e1ec7dd4 | 22 | #include "odp-util.h" |
70742c7f | 23 | #include "ofp-util.h" |
9fbe253e | 24 | #include "ovs-thread.h" |
adcf00ba | 25 | #include "ofproto-provider.h" |
9583bc14 EJ |
26 | #include "timer.h" |
27 | #include "util.h" | |
ec89fc6f | 28 | #include "ovs-thread.h" |
9583bc14 | 29 | |
4ae48dcd SH |
30 | /* Priority for internal rules created to handle recirculation */ |
31 | #define RECIRC_RULE_PRIORITY 20 | |
32 | ||
9583bc14 | 33 | union user_action_cookie; |
70742c7f | 34 | struct dpif_flow_stats; |
f5374617 | 35 | struct ofproto; |
46c88433 | 36 | struct ofproto_dpif; |
0fb7792a | 37 | struct ofproto_packet_in; |
46c88433 | 38 | struct ofport_dpif; |
8449c4d6 | 39 | struct dpif_backer; |
70742c7f | 40 | struct OVS_LOCKABLE rule_dpif; |
f4fb341b | 41 | struct OVS_LOCKABLE group_dpif; |
9583bc14 | 42 | |
e1ec7dd4 EJ |
43 | /* Ofproto-dpif -- DPIF based ofproto implementation. |
44 | * | |
45 | * Ofproto-dpif provides an ofproto implementation for those platforms which | |
46 | * implement the netdev and dpif interface defined in netdev.h and dpif.h. The | |
47 | * most important of which is the Linux Kernel Module (dpif-linux), but | |
48 | * alternatives are supported such as a userspace only implementation | |
49 | * (dpif-netdev), and a dummy implementation used for unit testing. | |
50 | * | |
51 | * Ofproto-dpif is divided into three major chunks. | |
52 | * | |
53 | * - ofproto-dpif.c | |
54 | * The main ofproto-dpif module is responsible for implementing the | |
55 | * provider interface, installing and removing datapath flows, maintaining | |
56 | * packet statistics, running protocols (BFD, LACP, STP, etc), and | |
57 | * configuring relevant submodules. | |
58 | * | |
59 | * - ofproto-dpif-upcall.c | |
60 | * Ofproto-dpif-upcall is responsible for retrieving upcalls from the kernel, | |
61 | * processing miss upcalls, and handing more complex ones up to the main | |
62 | * ofproto-dpif module. Miss upcall processing boils down to figuring out | |
63 | * what each packet's actions are, executing them (i.e. asking the kernel to | |
64 | * forward it), and handing it up to ofproto-dpif to decided whether or not | |
65 | * to install a kernel flow. | |
66 | * | |
67 | * - ofproto-dpif-xlate.c | |
cf9cf2e8 YT |
68 | * Ofproto-dpif-xlate is responsible for translating OpenFlow actions into |
69 | * datapath actions. */ | |
e1ec7dd4 | 70 | |
8bfd0fda | 71 | size_t ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *); |
adcf00ba | 72 | bool ofproto_dpif_get_enable_recirc(const struct ofproto_dpif *); |
8bfd0fda | 73 | |
34dd0d78 JR |
74 | struct rule_dpif *rule_dpif_lookup(struct ofproto_dpif *, struct flow *, |
75 | struct flow_wildcards *, bool take_ref, | |
76 | const struct dpif_flow_stats *, | |
77 | uint8_t *table_id); | |
78 | ||
79 | struct rule_dpif *rule_dpif_lookup_from_table(struct ofproto_dpif *, | |
80 | struct flow *, | |
81 | struct flow_wildcards *, | |
82 | bool take_ref, | |
83 | const struct dpif_flow_stats *, | |
84 | uint8_t *table_id, | |
85 | ofp_port_t in_port, | |
86 | bool may_packet_in, | |
87 | bool honor_table_miss); | |
70742c7f | 88 | |
003ce655 JR |
89 | static inline void rule_dpif_ref(struct rule_dpif *); |
90 | static inline void rule_dpif_unref(struct rule_dpif *); | |
70742c7f | 91 | |
cd1acaab SH |
92 | void rule_dpif_credit_stats(struct rule_dpif *rule , |
93 | const struct dpif_flow_stats *); | |
70742c7f | 94 | |
003ce655 JR |
95 | static inline bool rule_dpif_is_fail_open(const struct rule_dpif *); |
96 | static inline bool rule_dpif_is_table_miss(const struct rule_dpif *); | |
97 | static inline bool rule_dpif_is_internal(const struct rule_dpif *); | |
98 | ||
adcf00ba | 99 | uint8_t rule_dpif_get_table(const struct rule_dpif *); |
70742c7f | 100 | |
56c091ec SH |
101 | bool table_is_internal(uint8_t table_id); |
102 | ||
dc723c44 | 103 | const struct rule_actions *rule_dpif_get_actions(const struct rule_dpif *); |
888ac0d7 SH |
104 | uint32_t rule_dpif_get_recirc_id(struct rule_dpif *); |
105 | void rule_set_recirc_id(struct rule *, uint32_t id); | |
ad3efdcb | 106 | |
70742c7f | 107 | ovs_be64 rule_dpif_get_flow_cookie(const struct rule_dpif *rule); |
9583bc14 | 108 | |
70742c7f EJ |
109 | void rule_dpif_reduce_timeouts(struct rule_dpif *rule, uint16_t idle_timeout, |
110 | uint16_t hard_timeout); | |
9583bc14 | 111 | |
70742c7f EJ |
112 | void choose_miss_rule(enum ofputil_port_config, |
113 | struct rule_dpif *miss_rule, | |
114 | struct rule_dpif *no_packet_in_rule, | |
1a7c0cd7 | 115 | struct rule_dpif **rule, bool take_ref); |
ec89fc6f | 116 | |
1e684d7d RW |
117 | void group_dpif_credit_stats(struct group_dpif *, |
118 | struct ofputil_bucket *, | |
119 | const struct dpif_flow_stats *); | |
f4fb341b SH |
120 | bool group_dpif_lookup(struct ofproto_dpif *ofproto, uint32_t group_id, |
121 | struct group_dpif **group); | |
122 | ||
f4fb341b SH |
123 | void group_dpif_get_buckets(const struct group_dpif *group, |
124 | const struct list **buckets); | |
125 | enum ofp11_group_type group_dpif_get_type(const struct group_dpif *group); | |
126 | ||
46c88433 | 127 | bool ofproto_has_vlan_splinters(const struct ofproto_dpif *); |
4e022ec0 AW |
128 | ofp_port_t vsp_realdev_to_vlandev(const struct ofproto_dpif *, |
129 | ofp_port_t realdev_ofp_port, | |
130 | ovs_be16 vlan_tci); | |
cc377352 EJ |
131 | bool vsp_adjust_flow(const struct ofproto_dpif *, struct flow *, |
132 | struct ofpbuf *packet); | |
9583bc14 | 133 | |
419460f4 AW |
134 | int ofproto_dpif_execute_actions(struct ofproto_dpif *, const struct flow *, |
135 | struct rule_dpif *, const struct ofpact *, | |
84f0f298 | 136 | size_t ofpacts_len, struct ofpbuf *); |
46c88433 | 137 | void ofproto_dpif_send_packet_in(struct ofproto_dpif *, |
0fb7792a | 138 | struct ofproto_packet_in *); |
6b83a3c5 | 139 | bool ofproto_dpif_wants_packet_in_on_miss(struct ofproto_dpif *); |
91d6cd12 | 140 | int ofproto_dpif_send_packet(const struct ofport_dpif *, struct ofpbuf *); |
3d9c5e58 | 141 | void ofproto_dpif_flow_mod(struct ofproto_dpif *, struct ofputil_flow_mod *); |
1ebeaaa7 | 142 | struct rule_dpif *ofproto_dpif_refresh_rule(struct rule_dpif *); |
46c88433 | 143 | |
8449c4d6 EJ |
144 | struct ofport_dpif *odp_port_to_ofport(const struct dpif_backer *, odp_port_t); |
145 | ||
572f732a AZ |
146 | /* |
147 | * Recirculation | |
148 | * ============= | |
149 | * | |
9b516652 YT |
150 | * Recirculation is a technique to allow a frame to re-enter the packet |
151 | * processing path for one or multiple times to achieve more flexible packet | |
152 | * processing in the data path. MPLS handling and selecting bond slave port | |
153 | * of a bond ports. | |
572f732a AZ |
154 | * |
155 | * Data path and user space interface | |
156 | * ----------------------------------- | |
157 | * | |
9b516652 YT |
158 | * Two new fields, recirc_id and dp_hash, are added to the current flow data |
159 | * structure. They are both of type uint32_t. In addition, a new action, | |
160 | * RECIRC, are added. | |
572f732a | 161 | * |
9b516652 YT |
162 | * The value recirc_id is used to distinguish a packet from multiple |
163 | * iterations of recirculation. A packet initially received is considered of | |
164 | * having recirc_id of 0. Recirc_id is managed by the user space, opaque to | |
165 | * the data path. | |
572f732a AZ |
166 | * |
167 | * On the other hand, dp_hash can only be computed by the data path, opaque to | |
9b516652 YT |
168 | * the user space. In fact, user space may not able to recompute the hash |
169 | * value. The dp_hash value should be wildcarded when for a newly received | |
170 | * packet. RECIRC action specifies whether the hash is computed. If computed, | |
171 | * how many fields to be included in the hash computation. The computed hash | |
172 | * value is stored into the dp_hash field prior to recirculation. | |
173 | * | |
174 | * The RECIRC action computes and set the dp_hash field, set the recirc_id | |
175 | * field and then reprocess the packet as if it was received on the same input | |
176 | * port. RECIRC action works like a function call; actions listed behind the | |
177 | * RECIRC action will be executed after its execution. RECIRC action can be | |
178 | * nested, data path implementation limits the number of recirculation executed | |
572f732a AZ |
179 | * to prevent unreasonable nesting depth or infinite loop. |
180 | * | |
0746a84f | 181 | * Both flow fields and the RECIRC action are exposed as OpenFlow fields via |
572f732a AZ |
182 | * Nicira extensions. |
183 | * | |
184 | * Post recirculation flow | |
185 | * ------------------------ | |
186 | * | |
0746a84f | 187 | * At the OpenFlow level, post recirculation rules are always hidden from the |
9b516652 YT |
188 | * controller. They are installed in table 254 which is set up as a hidden |
189 | * table during boot time. Those rules are managed by the local user space | |
190 | * program only. | |
572f732a | 191 | * |
9b516652 YT |
192 | * To speed up the classifier look up process, recirc_id is always reflected |
193 | * into the metadata field, since recirc_id is required to be exactly matched. | |
572f732a AZ |
194 | * |
195 | * Classifier look up always starts with table 254. A post recirculation flow | |
196 | * lookup should find its hidden rule within this table. On the other hand, A | |
197 | * newly received packet should miss all post recirculation rules because its | |
198 | * recirc_id is zero, then hit a pre-installed lower priority rule to redirect | |
199 | * classifier to look up starting from table 0: | |
200 | * | |
201 | * * , actions=resubmit(,0) | |
202 | * | |
203 | * Post recirculation data path flows are managed like other data path flows. | |
204 | * They are created on demand. Miss handling, stats collection and revalidation | |
205 | * work the same way as regular flows. | |
206 | */ | |
207 | ||
f5374617 AZ |
208 | uint32_t ofproto_dpif_alloc_recirc_id(struct ofproto_dpif *ofproto); |
209 | void ofproto_dpif_free_recirc_id(struct ofproto_dpif *ofproto, uint32_t recirc_id); | |
adcf00ba | 210 | int ofproto_dpif_add_internal_flow(struct ofproto_dpif *, |
fe99c360 | 211 | const struct match *, int priority, |
290ad78a | 212 | uint16_t idle_timeout, |
adcf00ba AZ |
213 | const struct ofpbuf *ofpacts, |
214 | struct rule **rulep); | |
215 | int ofproto_dpif_delete_internal_flow(struct ofproto_dpif *, struct match *, | |
216 | int priority); | |
217 | ||
003ce655 JR |
218 | /* Number of implemented OpenFlow tables. */ |
219 | enum { N_TABLES = 255 }; | |
220 | enum { TBL_INTERNAL = N_TABLES - 1 }; /* Used for internal hidden rules. */ | |
221 | BUILD_ASSERT_DECL(N_TABLES >= 2 && N_TABLES <= 255); | |
222 | ||
223 | \f | |
224 | /* struct rule_dpif has struct rule as it's first member. */ | |
225 | #define RULE_CAST(RULE) ((struct rule *)RULE) | |
809c7548 RW |
226 | #define GROUP_CAST(GROUP) ((struct ofgroup *)GROUP) |
227 | ||
228 | static inline struct group_dpif* group_dpif_ref(struct group_dpif *group) | |
229 | { | |
230 | if (group) { | |
231 | ofproto_group_ref(GROUP_CAST(group)); | |
232 | } | |
233 | return group; | |
234 | } | |
235 | ||
236 | static inline void group_dpif_unref(struct group_dpif *group) | |
237 | { | |
238 | if (group) { | |
239 | ofproto_group_unref(GROUP_CAST(group)); | |
240 | } | |
241 | } | |
003ce655 JR |
242 | |
243 | static inline void rule_dpif_ref(struct rule_dpif *rule) | |
244 | { | |
245 | if (rule) { | |
246 | ofproto_rule_ref(RULE_CAST(rule)); | |
247 | } | |
248 | } | |
249 | ||
f5d16e55 JR |
250 | static inline bool rule_dpif_try_ref(struct rule_dpif *rule) |
251 | { | |
252 | if (rule) { | |
253 | return ofproto_rule_try_ref(RULE_CAST(rule)); | |
254 | } | |
255 | return false; | |
256 | } | |
257 | ||
258 | ||
003ce655 JR |
259 | static inline void rule_dpif_unref(struct rule_dpif *rule) |
260 | { | |
261 | if (rule) { | |
262 | ofproto_rule_unref(RULE_CAST(rule)); | |
263 | } | |
264 | } | |
265 | ||
266 | static inline bool rule_dpif_is_fail_open(const struct rule_dpif *rule) | |
267 | { | |
268 | return is_fail_open_rule(RULE_CAST(rule)); | |
269 | } | |
270 | ||
271 | static inline bool rule_dpif_is_table_miss(const struct rule_dpif *rule) | |
272 | { | |
273 | return rule_is_table_miss(RULE_CAST(rule)); | |
274 | } | |
275 | ||
276 | /* Returns true if 'rule' is an internal rule, false otherwise. */ | |
277 | static inline bool rule_dpif_is_internal(const struct rule_dpif *rule) | |
278 | { | |
279 | return RULE_CAST(rule)->table_id == TBL_INTERNAL; | |
280 | } | |
281 | ||
282 | #undef RULE_CAST | |
283 | ||
a36de779 | 284 | bool ovs_native_tunneling_is_on(struct ofproto_dpif *ofproto); |
9583bc14 | 285 | #endif /* ofproto-dpif.h */ |