]>
Commit | Line | Data |
---|---|---|
064af421 BP |
1 | /* |
2 | * Copyright (c) 2008, 2009 Nicira Networks. | |
3 | * | |
a14bc59f BP |
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: | |
064af421 | 7 | * |
a14bc59f BP |
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. | |
064af421 BP |
15 | */ |
16 | ||
17 | #include <config.h> | |
96fba48f | 18 | #include "dpif-provider.h" |
064af421 BP |
19 | |
20 | #include <assert.h> | |
21 | #include <ctype.h> | |
22 | #include <errno.h> | |
064af421 | 23 | #include <inttypes.h> |
064af421 BP |
24 | #include <stdlib.h> |
25 | #include <string.h> | |
064af421 BP |
26 | |
27 | #include "coverage.h" | |
28 | #include "dynamic-string.h" | |
29 | #include "flow.h" | |
30 | #include "netlink.h" | |
31 | #include "odp-util.h" | |
32 | #include "ofp-print.h" | |
33 | #include "ofpbuf.h" | |
34 | #include "packets.h" | |
35 | #include "poll-loop.h" | |
36 | #include "util.h" | |
37 | #include "valgrind.h" | |
38 | ||
39 | #include "vlog.h" | |
40 | #define THIS_MODULE VLM_dpif | |
41 | ||
72865317 | 42 | static const struct dpif_class *dpif_classes[] = { |
96fba48f | 43 | &dpif_linux_class, |
72865317 | 44 | &dpif_netdev_class, |
c228a364 | 45 | }; |
96fba48f | 46 | enum { N_DPIF_CLASSES = ARRAY_SIZE(dpif_classes) }; |
c228a364 | 47 | |
064af421 BP |
48 | /* Rate limit for individual messages going to or from the datapath, output at |
49 | * DBG level. This is very high because, if these are enabled, it is because | |
50 | * we really need to see them. */ | |
51 | static struct vlog_rate_limit dpmsg_rl = VLOG_RATE_LIMIT_INIT(600, 600); | |
52 | ||
53 | /* Not really much point in logging many dpif errors. */ | |
54 | static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(9999, 5); | |
55 | ||
96fba48f BP |
56 | static void log_operation(const struct dpif *, const char *operation, |
57 | int error); | |
58 | static void log_flow_operation(const struct dpif *, const char *operation, | |
59 | int error, struct odp_flow *flow); | |
60 | static void log_flow_put(struct dpif *, int error, | |
61 | const struct odp_flow_put *); | |
62 | static bool should_log_flow_message(int error); | |
064af421 BP |
63 | static void check_rw_odp_flow(struct odp_flow *); |
64 | ||
5792c5c6 BP |
65 | /* Performs periodic work needed by all the various kinds of dpifs. |
66 | * | |
67 | * If your program opens any dpifs, it must call this function within its main | |
68 | * poll loop. */ | |
69 | void | |
70 | dp_run(void) | |
71 | { | |
72 | int i; | |
73 | for (i = 0; i < N_DPIF_CLASSES; i++) { | |
74 | const struct dpif_class *class = dpif_classes[i]; | |
75 | if (class->run) { | |
76 | class->run(); | |
77 | } | |
78 | } | |
79 | } | |
80 | ||
81 | /* Arranges for poll_block() to wake up when dp_run() needs to be called. | |
82 | * | |
83 | * If your program opens any dpifs, it must call this function within its main | |
84 | * poll loop. */ | |
85 | void | |
86 | dp_wait(void) | |
87 | { | |
88 | int i; | |
89 | for (i = 0; i < N_DPIF_CLASSES; i++) { | |
90 | const struct dpif_class *class = dpif_classes[i]; | |
91 | if (class->wait) { | |
92 | class->wait(); | |
93 | } | |
94 | } | |
95 | } | |
96 | ||
96fba48f BP |
97 | static int |
98 | do_open(const char *name_, bool create, struct dpif **dpifp) | |
064af421 | 99 | { |
96fba48f BP |
100 | char *name = xstrdup(name_); |
101 | char *prefix, *suffix, *colon; | |
102 | struct dpif *dpif = NULL; | |
064af421 | 103 | int error; |
96fba48f | 104 | int i; |
064af421 | 105 | |
96fba48f BP |
106 | colon = strchr(name, ':'); |
107 | if (colon) { | |
108 | *colon = '\0'; | |
109 | prefix = name; | |
110 | suffix = colon + 1; | |
111 | } else { | |
112 | prefix = ""; | |
113 | suffix = name; | |
064af421 BP |
114 | } |
115 | ||
96fba48f BP |
116 | for (i = 0; i < N_DPIF_CLASSES; i++) { |
117 | const struct dpif_class *class = dpif_classes[i]; | |
118 | if (!strcmp(prefix, class->prefix)) { | |
119 | error = class->open(name_, suffix, create, &dpif); | |
120 | goto exit; | |
064af421 | 121 | } |
064af421 | 122 | } |
96fba48f | 123 | error = EAFNOSUPPORT; |
064af421 | 124 | |
96fba48f BP |
125 | exit: |
126 | *dpifp = error ? NULL : dpif; | |
127 | return error; | |
064af421 BP |
128 | } |
129 | ||
96fba48f BP |
130 | /* Tries to open an existing datapath named 'name'. Will fail if no datapath |
131 | * named 'name' exists. Returns 0 if successful, otherwise a positive errno | |
132 | * value. On success stores a pointer to the datapath in '*dpifp', otherwise a | |
133 | * null pointer. */ | |
134 | int | |
135 | dpif_open(const char *name, struct dpif **dpifp) | |
064af421 | 136 | { |
96fba48f | 137 | return do_open(name, false, dpifp); |
064af421 BP |
138 | } |
139 | ||
96fba48f BP |
140 | /* Tries to create and open a new datapath with the given 'name'. Will fail if |
141 | * a datapath named 'name' already exists. Returns 0 if successful, otherwise | |
142 | * a positive errno value. On success stores a pointer to the datapath in | |
143 | * '*dpifp', otherwise a null pointer.*/ | |
064af421 | 144 | int |
c228a364 | 145 | dpif_create(const char *name, struct dpif **dpifp) |
064af421 | 146 | { |
96fba48f BP |
147 | return do_open(name, true, dpifp); |
148 | } | |
064af421 | 149 | |
96fba48f BP |
150 | /* Closes and frees the connection to 'dpif'. Does not destroy the datapath |
151 | * itself; call dpif_delete() first, instead, if that is desirable. */ | |
152 | void | |
153 | dpif_close(struct dpif *dpif) | |
154 | { | |
155 | if (dpif) { | |
156 | char *name = dpif->name; | |
157 | dpif->class->close(dpif); | |
158 | free(name); | |
064af421 BP |
159 | } |
160 | } | |
161 | ||
96fba48f | 162 | /* Returns the name of datapath 'dpif' (for use in log messages). */ |
b29ba128 BP |
163 | const char * |
164 | dpif_name(const struct dpif *dpif) | |
165 | { | |
166 | return dpif->name; | |
167 | } | |
168 | ||
96fba48f BP |
169 | /* Destroys the datapath that 'dpif' is connected to, first removing all of its |
170 | * ports. After calling this function, it does not make sense to pass 'dpif' | |
171 | * to any functions other than dpif_name() or dpif_close(). */ | |
064af421 BP |
172 | int |
173 | dpif_delete(struct dpif *dpif) | |
174 | { | |
96fba48f BP |
175 | int error; |
176 | ||
064af421 | 177 | COVERAGE_INC(dpif_destroy); |
96fba48f BP |
178 | |
179 | error = dpif->class->delete(dpif); | |
180 | log_operation(dpif, "delete", error); | |
181 | return error; | |
064af421 BP |
182 | } |
183 | ||
96fba48f BP |
184 | /* Retrieves statistics for 'dpif' into 'stats'. Returns 0 if successful, |
185 | * otherwise a positive errno value. */ | |
064af421 BP |
186 | int |
187 | dpif_get_dp_stats(const struct dpif *dpif, struct odp_stats *stats) | |
188 | { | |
96fba48f BP |
189 | int error = dpif->class->get_stats(dpif, stats); |
190 | if (error) { | |
191 | memset(stats, 0, sizeof *stats); | |
192 | } | |
193 | log_operation(dpif, "get_stats", error); | |
194 | return error; | |
064af421 BP |
195 | } |
196 | ||
96fba48f BP |
197 | /* Retrieves the current IP fragment handling policy for 'dpif' into |
198 | * '*drop_frags': true indicates that fragments are dropped, false indicates | |
199 | * that fragments are treated in the same way as other IP packets (except that | |
200 | * the L4 header cannot be read). Returns 0 if successful, otherwise a | |
201 | * positive errno value. */ | |
064af421 BP |
202 | int |
203 | dpif_get_drop_frags(const struct dpif *dpif, bool *drop_frags) | |
204 | { | |
96fba48f BP |
205 | int error = dpif->class->get_drop_frags(dpif, drop_frags); |
206 | if (error) { | |
207 | *drop_frags = false; | |
208 | } | |
209 | log_operation(dpif, "get_drop_frags", error); | |
064af421 BP |
210 | return error; |
211 | } | |
212 | ||
96fba48f BP |
213 | /* Changes 'dpif''s treatment of IP fragments to 'drop_frags', whose meaning is |
214 | * the same as for the get_drop_frags member function. Returns 0 if | |
215 | * successful, otherwise a positive errno value. */ | |
064af421 BP |
216 | int |
217 | dpif_set_drop_frags(struct dpif *dpif, bool drop_frags) | |
218 | { | |
96fba48f BP |
219 | int error = dpif->class->set_drop_frags(dpif, drop_frags); |
220 | log_operation(dpif, "set_drop_frags", error); | |
221 | return error; | |
064af421 BP |
222 | } |
223 | ||
96fba48f BP |
224 | /* Attempts to add 'devname' as a port on 'dpif', given the combination of |
225 | * ODP_PORT_* flags in 'flags'. If successful, returns 0 and sets '*port_nop' | |
226 | * to the new port's port number (if 'port_nop' is non-null). On failure, | |
227 | * returns a positive errno value and sets '*port_nop' to UINT16_MAX (if | |
228 | * 'port_nop' is non-null). */ | |
064af421 | 229 | int |
9ee3ae3e BP |
230 | dpif_port_add(struct dpif *dpif, const char *devname, uint16_t flags, |
231 | uint16_t *port_nop) | |
064af421 | 232 | { |
9ee3ae3e BP |
233 | uint16_t port_no; |
234 | int error; | |
064af421 BP |
235 | |
236 | COVERAGE_INC(dpif_port_add); | |
9ee3ae3e | 237 | |
96fba48f | 238 | error = dpif->class->port_add(dpif, devname, flags, &port_no); |
9ee3ae3e | 239 | if (!error) { |
b29ba128 BP |
240 | VLOG_DBG_RL(&dpmsg_rl, "%s: added %s as port %"PRIu16, |
241 | dpif_name(dpif), devname, port_no); | |
064af421 | 242 | } else { |
9ee3ae3e | 243 | VLOG_WARN_RL(&error_rl, "%s: failed to add %s as port: %s", |
96fba48f BP |
244 | dpif_name(dpif), devname, strerror(error)); |
245 | port_no = UINT16_MAX; | |
9ee3ae3e BP |
246 | } |
247 | if (port_nop) { | |
248 | *port_nop = port_no; | |
064af421 | 249 | } |
9ee3ae3e | 250 | return error; |
064af421 BP |
251 | } |
252 | ||
96fba48f BP |
253 | /* Attempts to remove 'dpif''s port number 'port_no'. Returns 0 if successful, |
254 | * otherwise a positive errno value. */ | |
064af421 BP |
255 | int |
256 | dpif_port_del(struct dpif *dpif, uint16_t port_no) | |
257 | { | |
96fba48f BP |
258 | int error; |
259 | ||
064af421 | 260 | COVERAGE_INC(dpif_port_del); |
96fba48f BP |
261 | |
262 | error = dpif->class->port_del(dpif, port_no); | |
263 | log_operation(dpif, "port_del", error); | |
264 | return error; | |
064af421 BP |
265 | } |
266 | ||
96fba48f BP |
267 | /* Looks up port number 'port_no' in 'dpif'. On success, returns 0 and |
268 | * initializes '*port' appropriately; on failure, returns a positive errno | |
269 | * value. */ | |
064af421 BP |
270 | int |
271 | dpif_port_query_by_number(const struct dpif *dpif, uint16_t port_no, | |
272 | struct odp_port *port) | |
273 | { | |
96fba48f BP |
274 | int error = dpif->class->port_query_by_number(dpif, port_no, port); |
275 | if (!error) { | |
b29ba128 BP |
276 | VLOG_DBG_RL(&dpmsg_rl, "%s: port %"PRIu16" is device %s", |
277 | dpif_name(dpif), port_no, port->devname); | |
064af421 | 278 | } else { |
96fba48f | 279 | memset(port, 0, sizeof *port); |
b29ba128 | 280 | VLOG_WARN_RL(&error_rl, "%s: failed to query port %"PRIu16": %s", |
96fba48f | 281 | dpif_name(dpif), port_no, strerror(error)); |
064af421 | 282 | } |
96fba48f | 283 | return error; |
064af421 BP |
284 | } |
285 | ||
96fba48f BP |
286 | /* Looks up port named 'devname' in 'dpif'. On success, returns 0 and |
287 | * initializes '*port' appropriately; on failure, returns a positive errno | |
288 | * value. */ | |
064af421 BP |
289 | int |
290 | dpif_port_query_by_name(const struct dpif *dpif, const char *devname, | |
291 | struct odp_port *port) | |
292 | { | |
96fba48f BP |
293 | int error = dpif->class->port_query_by_name(dpif, devname, port); |
294 | if (!error) { | |
b29ba128 BP |
295 | VLOG_DBG_RL(&dpmsg_rl, "%s: device %s is on port %"PRIu16, |
296 | dpif_name(dpif), devname, port->port); | |
064af421 | 297 | } else { |
96fba48f BP |
298 | memset(port, 0, sizeof *port); |
299 | ||
5c6d2a3f BP |
300 | /* Log level is DBG here because all the current callers are interested |
301 | * in whether 'dpif' actually has a port 'devname', so that it's not an | |
302 | * issue worth logging if it doesn't. */ | |
303 | VLOG_DBG_RL(&error_rl, "%s: failed to query port %s: %s", | |
96fba48f | 304 | dpif_name(dpif), devname, strerror(error)); |
064af421 | 305 | } |
96fba48f | 306 | return error; |
064af421 BP |
307 | } |
308 | ||
96fba48f BP |
309 | /* Looks up port number 'port_no' in 'dpif'. On success, returns 0 and copies |
310 | * the port's name into the 'name_size' bytes in 'name', ensuring that the | |
311 | * result is null-terminated. On failure, returns a positive errno value and | |
312 | * makes 'name' the empty string. */ | |
335562c0 BP |
313 | int |
314 | dpif_port_get_name(struct dpif *dpif, uint16_t port_no, | |
315 | char *name, size_t name_size) | |
316 | { | |
317 | struct odp_port port; | |
318 | int error; | |
319 | ||
320 | assert(name_size > 0); | |
321 | ||
322 | error = dpif_port_query_by_number(dpif, port_no, &port); | |
323 | if (!error) { | |
324 | ovs_strlcpy(name, port.devname, name_size); | |
325 | } else { | |
326 | *name = '\0'; | |
327 | } | |
328 | return error; | |
329 | } | |
330 | ||
96fba48f BP |
331 | /* Obtains a list of all the ports in 'dpif'. |
332 | * | |
333 | * If successful, returns 0 and sets '*portsp' to point to an array of | |
334 | * appropriately initialized port structures and '*n_portsp' to the number of | |
335 | * ports in the array. The caller is responsible for freeing '*portp' by | |
336 | * calling free(). | |
337 | * | |
338 | * On failure, returns a positive errno value and sets '*portsp' to NULL and | |
339 | * '*n_portsp' to 0. */ | |
064af421 BP |
340 | int |
341 | dpif_port_list(const struct dpif *dpif, | |
f4ba4c4f | 342 | struct odp_port **portsp, size_t *n_portsp) |
064af421 | 343 | { |
f4ba4c4f BP |
344 | struct odp_port *ports; |
345 | size_t n_ports; | |
064af421 BP |
346 | int error; |
347 | ||
f4ba4c4f BP |
348 | for (;;) { |
349 | struct odp_stats stats; | |
96fba48f | 350 | int retval; |
f4ba4c4f | 351 | |
064af421 BP |
352 | error = dpif_get_dp_stats(dpif, &stats); |
353 | if (error) { | |
f4ba4c4f | 354 | goto exit; |
064af421 BP |
355 | } |
356 | ||
f4ba4c4f | 357 | ports = xcalloc(stats.n_ports, sizeof *ports); |
96fba48f BP |
358 | retval = dpif->class->port_list(dpif, ports, stats.n_ports); |
359 | if (retval < 0) { | |
f4ba4c4f | 360 | /* Hard error. */ |
96fba48f | 361 | error = -retval; |
f4ba4c4f BP |
362 | free(ports); |
363 | goto exit; | |
96fba48f | 364 | } else if (retval <= stats.n_ports) { |
f4ba4c4f BP |
365 | /* Success. */ |
366 | error = 0; | |
96fba48f | 367 | n_ports = retval; |
f4ba4c4f BP |
368 | goto exit; |
369 | } else { | |
370 | /* Soft error: port count increased behind our back. Try again. */ | |
371 | free(ports); | |
064af421 | 372 | } |
f4ba4c4f | 373 | } |
064af421 | 374 | |
f4ba4c4f BP |
375 | exit: |
376 | if (error) { | |
377 | *portsp = NULL; | |
378 | *n_portsp = 0; | |
379 | } else { | |
380 | *portsp = ports; | |
381 | *n_portsp = n_ports; | |
382 | } | |
96fba48f | 383 | log_operation(dpif, "port_list", error); |
064af421 BP |
384 | return error; |
385 | } | |
386 | ||
e9e28be3 BP |
387 | /* Polls for changes in the set of ports in 'dpif'. If the set of ports in |
388 | * 'dpif' has changed, this function does one of the following: | |
389 | * | |
390 | * - Stores the name of the device that was added to or deleted from 'dpif' in | |
391 | * '*devnamep' and returns 0. The caller is responsible for freeing | |
392 | * '*devnamep' (with free()) when it no longer needs it. | |
393 | * | |
394 | * - Returns ENOBUFS and sets '*devnamep' to NULL. | |
395 | * | |
396 | * This function may also return 'false positives', where it returns 0 and | |
397 | * '*devnamep' names a device that was not actually added or deleted or it | |
398 | * returns ENOBUFS without any change. | |
399 | * | |
400 | * Returns EAGAIN if the set of ports in 'dpif' has not changed. May also | |
401 | * return other positive errno values to indicate that something has gone | |
402 | * wrong. */ | |
403 | int | |
404 | dpif_port_poll(const struct dpif *dpif, char **devnamep) | |
405 | { | |
406 | int error = dpif->class->port_poll(dpif, devnamep); | |
407 | if (error) { | |
408 | *devnamep = NULL; | |
409 | } | |
410 | return error; | |
411 | } | |
412 | ||
413 | /* Arranges for the poll loop to wake up when port_poll(dpif) will return a | |
414 | * value other than EAGAIN. */ | |
415 | void | |
416 | dpif_port_poll_wait(const struct dpif *dpif) | |
417 | { | |
418 | dpif->class->port_poll_wait(dpif); | |
419 | } | |
420 | ||
96fba48f BP |
421 | /* Retrieves a list of the port numbers in port group 'group' in 'dpif'. |
422 | * | |
423 | * On success, returns 0 and points '*ports' to a newly allocated array of | |
424 | * integers, each of which is a 'dpif' port number for a port in | |
425 | * 'group'. Stores the number of elements in the array in '*n_ports'. The | |
426 | * caller is responsible for freeing '*ports' by calling free(). | |
427 | * | |
428 | * On failure, returns a positive errno value and sets '*ports' to NULL and | |
429 | * '*n_ports' to 0. */ | |
064af421 BP |
430 | int |
431 | dpif_port_group_get(const struct dpif *dpif, uint16_t group, | |
bb8a9a2b | 432 | uint16_t **ports, size_t *n_ports) |
064af421 | 433 | { |
064af421 BP |
434 | int error; |
435 | ||
bb8a9a2b BP |
436 | *ports = NULL; |
437 | *n_ports = 0; | |
438 | for (;;) { | |
96fba48f BP |
439 | int retval = dpif->class->port_group_get(dpif, group, |
440 | *ports, *n_ports); | |
441 | if (retval < 0) { | |
bb8a9a2b | 442 | /* Hard error. */ |
96fba48f | 443 | error = -retval; |
bb8a9a2b BP |
444 | free(*ports); |
445 | *ports = NULL; | |
446 | *n_ports = 0; | |
447 | break; | |
96fba48f | 448 | } else if (retval <= *n_ports) { |
bb8a9a2b | 449 | /* Success. */ |
96fba48f BP |
450 | error = 0; |
451 | *n_ports = retval; | |
bb8a9a2b BP |
452 | break; |
453 | } else { | |
454 | /* Soft error: there were more ports than we expected in the | |
455 | * group. Try again. */ | |
456 | free(*ports); | |
96fba48f BP |
457 | *ports = xcalloc(retval, sizeof **ports); |
458 | *n_ports = retval; | |
bb8a9a2b BP |
459 | } |
460 | } | |
96fba48f | 461 | log_operation(dpif, "port_group_get", error); |
064af421 BP |
462 | return error; |
463 | } | |
464 | ||
96fba48f BP |
465 | /* Updates port group 'group' in 'dpif', making it contain the 'n_ports' ports |
466 | * whose 'dpif' port numbers are given in 'n_ports'. Returns 0 if | |
467 | * successful, otherwise a positive errno value. | |
468 | * | |
469 | * Behavior is undefined if the values in ports[] are not unique. */ | |
064af421 | 470 | int |
96fba48f BP |
471 | dpif_port_group_set(struct dpif *dpif, uint16_t group, |
472 | const uint16_t ports[], size_t n_ports) | |
064af421 | 473 | { |
96fba48f | 474 | int error; |
064af421 | 475 | |
96fba48f BP |
476 | COVERAGE_INC(dpif_port_group_set); |
477 | ||
478 | error = dpif->class->port_group_set(dpif, group, ports, n_ports); | |
479 | log_operation(dpif, "port_group_set", error); | |
480 | return error; | |
064af421 BP |
481 | } |
482 | ||
96fba48f BP |
483 | /* Deletes all flows from 'dpif'. Returns 0 if successful, otherwise a |
484 | * positive errno value. */ | |
485 | int | |
486 | dpif_flow_flush(struct dpif *dpif) | |
064af421 | 487 | { |
96fba48f BP |
488 | int error; |
489 | ||
490 | COVERAGE_INC(dpif_flow_flush); | |
491 | ||
492 | error = dpif->class->flow_flush(dpif); | |
493 | log_operation(dpif, "flow_flush", error); | |
494 | return error; | |
064af421 BP |
495 | } |
496 | ||
96fba48f BP |
497 | /* Queries 'dpif' for a flow entry matching 'flow->key'. |
498 | * | |
499 | * If a flow matching 'flow->key' exists in 'dpif', stores statistics for the | |
500 | * flow into 'flow->stats'. If 'flow->n_actions' is zero, then 'flow->actions' | |
501 | * is ignored. If 'flow->n_actions' is nonzero, then 'flow->actions' should | |
502 | * point to an array of the specified number of actions. At most that many of | |
503 | * the flow's actions will be copied into that array. 'flow->n_actions' will | |
504 | * be updated to the number of actions actually present in the flow, which may | |
505 | * be greater than the number stored if the flow has more actions than space | |
506 | * available in the array. | |
507 | * | |
508 | * If no flow matching 'flow->key' exists in 'dpif', returns ENOENT. On other | |
509 | * failure, returns a positive errno value. */ | |
510 | int | |
511 | dpif_flow_get(const struct dpif *dpif, struct odp_flow *flow) | |
064af421 | 512 | { |
96fba48f BP |
513 | int error; |
514 | ||
515 | COVERAGE_INC(dpif_flow_get); | |
516 | ||
517 | check_rw_odp_flow(flow); | |
518 | error = dpif->class->flow_get(dpif, flow, 1); | |
519 | if (!error) { | |
520 | error = flow->stats.error; | |
064af421 | 521 | } |
96fba48f BP |
522 | if (should_log_flow_message(error)) { |
523 | log_flow_operation(dpif, "flow_get", error, flow); | |
064af421 | 524 | } |
96fba48f | 525 | return error; |
064af421 BP |
526 | } |
527 | ||
96fba48f BP |
528 | /* For each flow 'flow' in the 'n' flows in 'flows': |
529 | * | |
530 | * - If a flow matching 'flow->key' exists in 'dpif': | |
531 | * | |
532 | * Stores 0 into 'flow->stats.error' and stores statistics for the flow | |
533 | * into 'flow->stats'. | |
534 | * | |
535 | * If 'flow->n_actions' is zero, then 'flow->actions' is ignored. If | |
536 | * 'flow->n_actions' is nonzero, then 'flow->actions' should point to an | |
537 | * array of the specified number of actions. At most that many of the | |
538 | * flow's actions will be copied into that array. 'flow->n_actions' will | |
539 | * be updated to the number of actions actually present in the flow, which | |
540 | * may be greater than the number stored if the flow has more actions than | |
541 | * space available in the array. | |
542 | * | |
543 | * - Flow-specific errors are indicated by a positive errno value in | |
544 | * 'flow->stats.error'. In particular, ENOENT indicates that no flow | |
545 | * matching 'flow->key' exists in 'dpif'. When an error value is stored, the | |
546 | * contents of 'flow->key' are preserved but other members of 'flow' should | |
547 | * be treated as indeterminate. | |
548 | * | |
549 | * Returns 0 if all 'n' flows in 'flows' were updated (whether they were | |
550 | * individually successful or not is indicated by 'flow->stats.error', | |
551 | * however). Returns a positive errno value if an error that prevented this | |
552 | * update occurred, in which the caller must not depend on any elements in | |
553 | * 'flows' being updated or not updated. | |
554 | */ | |
555 | int | |
556 | dpif_flow_get_multiple(const struct dpif *dpif, | |
557 | struct odp_flow flows[], size_t n) | |
064af421 | 558 | { |
96fba48f BP |
559 | int error; |
560 | size_t i; | |
561 | ||
562 | COVERAGE_ADD(dpif_flow_get, n); | |
563 | ||
564 | for (i = 0; i < n; i++) { | |
565 | check_rw_odp_flow(&flows[i]); | |
064af421 | 566 | } |
96fba48f BP |
567 | |
568 | error = dpif->class->flow_get(dpif, flows, n); | |
569 | log_operation(dpif, "flow_get_multiple", error); | |
064af421 BP |
570 | return error; |
571 | } | |
572 | ||
96fba48f BP |
573 | /* Adds or modifies a flow in 'dpif' as specified in 'put': |
574 | * | |
575 | * - If the flow specified in 'put->flow' does not exist in 'dpif', then | |
576 | * behavior depends on whether ODPPF_CREATE is specified in 'put->flags': if | |
577 | * it is, the flow will be added, otherwise the operation will fail with | |
578 | * ENOENT. | |
579 | * | |
580 | * - Otherwise, the flow specified in 'put->flow' does exist in 'dpif'. | |
581 | * Behavior in this case depends on whether ODPPF_MODIFY is specified in | |
582 | * 'put->flags': if it is, the flow's actions will be updated, otherwise the | |
583 | * operation will fail with EEXIST. If the flow's actions are updated, then | |
584 | * its statistics will be zeroed if ODPPF_ZERO_STATS is set in 'put->flags', | |
585 | * left as-is otherwise. | |
586 | * | |
587 | * Returns 0 if successful, otherwise a positive errno value. | |
588 | */ | |
064af421 BP |
589 | int |
590 | dpif_flow_put(struct dpif *dpif, struct odp_flow_put *put) | |
591 | { | |
96fba48f BP |
592 | int error; |
593 | ||
064af421 | 594 | COVERAGE_INC(dpif_flow_put); |
96fba48f BP |
595 | |
596 | error = dpif->class->flow_put(dpif, put); | |
064af421 | 597 | if (should_log_flow_message(error)) { |
96fba48f | 598 | log_flow_put(dpif, error, put); |
064af421 BP |
599 | } |
600 | return error; | |
601 | } | |
602 | ||
96fba48f BP |
603 | /* Deletes a flow matching 'flow->key' from 'dpif' or returns ENOENT if 'dpif' |
604 | * does not contain such a flow. | |
605 | * | |
606 | * If successful, updates 'flow->stats', 'flow->n_actions', and 'flow->actions' | |
607 | * as described for dpif_flow_get(). */ | |
064af421 BP |
608 | int |
609 | dpif_flow_del(struct dpif *dpif, struct odp_flow *flow) | |
610 | { | |
f1aa2072 BP |
611 | int error; |
612 | ||
96fba48f | 613 | COVERAGE_INC(dpif_flow_del); |
f1aa2072 | 614 | |
064af421 | 615 | check_rw_odp_flow(flow); |
96fba48f | 616 | memset(&flow->stats, 0, sizeof flow->stats); |
064af421 | 617 | |
96fba48f BP |
618 | error = dpif->class->flow_del(dpif, flow); |
619 | if (should_log_flow_message(error)) { | |
620 | log_flow_operation(dpif, "delete flow", error, flow); | |
064af421 | 621 | } |
96fba48f | 622 | return error; |
064af421 BP |
623 | } |
624 | ||
96fba48f BP |
625 | /* Stores up to 'n' flows in 'dpif' into 'flows', including their statistics |
626 | * but not including any information about their actions. If successful, | |
627 | * returns 0 and sets '*n_out' to the number of flows actually present in | |
628 | * 'dpif', which might be greater than the number stored (if 'dpif' has more | |
629 | * than 'n' flows). On failure, returns a negative errno value and sets | |
630 | * '*n_out' to 0. */ | |
064af421 BP |
631 | int |
632 | dpif_flow_list(const struct dpif *dpif, struct odp_flow flows[], size_t n, | |
633 | size_t *n_out) | |
634 | { | |
064af421 | 635 | uint32_t i; |
96fba48f | 636 | int retval; |
064af421 BP |
637 | |
638 | COVERAGE_INC(dpif_flow_query_list); | |
064af421 BP |
639 | if (RUNNING_ON_VALGRIND) { |
640 | memset(flows, 0, n * sizeof *flows); | |
641 | } else { | |
642 | for (i = 0; i < n; i++) { | |
643 | flows[i].actions = NULL; | |
644 | flows[i].n_actions = 0; | |
645 | } | |
646 | } | |
96fba48f BP |
647 | retval = dpif->class->flow_list(dpif, flows, n); |
648 | if (retval < 0) { | |
064af421 | 649 | *n_out = 0; |
b29ba128 | 650 | VLOG_WARN_RL(&error_rl, "%s: flow list failed (%s)", |
96fba48f BP |
651 | dpif_name(dpif), strerror(-retval)); |
652 | return -retval; | |
064af421 | 653 | } else { |
96fba48f BP |
654 | COVERAGE_ADD(dpif_flow_query_list_n, retval); |
655 | *n_out = MIN(n, retval); | |
656 | VLOG_DBG_RL(&dpmsg_rl, "%s: listed %zu flows (of %d)", | |
657 | dpif_name(dpif), *n_out, retval); | |
658 | return 0; | |
064af421 | 659 | } |
064af421 BP |
660 | } |
661 | ||
96fba48f BP |
662 | /* Retrieves all of the flows in 'dpif'. |
663 | * | |
664 | * If successful, returns 0 and stores in '*flowsp' a pointer to a newly | |
665 | * allocated array of flows, including their statistics but not including any | |
666 | * information about their actions, and sets '*np' to the number of flows in | |
667 | * '*flowsp'. The caller is responsible for freeing '*flowsp' by calling | |
668 | * free(). | |
669 | * | |
670 | * On failure, returns a positive errno value and sets '*flowsp' to NULL and | |
671 | * '*np' to 0. */ | |
064af421 BP |
672 | int |
673 | dpif_flow_list_all(const struct dpif *dpif, | |
674 | struct odp_flow **flowsp, size_t *np) | |
675 | { | |
676 | struct odp_stats stats; | |
677 | struct odp_flow *flows; | |
678 | size_t n_flows; | |
679 | int error; | |
680 | ||
681 | *flowsp = NULL; | |
682 | *np = 0; | |
683 | ||
684 | error = dpif_get_dp_stats(dpif, &stats); | |
685 | if (error) { | |
686 | return error; | |
687 | } | |
688 | ||
689 | flows = xmalloc(sizeof *flows * stats.n_flows); | |
690 | error = dpif_flow_list(dpif, flows, stats.n_flows, &n_flows); | |
691 | if (error) { | |
692 | free(flows); | |
693 | return error; | |
694 | } | |
695 | ||
696 | if (stats.n_flows != n_flows) { | |
b29ba128 | 697 | VLOG_WARN_RL(&error_rl, "%s: datapath stats reported %"PRIu32" " |
064af421 | 698 | "flows but flow listing reported %zu", |
b29ba128 | 699 | dpif_name(dpif), stats.n_flows, n_flows); |
064af421 BP |
700 | } |
701 | *flowsp = flows; | |
702 | *np = n_flows; | |
703 | return 0; | |
704 | } | |
705 | ||
96fba48f BP |
706 | /* Causes 'dpif' to perform the 'n_actions' actions in 'actions' on the |
707 | * Ethernet frame specified in 'packet'. | |
708 | * | |
709 | * Pretends that the frame was originally received on the port numbered | |
710 | * 'in_port'. This affects only ODPAT_OUTPUT_GROUP actions, which will not | |
711 | * send a packet out their input port. Specify the number of an unused port | |
712 | * (e.g. UINT16_MAX is currently always unused) to avoid this behavior. | |
713 | * | |
714 | * Returns 0 if successful, otherwise a positive errno value. */ | |
064af421 BP |
715 | int |
716 | dpif_execute(struct dpif *dpif, uint16_t in_port, | |
717 | const union odp_action actions[], size_t n_actions, | |
718 | const struct ofpbuf *buf) | |
719 | { | |
720 | int error; | |
721 | ||
722 | COVERAGE_INC(dpif_execute); | |
723 | if (n_actions > 0) { | |
96fba48f | 724 | error = dpif->class->execute(dpif, in_port, actions, n_actions, buf); |
064af421 BP |
725 | } else { |
726 | error = 0; | |
727 | } | |
728 | ||
729 | if (!(error ? VLOG_DROP_WARN(&error_rl) : VLOG_DROP_DBG(&dpmsg_rl))) { | |
730 | struct ds ds = DS_EMPTY_INITIALIZER; | |
731 | char *packet = ofp_packet_to_string(buf->data, buf->size, buf->size); | |
b29ba128 | 732 | ds_put_format(&ds, "%s: execute ", dpif_name(dpif)); |
064af421 BP |
733 | format_odp_actions(&ds, actions, n_actions); |
734 | if (error) { | |
735 | ds_put_format(&ds, " failed (%s)", strerror(error)); | |
736 | } | |
737 | ds_put_format(&ds, " on packet %s", packet); | |
738 | vlog(THIS_MODULE, error ? VLL_WARN : VLL_DBG, "%s", ds_cstr(&ds)); | |
739 | ds_destroy(&ds); | |
740 | free(packet); | |
741 | } | |
742 | return error; | |
743 | } | |
744 | ||
96fba48f BP |
745 | /* Retrieves 'dpif''s "listen mask" into '*listen_mask'. Each ODPL_* bit set |
746 | * in '*listen_mask' indicates that dpif_recv() will receive messages of that | |
747 | * type. Returns 0 if successful, otherwise a positive errno value. */ | |
8f24562a BP |
748 | int |
749 | dpif_recv_get_mask(const struct dpif *dpif, int *listen_mask) | |
750 | { | |
96fba48f | 751 | int error = dpif->class->recv_get_mask(dpif, listen_mask); |
8f24562a BP |
752 | if (error) { |
753 | *listen_mask = 0; | |
754 | } | |
96fba48f | 755 | log_operation(dpif, "recv_get_mask", error); |
8f24562a BP |
756 | return error; |
757 | } | |
758 | ||
96fba48f BP |
759 | /* Sets 'dpif''s "listen mask" to 'listen_mask'. Each ODPL_* bit set in |
760 | * '*listen_mask' requests that dpif_recv() receive messages of that type. | |
761 | * Returns 0 if successful, otherwise a positive errno value. */ | |
8f24562a BP |
762 | int |
763 | dpif_recv_set_mask(struct dpif *dpif, int listen_mask) | |
764 | { | |
96fba48f BP |
765 | int error = dpif->class->recv_set_mask(dpif, listen_mask); |
766 | log_operation(dpif, "recv_set_mask", error); | |
767 | return error; | |
8f24562a BP |
768 | } |
769 | ||
96fba48f BP |
770 | /* Attempts to receive a message from 'dpif'. If successful, stores the |
771 | * message into '*packetp'. The message, if one is received, will begin with | |
772 | * 'struct odp_msg' as a header. Only messages of the types selected with | |
773 | * dpif_set_listen_mask() will ordinarily be received (but if a message type is | |
774 | * enabled and then later disabled, some stragglers might pop up). | |
775 | * | |
776 | * Returns 0 if successful, otherwise a positive errno value. Returns EAGAIN | |
777 | * if no message is immediately available. */ | |
064af421 | 778 | int |
96fba48f | 779 | dpif_recv(struct dpif *dpif, struct ofpbuf **packetp) |
064af421 | 780 | { |
96fba48f BP |
781 | int error = dpif->class->recv(dpif, packetp); |
782 | if (!error) { | |
783 | if (VLOG_IS_DBG_ENABLED()) { | |
784 | struct ofpbuf *buf = *packetp; | |
785 | struct odp_msg *msg = buf->data; | |
786 | void *payload = msg + 1; | |
787 | size_t payload_len = buf->size - sizeof *msg; | |
788 | char *s = ofp_packet_to_string(payload, payload_len, payload_len); | |
789 | VLOG_DBG_RL(&dpmsg_rl, "%s: received %s message of length " | |
790 | "%zu on port %"PRIu16": %s", dpif_name(dpif), | |
791 | (msg->type == _ODPL_MISS_NR ? "miss" | |
792 | : msg->type == _ODPL_ACTION_NR ? "action" | |
793 | : "<unknown>"), | |
794 | payload_len, msg->port, s); | |
795 | free(s); | |
064af421 | 796 | } |
064af421 | 797 | } else { |
96fba48f | 798 | *packetp = NULL; |
064af421 | 799 | } |
064af421 BP |
800 | return error; |
801 | } | |
802 | ||
96fba48f BP |
803 | /* Discards all messages that would otherwise be received by dpif_recv() on |
804 | * 'dpif'. Returns 0 if successful, otherwise a positive errno value. */ | |
805 | int | |
806 | dpif_recv_purge(struct dpif *dpif) | |
807 | { | |
808 | struct odp_stats stats; | |
809 | unsigned int i; | |
810 | int error; | |
811 | ||
812 | COVERAGE_INC(dpif_purge); | |
813 | ||
814 | error = dpif_get_dp_stats(dpif, &stats); | |
815 | if (error) { | |
816 | return error; | |
817 | } | |
818 | ||
819 | for (i = 0; i < stats.max_miss_queue + stats.max_action_queue; i++) { | |
820 | struct ofpbuf *buf; | |
821 | error = dpif_recv(dpif, &buf); | |
822 | if (error) { | |
823 | return error == EAGAIN ? 0 : error; | |
824 | } | |
825 | ofpbuf_delete(buf); | |
826 | } | |
827 | return 0; | |
828 | } | |
829 | ||
830 | /* Arranges for the poll loop to wake up when 'dpif' has a message queued to be | |
831 | * received with dpif_recv(). */ | |
064af421 BP |
832 | void |
833 | dpif_recv_wait(struct dpif *dpif) | |
834 | { | |
96fba48f | 835 | dpif->class->recv_wait(dpif); |
064af421 | 836 | } |
53a4218d | 837 | |
96fba48f BP |
838 | /* Obtains the NetFlow engine type and engine ID for 'dpif' into '*engine_type' |
839 | * and '*engine_id', respectively. */ | |
53a4218d BP |
840 | void |
841 | dpif_get_netflow_ids(const struct dpif *dpif, | |
842 | uint8_t *engine_type, uint8_t *engine_id) | |
843 | { | |
96fba48f BP |
844 | *engine_type = dpif->netflow_engine_type; |
845 | *engine_id = dpif->netflow_engine_id; | |
846 | } | |
847 | \f | |
848 | void | |
849 | dpif_init(struct dpif *dpif, const struct dpif_class *class, const char *name, | |
850 | uint8_t netflow_engine_type, uint8_t netflow_engine_id) | |
851 | { | |
852 | dpif->class = class; | |
853 | dpif->name = xstrdup(name); | |
854 | dpif->netflow_engine_type = netflow_engine_type; | |
855 | dpif->netflow_engine_id = netflow_engine_id; | |
856 | } | |
857 | \f | |
858 | static void | |
859 | log_operation(const struct dpif *dpif, const char *operation, int error) | |
860 | { | |
861 | if (!error) { | |
862 | VLOG_DBG_RL(&dpmsg_rl, "%s: %s success", dpif_name(dpif), operation); | |
863 | } else { | |
864 | VLOG_WARN_RL(&error_rl, "%s: %s failed (%s)", | |
865 | dpif_name(dpif), operation, strerror(error)); | |
866 | } | |
867 | } | |
868 | ||
869 | static enum vlog_level | |
870 | flow_message_log_level(int error) | |
871 | { | |
872 | return error ? VLL_WARN : VLL_DBG; | |
873 | } | |
874 | ||
875 | static bool | |
876 | should_log_flow_message(int error) | |
877 | { | |
878 | return !vlog_should_drop(THIS_MODULE, flow_message_log_level(error), | |
879 | error ? &error_rl : &dpmsg_rl); | |
880 | } | |
881 | ||
882 | static void | |
883 | log_flow_message(const struct dpif *dpif, int error, const char *operation, | |
884 | const flow_t *flow, const struct odp_flow_stats *stats, | |
885 | const union odp_action *actions, size_t n_actions) | |
886 | { | |
887 | struct ds ds = DS_EMPTY_INITIALIZER; | |
888 | ds_put_format(&ds, "%s: ", dpif_name(dpif)); | |
889 | if (error) { | |
890 | ds_put_cstr(&ds, "failed to "); | |
891 | } | |
892 | ds_put_format(&ds, "%s ", operation); | |
893 | if (error) { | |
894 | ds_put_format(&ds, "(%s) ", strerror(error)); | |
895 | } | |
896 | flow_format(&ds, flow); | |
897 | if (stats) { | |
898 | ds_put_cstr(&ds, ", "); | |
899 | format_odp_flow_stats(&ds, stats); | |
900 | } | |
901 | if (actions || n_actions) { | |
902 | ds_put_cstr(&ds, ", actions:"); | |
903 | format_odp_actions(&ds, actions, n_actions); | |
904 | } | |
905 | vlog(THIS_MODULE, flow_message_log_level(error), "%s", ds_cstr(&ds)); | |
906 | ds_destroy(&ds); | |
907 | } | |
908 | ||
909 | static void | |
910 | log_flow_operation(const struct dpif *dpif, const char *operation, int error, | |
911 | struct odp_flow *flow) | |
912 | { | |
913 | if (error) { | |
914 | flow->n_actions = 0; | |
915 | } | |
916 | log_flow_message(dpif, error, operation, &flow->key, | |
917 | !error ? &flow->stats : NULL, | |
918 | flow->actions, flow->n_actions); | |
919 | } | |
920 | ||
921 | static void | |
922 | log_flow_put(struct dpif *dpif, int error, const struct odp_flow_put *put) | |
923 | { | |
924 | enum { ODPPF_ALL = ODPPF_CREATE | ODPPF_MODIFY | ODPPF_ZERO_STATS }; | |
925 | struct ds s; | |
926 | ||
927 | ds_init(&s); | |
928 | ds_put_cstr(&s, "put"); | |
929 | if (put->flags & ODPPF_CREATE) { | |
930 | ds_put_cstr(&s, "[create]"); | |
931 | } | |
932 | if (put->flags & ODPPF_MODIFY) { | |
933 | ds_put_cstr(&s, "[modify]"); | |
934 | } | |
935 | if (put->flags & ODPPF_ZERO_STATS) { | |
936 | ds_put_cstr(&s, "[zero]"); | |
937 | } | |
938 | if (put->flags & ~ODPPF_ALL) { | |
939 | ds_put_format(&s, "[%x]", put->flags & ~ODPPF_ALL); | |
940 | } | |
941 | log_flow_message(dpif, error, ds_cstr(&s), &put->flow.key, | |
942 | !error ? &put->flow.stats : NULL, | |
943 | put->flow.actions, put->flow.n_actions); | |
944 | ds_destroy(&s); | |
945 | } | |
946 | ||
947 | /* There is a tendency to construct odp_flow objects on the stack and to | |
948 | * forget to properly initialize their "actions" and "n_actions" members. | |
949 | * When this happens, we get memory corruption because the kernel | |
950 | * writes through the random pointer that is in the "actions" member. | |
951 | * | |
952 | * This function attempts to combat the problem by: | |
953 | * | |
954 | * - Forcing a segfault if "actions" points to an invalid region (instead | |
955 | * of just getting back EFAULT, which can be easily missed in the log). | |
956 | * | |
957 | * - Storing a distinctive value that is likely to cause an | |
958 | * easy-to-identify error later if it is dereferenced, etc. | |
959 | * | |
960 | * - Triggering a warning on uninitialized memory from Valgrind if | |
961 | * "actions" or "n_actions" was not initialized. | |
962 | */ | |
963 | static void | |
964 | check_rw_odp_flow(struct odp_flow *flow) | |
965 | { | |
966 | if (flow->n_actions) { | |
967 | memset(&flow->actions[0], 0xcc, sizeof flow->actions[0]); | |
968 | } | |
53a4218d | 969 | } |