X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif.c;h=06f793ca636ec4c13163a947c1f3df508a1d91fc;hb=4e256b6bf053a0c4ef9a599f83e647daca3b21a6;hp=e823fa348a5183b6a10a57b07cadde1a2315f0b5;hpb=8fef8c7121222233075a03d57db7e0b48d5f6be5;p=openvswitch diff --git a/lib/dpif.c b/lib/dpif.c index e823fa34..06f793ca 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009 Nicira Networks. + * Copyright (c) 2008, 2009, 2010 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -169,13 +169,35 @@ dpif_open(const char *name, struct dpif **dpifp) /* Tries to create and open a new datapath with the given 'name'. Will fail if * a datapath named 'name' already exists. Returns 0 if successful, otherwise * a positive errno value. On success stores a pointer to the datapath in - * '*dpifp', otherwise a null pointer.*/ + * '*dpifp', otherwise a null pointer. */ int dpif_create(const char *name, struct dpif **dpifp) { return do_open(name, true, dpifp); } +/* Tries to open a datapath with the given 'name', creating it if it does not + * exist. Returns 0 if successful, otherwise a positive errno value. On + * success stores a pointer to the datapath in '*dpifp', otherwise a null + * pointer. */ +int +dpif_create_and_open(const char *name, struct dpif **dpifp) +{ + int error; + + error = dpif_create(name, dpifp); + if (error == EEXIST || error == EBUSY) { + error = dpif_open(name, dpifp); + if (error) { + VLOG_WARN("datapath %s already exists but cannot be opened: %s", + name, strerror(error)); + } + } else if (error) { + VLOG_WARN("failed to create datapath %s: %s", name, strerror(error)); + } + return error; +} + /* Closes and frees the connection to 'dpif'. Does not destroy the datapath * itself; call dpif_delete() first, instead, if that is desirable. */ void @@ -276,6 +298,7 @@ dpif_set_drop_frags(struct dpif *dpif, bool drop_frags) return error; } + /* Attempts to add 'devname' as a port on 'dpif', given the combination of * ODP_PORT_* flags in 'flags'. If successful, returns 0 and sets '*port_nop' * to the new port's port number (if 'port_nop' is non-null). On failure, @@ -397,7 +420,7 @@ dpif_port_list(const struct dpif *dpif, struct odp_port **portsp, size_t *n_portsp) { struct odp_port *ports; - size_t n_ports; + size_t n_ports = 0; int error; for (;;) { @@ -822,6 +845,41 @@ dpif_recv_set_mask(struct dpif *dpif, int listen_mask) return error; } +/* Retrieve the sFlow sampling probability. '*probability' is expressed as the + * number of packets out of UINT_MAX to sample, e.g. probability/UINT_MAX is + * the probability of sampling a given packet. + * + * Returns 0 if successful, otherwise a positive errno value. EOPNOTSUPP + * indicates that 'dpif' does not support sFlow sampling. */ +int +dpif_get_sflow_probability(const struct dpif *dpif, uint32_t *probability) +{ + int error = (dpif->class->get_sflow_probability + ? dpif->class->get_sflow_probability(dpif, probability) + : EOPNOTSUPP); + if (error) { + *probability = 0; + } + log_operation(dpif, "get_sflow_probability", error); + return error; +} + +/* Set the sFlow sampling probability. 'probability' is expressed as the + * number of packets out of UINT_MAX to sample, e.g. probability/UINT_MAX is + * the probability of sampling a given packet. + * + * Returns 0 if successful, otherwise a positive errno value. EOPNOTSUPP + * indicates that 'dpif' does not support sFlow sampling. */ +int +dpif_set_sflow_probability(struct dpif *dpif, uint32_t probability) +{ + int error = (dpif->class->set_sflow_probability + ? dpif->class->set_sflow_probability(dpif, probability) + : EOPNOTSUPP); + log_operation(dpif, "set_sflow_probability", error); + return error; +} + /* Attempts to receive a message from 'dpif'. If successful, stores the * message into '*packetp'. The message, if one is received, will begin with * 'struct odp_msg' as a header. Only messages of the types selected with @@ -845,6 +903,7 @@ dpif_recv(struct dpif *dpif, struct ofpbuf **packetp) "%zu on port %"PRIu16": %s", dpif_name(dpif), (msg->type == _ODPL_MISS_NR ? "miss" : msg->type == _ODPL_ACTION_NR ? "action" + : msg->type == _ODPL_SFLOW_NR ? "sFlow" : ""), payload_len, msg->port, s); free(s); @@ -871,7 +930,7 @@ dpif_recv_purge(struct dpif *dpif) return error; } - for (i = 0; i < stats.max_miss_queue + stats.max_action_queue; i++) { + for (i = 0; i < stats.max_miss_queue + stats.max_action_queue + stats.max_sflow_queue; i++) { struct ofpbuf *buf; error = dpif_recv(dpif, &buf); if (error) {