]>
Commit | Line | Data |
---|---|---|
1 | /* Copyright (c) 2009-2017 Nicira, Inc. | |
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 | /* ofproto-dpif -- DPIF based ofproto implementation. | |
19 | * | |
20 | * ofproto-dpif provides an ofproto implementation for those platforms which | |
21 | * implement the netdev and dpif interface defined in netdev.h and dpif.h. The | |
22 | * most important of which is the Linux Kernel Module (dpif-netlink), but | |
23 | * alternatives are supported such as a userspace only implementation | |
24 | * (dpif-netdev), and a dummy implementation used for unit testing. | |
25 | * | |
26 | * ofproto-dpif is divided into three major chunks. | |
27 | * | |
28 | * - ofproto-dpif.c | |
29 | * The main ofproto-dpif module is responsible for implementing the | |
30 | * provider interface, installing and removing datapath flows, maintaining | |
31 | * packet statistics, running protocols (BFD, LACP, STP, etc), and | |
32 | * configuring relevant submodules. | |
33 | * | |
34 | * - ofproto-dpif-upcall.c | |
35 | * ofproto-dpif-upcall is responsible for retrieving upcalls from the kernel, | |
36 | * processing miss upcalls, and handing more complex ones up to the main | |
37 | * ofproto-dpif module. Miss upcall processing boils down to figuring out | |
38 | * what each packet's actions are, executing them (i.e. asking the kernel to | |
39 | * forward it), and handing it up to ofproto-dpif to decided whether or not | |
40 | * to install a kernel flow. | |
41 | * | |
42 | * - ofproto-dpif-xlate.c | |
43 | * ofproto-dpif-xlate is responsible for translating OpenFlow actions into | |
44 | * datapath actions. | |
45 | */ | |
46 | ||
47 | #include <stdint.h> | |
48 | ||
49 | #include "dpif.h" | |
50 | #include "fail-open.h" | |
51 | #include "hmapx.h" | |
52 | #include "odp-util.h" | |
53 | #include "id-pool.h" | |
54 | #include "ovs-thread.h" | |
55 | #include "ofproto-provider.h" | |
56 | #include "util.h" | |
57 | #include "ovs-thread.h" | |
58 | ||
59 | struct dpif_flow_stats; | |
60 | struct ofproto_async_msg; | |
61 | struct ofproto_dpif; | |
62 | struct uuid; | |
63 | struct xlate_cache; | |
64 | struct xlate_ctx; | |
65 | ||
66 | /* Number of implemented OpenFlow tables. */ | |
67 | enum { N_TABLES = 255 }; | |
68 | enum { TBL_INTERNAL = N_TABLES - 1 }; /* Used for internal hidden rules. */ | |
69 | BUILD_ASSERT_DECL(N_TABLES >= 2 && N_TABLES <= 255); | |
70 | ||
71 | struct rule_dpif { | |
72 | struct rule up; | |
73 | ||
74 | /* These statistics: | |
75 | * | |
76 | * - Do include packets and bytes from datapath flows which have not | |
77 | * recently been processed by a revalidator. */ | |
78 | struct ovs_mutex stats_mutex; | |
79 | struct dpif_flow_detailed_stats stats OVS_GUARDED; | |
80 | ||
81 | /* In non-NULL, will point to a new rule (for which a reference is held) to | |
82 | * which all the stats updates should be forwarded. This exists only | |
83 | * transitionally when flows are replaced. | |
84 | * | |
85 | * Protected by stats_mutex. If both 'rule->stats_mutex' and | |
86 | * 'rule->new_rule->stats_mutex' must be held together, acquire them in that | |
87 | * order, */ | |
88 | struct rule_dpif *new_rule OVS_GUARDED; | |
89 | bool forward_counts OVS_GUARDED; /* Forward counts? 'used' time will be | |
90 | * forwarded in all cases. */ | |
91 | ||
92 | /* If non-zero then the recirculation id that has | |
93 | * been allocated for use with this rule. | |
94 | * The recirculation id and associated internal flow should | |
95 | * be freed when the rule is freed */ | |
96 | uint32_t recirc_id; | |
97 | }; | |
98 | ||
99 | struct rule_dpif *rule_dpif_lookup_from_table(struct ofproto_dpif *, | |
100 | ovs_version_t, struct flow *, | |
101 | struct flow_wildcards *, | |
102 | const struct dpif_flow_stats *, | |
103 | uint8_t *table_id, | |
104 | ofp_port_t in_port, | |
105 | bool may_packet_in, | |
106 | bool honor_table_miss, | |
107 | struct xlate_cache *); | |
108 | ||
109 | void rule_dpif_credit_stats(struct rule_dpif *, | |
110 | const struct dpif_flow_stats *, bool); | |
111 | ||
112 | void rule_set_recirc_id(struct rule *, uint32_t id); | |
113 | ||
114 | /* Returns true if 'rule' is an internal rule, false otherwise. */ | |
115 | static inline bool | |
116 | rule_dpif_is_internal(const struct rule_dpif *rule) | |
117 | { | |
118 | return rule->up.table_id == TBL_INTERNAL; | |
119 | } | |
120 | \f | |
121 | /* Groups. */ | |
122 | ||
123 | enum group_selection_method { | |
124 | SEL_METHOD_DEFAULT, | |
125 | SEL_METHOD_DP_HASH, | |
126 | SEL_METHOD_HASH, | |
127 | }; | |
128 | ||
129 | struct group_dpif { | |
130 | struct ofgroup up; | |
131 | ||
132 | /* These statistics: | |
133 | * | |
134 | * - Do include packets and bytes from datapath flows which have not | |
135 | * recently been processed by a revalidator. */ | |
136 | struct ovs_mutex stats_mutex; | |
137 | uint64_t packet_count OVS_GUARDED; /* Number of packets received. */ | |
138 | uint64_t byte_count OVS_GUARDED; /* Number of bytes received. */ | |
139 | ||
140 | enum group_selection_method selection_method; | |
141 | enum ovs_hash_alg hash_alg; /* dp_hash algorithm to be applied. */ | |
142 | uint32_t hash_basis; /* Basis for dp_hash. */ | |
143 | uint32_t hash_mask; /* Used to mask dp_hash (2^N - 1).*/ | |
144 | struct ofputil_bucket **hash_map; /* Map hash values to buckets. */ | |
145 | }; | |
146 | ||
147 | void group_dpif_credit_stats(struct group_dpif *, | |
148 | struct ofputil_bucket *, | |
149 | const struct dpif_flow_stats *); | |
150 | struct group_dpif *group_dpif_lookup(struct ofproto_dpif *, | |
151 | uint32_t group_id, ovs_version_t version, | |
152 | bool take_ref); | |
153 | ||
154 | \f | |
155 | /* Backers. | |
156 | * | |
157 | * A "backer" is the datapath (dpif) on which an dpif-based bridge (an | |
158 | * ofproto-dpif) resides. A backer can host several bridges, but a bridge is | |
159 | * backed by only a single dpif. */ | |
160 | ||
161 | ||
162 | /* DPIF_SUPPORT_FIELD(TYPE, FIELD_NAME, FIELD_DESCRIPTION) | |
163 | * | |
164 | * Each 'DPIF_SUPPORT_FIELD' defines a member in 'struct dpif_backer_support' | |
165 | * and represents support for a datapath action. | |
166 | * They are defined as macros to keep 'dpif_show_support()' in sync | |
167 | * as new fields are added. */ | |
168 | #define DPIF_SUPPORT_FIELDS \ | |
169 | /* True if the datapath supports masked data in OVS_ACTION_ATTR_SET \ | |
170 | * actions. */ \ | |
171 | DPIF_SUPPORT_FIELD(bool, masked_set_action, "Masked set action") \ | |
172 | \ | |
173 | /* True if the datapath supports tnl_push and pop actions. */ \ | |
174 | DPIF_SUPPORT_FIELD(bool, tnl_push_pop, "Tunnel push pop") \ | |
175 | \ | |
176 | /* True if the datapath supports OVS_FLOW_ATTR_UFID. */ \ | |
177 | DPIF_SUPPORT_FIELD(bool, ufid, "Ufid") \ | |
178 | \ | |
179 | /* True if the datapath supports OVS_ACTION_ATTR_TRUNC action. */ \ | |
180 | DPIF_SUPPORT_FIELD(bool, trunc, "Truncate action") \ | |
181 | \ | |
182 | /* True if the datapath supports OVS_ACTION_ATTR_CLONE action. */ \ | |
183 | DPIF_SUPPORT_FIELD(bool, clone, "Clone action") \ | |
184 | \ | |
185 | /* Maximum level of nesting allowed by OVS_ACTION_ATTR_SAMPLE action. */\ | |
186 | DPIF_SUPPORT_FIELD(size_t, sample_nesting, "Sample nesting") \ | |
187 | \ | |
188 | /* OVS_CT_ATTR_EVENTMASK supported by OVS_ACTION_ATTR_CT action. */ \ | |
189 | DPIF_SUPPORT_FIELD(bool, ct_eventmask, "Conntrack eventmask") \ | |
190 | \ | |
191 | /* True if the datapath supports OVS_ACTION_ATTR_CT_CLEAR action. */ \ | |
192 | DPIF_SUPPORT_FIELD(bool, ct_clear, "Conntrack clear") \ | |
193 | \ | |
194 | /* Highest supported dp_hash algorithm. */ \ | |
195 | DPIF_SUPPORT_FIELD(size_t, max_hash_alg, "Max dp_hash algorithm") \ | |
196 | \ | |
197 | /* True if the datapath supports OVS_ACTION_ATTR_CHECK_PKT_LEN. */ \ | |
198 | DPIF_SUPPORT_FIELD(bool, check_pkt_len, "Check pkt length action") \ | |
199 | \ | |
200 | /* True if the datapath supports OVS_CT_ATTR_TIMEOUT in \ | |
201 | * OVS_ACTION_ATTR_CT action. */ \ | |
202 | DPIF_SUPPORT_FIELD(bool, ct_timeout, "Conntrack timeout policy") \ | |
203 | \ | |
204 | /* True if the datapath supports explicit drop action. */ \ | |
205 | DPIF_SUPPORT_FIELD(bool, explicit_drop_action, "Explicit Drop action") | |
206 | ||
207 | ||
208 | /* Stores the various features which the corresponding backer supports. */ | |
209 | struct dpif_backer_support { | |
210 | #define DPIF_SUPPORT_FIELD(TYPE, NAME, TITLE) TYPE NAME; | |
211 | DPIF_SUPPORT_FIELDS | |
212 | #undef DPIF_SUPPORT_FIELD | |
213 | ||
214 | /* Each member represents support for related OVS_KEY_ATTR_* fields. */ | |
215 | struct odp_support odp; | |
216 | }; | |
217 | ||
218 | /* Reasons that we might need to revalidate every datapath flow, and | |
219 | * corresponding coverage counters. | |
220 | * | |
221 | * A value of 0 means that there is no need to revalidate. | |
222 | * | |
223 | * It would be nice to have some cleaner way to integrate with coverage | |
224 | * counters, but with only a few reasons I guess this is good enough for | |
225 | * now. */ | |
226 | enum revalidate_reason { | |
227 | REV_RECONFIGURE = 1, /* Switch configuration changed. */ | |
228 | REV_STP, /* Spanning tree protocol port status change. */ | |
229 | REV_RSTP, /* RSTP port status change. */ | |
230 | REV_BOND, /* Bonding changed. */ | |
231 | REV_PORT_TOGGLED, /* Port enabled or disabled by CFM, LACP, ...*/ | |
232 | REV_FLOW_TABLE, /* Flow table changed. */ | |
233 | REV_MAC_LEARNING, /* Mac learning changed. */ | |
234 | REV_MCAST_SNOOPING, /* Multicast snooping changed. */ | |
235 | }; | |
236 | ||
237 | /* All datapaths of a given type share a single dpif backer instance. */ | |
238 | struct dpif_backer { | |
239 | char *type; | |
240 | int refcount; | |
241 | struct dpif *dpif; | |
242 | struct udpif *udpif; | |
243 | ||
244 | struct ovs_rwlock odp_to_ofport_lock; | |
245 | struct hmap odp_to_ofport_map OVS_GUARDED; /* Contains "struct ofport"s. */ | |
246 | ||
247 | struct simap tnl_backers; /* Set of dpif ports backing tunnels. */ | |
248 | ||
249 | enum revalidate_reason need_revalidate; /* Revalidate all flows. */ | |
250 | ||
251 | bool recv_set_enable; /* Enables or disables receiving packets. */ | |
252 | ||
253 | /* Meter. */ | |
254 | struct id_pool *meter_ids; /* Datapath meter allocation. */ | |
255 | ||
256 | /* Connection tracking. */ | |
257 | struct id_pool *tp_ids; /* Datapath timeout policy id | |
258 | * allocation. */ | |
259 | struct cmap ct_zones; /* "struct ct_zone"s indexed by zone | |
260 | * id. */ | |
261 | struct hmap ct_tps; /* "struct ct_timeout_policy"s indexed | |
262 | * by timeout policy (struct simap). */ | |
263 | struct ovs_list ct_tp_kill_list; /* A list of timeout policy to be | |
264 | * deleted. */ | |
265 | ||
266 | /* Version string of the datapath stored in OVSDB. */ | |
267 | char *dp_version_string; | |
268 | ||
269 | /* Datapath feature support. */ | |
270 | struct dpif_backer_support bt_support; /* Boot time support. Set once | |
271 | when vswitch starts up, then | |
272 | it is read only through out | |
273 | the life time of vswitchd. */ | |
274 | struct dpif_backer_support rt_support; /* Runtime support. Can be | |
275 | set to a lower level in | |
276 | feature than 'bt_support'. */ | |
277 | ||
278 | struct atomic_count tnl_count; | |
279 | }; | |
280 | ||
281 | /* All existing ofproto_backer instances, indexed by ofproto->up.type. */ | |
282 | extern struct shash all_dpif_backers; | |
283 | ||
284 | struct ofport_dpif *odp_port_to_ofport(const struct dpif_backer *, odp_port_t); | |
285 | \f | |
286 | /* A bridge based on a "dpif" datapath. */ | |
287 | ||
288 | struct ofproto_dpif { | |
289 | /* In 'all_ofproto_dpifs_by_name'. */ | |
290 | struct hmap_node all_ofproto_dpifs_by_name_node; | |
291 | ||
292 | /* In 'all_ofproto_dpifs_by_uuid'. */ | |
293 | struct hmap_node all_ofproto_dpifs_by_uuid_node; | |
294 | ||
295 | struct ofproto up; | |
296 | struct dpif_backer *backer; | |
297 | ||
298 | /* Unique identifier for this instantiation of this bridge in this running | |
299 | * process. */ | |
300 | struct uuid uuid; | |
301 | ||
302 | ATOMIC(ovs_version_t) tables_version; /* For classifier lookups. */ | |
303 | ||
304 | uint64_t dump_seq; /* Last read of udpif_dump_seq(). */ | |
305 | ||
306 | /* Special OpenFlow rules. */ | |
307 | struct rule_dpif *miss_rule; /* Sends flow table misses to controller. */ | |
308 | struct rule_dpif *no_packet_in_rule; /* Drops flow table misses. */ | |
309 | struct rule_dpif *drop_frags_rule; /* Used in OFPUTIL_FRAG_DROP mode. */ | |
310 | ||
311 | /* Bridging. */ | |
312 | struct netflow *netflow; | |
313 | struct dpif_sflow *sflow; | |
314 | struct dpif_ipfix *ipfix; | |
315 | struct hmap bundles; /* Contains "struct ofbundle"s. */ | |
316 | struct mac_learning *ml; | |
317 | struct mcast_snooping *ms; | |
318 | bool has_bonded_bundles; | |
319 | bool lacp_enabled; | |
320 | struct mbridge *mbridge; | |
321 | ||
322 | struct ovs_mutex stats_mutex; | |
323 | struct netdev_stats stats OVS_GUARDED; /* To account packets generated and | |
324 | * consumed in userspace. */ | |
325 | ||
326 | /* Spanning tree. */ | |
327 | struct stp *stp; | |
328 | long long int stp_last_tick; | |
329 | ||
330 | /* Rapid Spanning Tree. */ | |
331 | struct rstp *rstp; | |
332 | long long int rstp_last_tick; | |
333 | ||
334 | /* Ports. */ | |
335 | struct sset ports; /* Set of standard port names. */ | |
336 | struct sset ghost_ports; /* Ports with no datapath port. */ | |
337 | struct sset port_poll_set; /* Queued names for port_poll() reply. */ | |
338 | int port_poll_errno; /* Last errno for port_poll() reply. */ | |
339 | uint64_t change_seq; /* Connectivity status changes. */ | |
340 | ||
341 | /* Work queues. */ | |
342 | struct guarded_list ams; /* Contains "struct ofproto_async_msgs"s. */ | |
343 | struct seq *ams_seq; /* For notifying 'ams' reception. */ | |
344 | uint64_t ams_seqno; | |
345 | }; | |
346 | ||
347 | struct ofproto_dpif *ofproto_dpif_lookup_by_name(const char *name); | |
348 | struct ofproto_dpif *ofproto_dpif_lookup_by_uuid(const struct uuid *uuid); | |
349 | ||
350 | ovs_version_t ofproto_dpif_get_tables_version(struct ofproto_dpif *); | |
351 | ||
352 | void ofproto_dpif_credit_table_stats(struct ofproto_dpif *, uint8_t table_id, | |
353 | uint64_t n_matches, uint64_t n_misses); | |
354 | ||
355 | int ofproto_dpif_execute_actions(struct ofproto_dpif *, ovs_version_t, | |
356 | const struct flow *, struct rule_dpif *, | |
357 | const struct ofpact *, size_t ofpacts_len, | |
358 | struct dp_packet *); | |
359 | int ofproto_dpif_execute_actions__(struct ofproto_dpif *, ovs_version_t, | |
360 | const struct flow *, struct rule_dpif *, | |
361 | const struct ofpact *, size_t ofpacts_len, | |
362 | int depth, int resubmits, | |
363 | struct dp_packet *); | |
364 | void ofproto_dpif_send_async_msg(struct ofproto_dpif *, | |
365 | struct ofproto_async_msg *); | |
366 | int ofproto_dpif_send_packet(const struct ofport_dpif *, bool oam, | |
367 | struct dp_packet *); | |
368 | enum ofperr ofproto_dpif_flow_mod_init_for_learn( | |
369 | struct ofproto_dpif *, const struct ofputil_flow_mod *, | |
370 | struct ofproto_flow_mod *); | |
371 | ||
372 | struct ofport_dpif *ofp_port_to_ofport(const struct ofproto_dpif *, | |
373 | ofp_port_t); | |
374 | ||
375 | int ofproto_dpif_add_internal_flow(struct ofproto_dpif *, | |
376 | struct match *, int priority, | |
377 | uint16_t idle_timeout, | |
378 | const struct ofpbuf *ofpacts, | |
379 | struct rule **rulep); | |
380 | int ofproto_dpif_delete_internal_flow(struct ofproto_dpif *, struct match *, | |
381 | int priority); | |
382 | ||
383 | bool ovs_native_tunneling_is_on(struct ofproto_dpif *); | |
384 | ||
385 | bool ofproto_dpif_ct_zone_timeout_policy_get_name( | |
386 | const struct dpif_backer *backer, uint16_t zone, uint16_t dl_type, | |
387 | uint8_t nw_proto, char **tp_name, bool *unwildcard); | |
388 | ||
389 | bool ovs_explicit_drop_action_supported(struct ofproto_dpif *); | |
390 | ||
391 | #endif /* ofproto-dpif.h */ |