]>
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 EJ |
29 | |
30 | union user_action_cookie; | |
70742c7f | 31 | struct dpif_flow_stats; |
f5374617 | 32 | struct ofproto; |
46c88433 | 33 | struct ofproto_dpif; |
0fb7792a | 34 | struct ofproto_packet_in; |
46c88433 | 35 | struct ofport_dpif; |
8449c4d6 | 36 | struct dpif_backer; |
70742c7f | 37 | struct OVS_LOCKABLE rule_dpif; |
f4fb341b | 38 | struct OVS_LOCKABLE group_dpif; |
9583bc14 | 39 | |
6d328fa2 SH |
40 | enum rule_dpif_lookup_verdict { |
41 | RULE_DPIF_LOOKUP_VERDICT_MATCH, /* A match occurred. */ | |
42 | RULE_DPIF_LOOKUP_VERDICT_CONTROLLER, /* A miss occurred and the packet | |
43 | * should be passed to | |
44 | * the controller. */ | |
45 | RULE_DPIF_LOOKUP_VERDICT_DROP, /* A miss occurred and the packet | |
46 | * should be dropped. */ | |
6b83a3c5 SH |
47 | RULE_DPIF_LOOKUP_VERDICT_DEFAULT, /* A miss occurred and the packet |
48 | * should handled by the default | |
49 | * miss behaviour. | |
50 | * For pre-OF1.3 it should be | |
51 | * forwarded to the controller. | |
52 | * For OF1.3+ it should be | |
53 | * dropped. */ | |
6d328fa2 SH |
54 | }; |
55 | ||
6a4d3ab5 BP |
56 | /* For lock annotation below only. */ |
57 | extern struct ovs_rwlock xlate_rwlock; | |
58 | ||
e1ec7dd4 EJ |
59 | /* Ofproto-dpif -- DPIF based ofproto implementation. |
60 | * | |
61 | * Ofproto-dpif provides an ofproto implementation for those platforms which | |
62 | * implement the netdev and dpif interface defined in netdev.h and dpif.h. The | |
63 | * most important of which is the Linux Kernel Module (dpif-linux), but | |
64 | * alternatives are supported such as a userspace only implementation | |
65 | * (dpif-netdev), and a dummy implementation used for unit testing. | |
66 | * | |
67 | * Ofproto-dpif is divided into three major chunks. | |
68 | * | |
69 | * - ofproto-dpif.c | |
70 | * The main ofproto-dpif module is responsible for implementing the | |
71 | * provider interface, installing and removing datapath flows, maintaining | |
72 | * packet statistics, running protocols (BFD, LACP, STP, etc), and | |
73 | * configuring relevant submodules. | |
74 | * | |
75 | * - ofproto-dpif-upcall.c | |
76 | * Ofproto-dpif-upcall is responsible for retrieving upcalls from the kernel, | |
77 | * processing miss upcalls, and handing more complex ones up to the main | |
78 | * ofproto-dpif module. Miss upcall processing boils down to figuring out | |
79 | * what each packet's actions are, executing them (i.e. asking the kernel to | |
80 | * forward it), and handing it up to ofproto-dpif to decided whether or not | |
81 | * to install a kernel flow. | |
82 | * | |
83 | * - ofproto-dpif-xlate.c | |
84 | * Ofproto-dpif-xlate is responsible for translating translating OpenFlow | |
85 | * actions into datapath actions. */ | |
86 | ||
8bfd0fda | 87 | size_t ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *); |
adcf00ba | 88 | bool ofproto_dpif_get_enable_recirc(const struct ofproto_dpif *); |
8bfd0fda | 89 | |
adcf00ba | 90 | uint8_t rule_dpif_lookup(struct ofproto_dpif *, struct flow *, |
1a7c0cd7 JR |
91 | struct flow_wildcards *, struct rule_dpif **rule, |
92 | bool take_ref); | |
ad3efdcb | 93 | |
6d328fa2 SH |
94 | enum rule_dpif_lookup_verdict rule_dpif_lookup_from_table(struct ofproto_dpif *, |
95 | const struct flow *, | |
96 | struct flow_wildcards *, | |
97 | bool force_controller_on_miss, | |
98 | uint8_t *table_id, | |
1a7c0cd7 JR |
99 | struct rule_dpif **rule, |
100 | bool take_ref); | |
70742c7f | 101 | |
003ce655 JR |
102 | static inline void rule_dpif_ref(struct rule_dpif *); |
103 | static inline void rule_dpif_unref(struct rule_dpif *); | |
70742c7f | 104 | |
cd1acaab SH |
105 | void rule_dpif_credit_stats(struct rule_dpif *rule , |
106 | const struct dpif_flow_stats *); | |
70742c7f | 107 | |
003ce655 JR |
108 | static inline bool rule_dpif_is_fail_open(const struct rule_dpif *); |
109 | static inline bool rule_dpif_is_table_miss(const struct rule_dpif *); | |
110 | static inline bool rule_dpif_is_internal(const struct rule_dpif *); | |
111 | ||
adcf00ba | 112 | uint8_t rule_dpif_get_table(const struct rule_dpif *); |
70742c7f | 113 | |
56c091ec SH |
114 | bool table_is_internal(uint8_t table_id); |
115 | ||
dc723c44 | 116 | const struct rule_actions *rule_dpif_get_actions(const struct rule_dpif *); |
ad3efdcb | 117 | |
70742c7f | 118 | ovs_be64 rule_dpif_get_flow_cookie(const struct rule_dpif *rule); |
9583bc14 | 119 | |
70742c7f EJ |
120 | void rule_dpif_reduce_timeouts(struct rule_dpif *rule, uint16_t idle_timeout, |
121 | uint16_t hard_timeout); | |
9583bc14 | 122 | |
70742c7f EJ |
123 | void choose_miss_rule(enum ofputil_port_config, |
124 | struct rule_dpif *miss_rule, | |
125 | struct rule_dpif *no_packet_in_rule, | |
1a7c0cd7 | 126 | struct rule_dpif **rule, bool take_ref); |
ec89fc6f | 127 | |
f4fb341b SH |
128 | bool group_dpif_lookup(struct ofproto_dpif *ofproto, uint32_t group_id, |
129 | struct group_dpif **group); | |
130 | ||
131 | void group_dpif_release(struct group_dpif *group); | |
132 | ||
133 | void group_dpif_get_buckets(const struct group_dpif *group, | |
134 | const struct list **buckets); | |
135 | enum ofp11_group_type group_dpif_get_type(const struct group_dpif *group); | |
136 | ||
46c88433 | 137 | bool ofproto_has_vlan_splinters(const struct ofproto_dpif *); |
4e022ec0 AW |
138 | ofp_port_t vsp_realdev_to_vlandev(const struct ofproto_dpif *, |
139 | ofp_port_t realdev_ofp_port, | |
140 | ovs_be16 vlan_tci); | |
8449c4d6 | 141 | bool vsp_adjust_flow(const struct ofproto_dpif *, struct flow *); |
9583bc14 | 142 | |
419460f4 AW |
143 | int ofproto_dpif_execute_actions(struct ofproto_dpif *, const struct flow *, |
144 | struct rule_dpif *, const struct ofpact *, | |
6a4d3ab5 BP |
145 | size_t ofpacts_len, struct ofpbuf *) |
146 | OVS_EXCLUDED(xlate_rwlock); | |
46c88433 | 147 | void ofproto_dpif_send_packet_in(struct ofproto_dpif *, |
0fb7792a | 148 | struct ofproto_packet_in *); |
6b83a3c5 | 149 | bool ofproto_dpif_wants_packet_in_on_miss(struct ofproto_dpif *); |
91d6cd12 | 150 | int ofproto_dpif_send_packet(const struct ofport_dpif *, struct ofpbuf *); |
3d9c5e58 | 151 | void ofproto_dpif_flow_mod(struct ofproto_dpif *, struct ofputil_flow_mod *); |
1ebeaaa7 | 152 | struct rule_dpif *ofproto_dpif_refresh_rule(struct rule_dpif *); |
46c88433 | 153 | |
8449c4d6 EJ |
154 | struct ofport_dpif *odp_port_to_ofport(const struct dpif_backer *, odp_port_t); |
155 | ||
572f732a AZ |
156 | /* |
157 | * Recirculation | |
158 | * ============= | |
159 | * | |
9b516652 YT |
160 | * Recirculation is a technique to allow a frame to re-enter the packet |
161 | * processing path for one or multiple times to achieve more flexible packet | |
162 | * processing in the data path. MPLS handling and selecting bond slave port | |
163 | * of a bond ports. | |
572f732a AZ |
164 | * |
165 | * Data path and user space interface | |
166 | * ----------------------------------- | |
167 | * | |
9b516652 YT |
168 | * Two new fields, recirc_id and dp_hash, are added to the current flow data |
169 | * structure. They are both of type uint32_t. In addition, a new action, | |
170 | * RECIRC, are added. | |
572f732a | 171 | * |
9b516652 YT |
172 | * The value recirc_id is used to distinguish a packet from multiple |
173 | * iterations of recirculation. A packet initially received is considered of | |
174 | * having recirc_id of 0. Recirc_id is managed by the user space, opaque to | |
175 | * the data path. | |
572f732a AZ |
176 | * |
177 | * On the other hand, dp_hash can only be computed by the data path, opaque to | |
9b516652 YT |
178 | * the user space. In fact, user space may not able to recompute the hash |
179 | * value. The dp_hash value should be wildcarded when for a newly received | |
180 | * packet. RECIRC action specifies whether the hash is computed. If computed, | |
181 | * how many fields to be included in the hash computation. The computed hash | |
182 | * value is stored into the dp_hash field prior to recirculation. | |
183 | * | |
184 | * The RECIRC action computes and set the dp_hash field, set the recirc_id | |
185 | * field and then reprocess the packet as if it was received on the same input | |
186 | * port. RECIRC action works like a function call; actions listed behind the | |
187 | * RECIRC action will be executed after its execution. RECIRC action can be | |
188 | * nested, data path implementation limits the number of recirculation executed | |
572f732a AZ |
189 | * to prevent unreasonable nesting depth or infinite loop. |
190 | * | |
191 | * Both flow fields and the RECIRC action are exposed as open flow fields via | |
192 | * Nicira extensions. | |
193 | * | |
194 | * Post recirculation flow | |
195 | * ------------------------ | |
196 | * | |
197 | * At the open flow level, post recirculation rules are always hidden from the | |
9b516652 YT |
198 | * controller. They are installed in table 254 which is set up as a hidden |
199 | * table during boot time. Those rules are managed by the local user space | |
200 | * program only. | |
572f732a | 201 | * |
9b516652 YT |
202 | * To speed up the classifier look up process, recirc_id is always reflected |
203 | * into the metadata field, since recirc_id is required to be exactly matched. | |
572f732a AZ |
204 | * |
205 | * Classifier look up always starts with table 254. A post recirculation flow | |
206 | * lookup should find its hidden rule within this table. On the other hand, A | |
207 | * newly received packet should miss all post recirculation rules because its | |
208 | * recirc_id is zero, then hit a pre-installed lower priority rule to redirect | |
209 | * classifier to look up starting from table 0: | |
210 | * | |
211 | * * , actions=resubmit(,0) | |
212 | * | |
213 | * Post recirculation data path flows are managed like other data path flows. | |
214 | * They are created on demand. Miss handling, stats collection and revalidation | |
215 | * work the same way as regular flows. | |
216 | */ | |
217 | ||
f5374617 AZ |
218 | uint32_t ofproto_dpif_alloc_recirc_id(struct ofproto_dpif *ofproto); |
219 | void ofproto_dpif_free_recirc_id(struct ofproto_dpif *ofproto, uint32_t recirc_id); | |
adcf00ba AZ |
220 | int ofproto_dpif_add_internal_flow(struct ofproto_dpif *, |
221 | struct match *, int priority, | |
222 | const struct ofpbuf *ofpacts, | |
223 | struct rule **rulep); | |
224 | int ofproto_dpif_delete_internal_flow(struct ofproto_dpif *, struct match *, | |
225 | int priority); | |
226 | ||
003ce655 JR |
227 | /* Number of implemented OpenFlow tables. */ |
228 | enum { N_TABLES = 255 }; | |
229 | enum { TBL_INTERNAL = N_TABLES - 1 }; /* Used for internal hidden rules. */ | |
230 | BUILD_ASSERT_DECL(N_TABLES >= 2 && N_TABLES <= 255); | |
231 | ||
232 | \f | |
233 | /* struct rule_dpif has struct rule as it's first member. */ | |
234 | #define RULE_CAST(RULE) ((struct rule *)RULE) | |
235 | ||
236 | static inline void rule_dpif_ref(struct rule_dpif *rule) | |
237 | { | |
238 | if (rule) { | |
239 | ofproto_rule_ref(RULE_CAST(rule)); | |
240 | } | |
241 | } | |
242 | ||
243 | static inline void rule_dpif_unref(struct rule_dpif *rule) | |
244 | { | |
245 | if (rule) { | |
246 | ofproto_rule_unref(RULE_CAST(rule)); | |
247 | } | |
248 | } | |
249 | ||
250 | static inline bool rule_dpif_is_fail_open(const struct rule_dpif *rule) | |
251 | { | |
252 | return is_fail_open_rule(RULE_CAST(rule)); | |
253 | } | |
254 | ||
255 | static inline bool rule_dpif_is_table_miss(const struct rule_dpif *rule) | |
256 | { | |
257 | return rule_is_table_miss(RULE_CAST(rule)); | |
258 | } | |
259 | ||
260 | /* Returns true if 'rule' is an internal rule, false otherwise. */ | |
261 | static inline bool rule_dpif_is_internal(const struct rule_dpif *rule) | |
262 | { | |
263 | return RULE_CAST(rule)->table_id == TBL_INTERNAL; | |
264 | } | |
265 | ||
266 | #undef RULE_CAST | |
267 | ||
9583bc14 | 268 | #endif /* ofproto-dpif.h */ |