/* 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
{
if (dpif) {
char *name = dpif->name;
- dpif->class->close(dpif);
+ dpif->dpif_class->close(dpif);
free(name);
}
}
int
dpif_get_all_names(const struct dpif *dpif, struct svec *all_names)
{
- if (dpif->class->get_all_names) {
- int error = dpif->class->get_all_names(dpif, all_names);
+ if (dpif->dpif_class->get_all_names) {
+ int error = dpif->dpif_class->get_all_names(dpif, all_names);
if (error) {
VLOG_WARN_RL(&error_rl,
"failed to retrieve names for datpath %s: %s",
COVERAGE_INC(dpif_destroy);
- error = dpif->class->delete(dpif);
+ error = dpif->dpif_class->destroy(dpif);
log_operation(dpif, "delete", error);
return error;
}
int
dpif_get_dp_stats(const struct dpif *dpif, struct odp_stats *stats)
{
- int error = dpif->class->get_stats(dpif, stats);
+ int error = dpif->dpif_class->get_stats(dpif, stats);
if (error) {
memset(stats, 0, sizeof *stats);
}
int
dpif_get_drop_frags(const struct dpif *dpif, bool *drop_frags)
{
- int error = dpif->class->get_drop_frags(dpif, drop_frags);
+ int error = dpif->dpif_class->get_drop_frags(dpif, drop_frags);
if (error) {
*drop_frags = false;
}
int
dpif_set_drop_frags(struct dpif *dpif, bool drop_frags)
{
- int error = dpif->class->set_drop_frags(dpif, drop_frags);
+ int error = dpif->dpif_class->set_drop_frags(dpif, drop_frags);
log_operation(dpif, "set_drop_frags", error);
return error;
}
COVERAGE_INC(dpif_port_add);
- error = dpif->class->port_add(dpif, devname, flags, &port_no);
+ error = dpif->dpif_class->port_add(dpif, devname, flags, &port_no);
if (!error) {
VLOG_DBG_RL(&dpmsg_rl, "%s: added %s as port %"PRIu16,
dpif_name(dpif), devname, port_no);
COVERAGE_INC(dpif_port_del);
- error = dpif->class->port_del(dpif, port_no);
+ error = dpif->dpif_class->port_del(dpif, port_no);
log_operation(dpif, "port_del", error);
return error;
}
dpif_port_query_by_number(const struct dpif *dpif, uint16_t port_no,
struct odp_port *port)
{
- int error = dpif->class->port_query_by_number(dpif, port_no, port);
+ int error = dpif->dpif_class->port_query_by_number(dpif, port_no, port);
if (!error) {
VLOG_DBG_RL(&dpmsg_rl, "%s: port %"PRIu16" is device %s",
dpif_name(dpif), port_no, port->devname);
dpif_port_query_by_name(const struct dpif *dpif, const char *devname,
struct odp_port *port)
{
- int error = dpif->class->port_query_by_name(dpif, devname, port);
+ int error = dpif->dpif_class->port_query_by_name(dpif, devname, port);
if (!error) {
VLOG_DBG_RL(&dpmsg_rl, "%s: device %s is on port %"PRIu16,
dpif_name(dpif), devname, port->port);
struct odp_port **portsp, size_t *n_portsp)
{
struct odp_port *ports;
- size_t n_ports;
+ size_t n_ports = 0;
int error;
for (;;) {
}
ports = xcalloc(stats.n_ports, sizeof *ports);
- retval = dpif->class->port_list(dpif, ports, stats.n_ports);
+ retval = dpif->dpif_class->port_list(dpif, ports, stats.n_ports);
if (retval < 0) {
/* Hard error. */
error = -retval;
int
dpif_port_poll(const struct dpif *dpif, char **devnamep)
{
- int error = dpif->class->port_poll(dpif, devnamep);
+ int error = dpif->dpif_class->port_poll(dpif, devnamep);
if (error) {
*devnamep = NULL;
}
void
dpif_port_poll_wait(const struct dpif *dpif)
{
- dpif->class->port_poll_wait(dpif);
+ dpif->dpif_class->port_poll_wait(dpif);
}
/* Retrieves a list of the port numbers in port group 'group' in 'dpif'.
*ports = NULL;
*n_ports = 0;
for (;;) {
- int retval = dpif->class->port_group_get(dpif, group,
- *ports, *n_ports);
+ int retval = dpif->dpif_class->port_group_get(dpif, group,
+ *ports, *n_ports);
if (retval < 0) {
/* Hard error. */
error = -retval;
COVERAGE_INC(dpif_port_group_set);
- error = dpif->class->port_group_set(dpif, group, ports, n_ports);
+ error = dpif->dpif_class->port_group_set(dpif, group, ports, n_ports);
log_operation(dpif, "port_group_set", error);
return error;
}
COVERAGE_INC(dpif_flow_flush);
- error = dpif->class->flow_flush(dpif);
+ error = dpif->dpif_class->flow_flush(dpif);
log_operation(dpif, "flow_flush", error);
return error;
}
COVERAGE_INC(dpif_flow_get);
check_rw_odp_flow(flow);
- error = dpif->class->flow_get(dpif, flow, 1);
+ error = dpif->dpif_class->flow_get(dpif, flow, 1);
if (!error) {
error = flow->stats.error;
}
check_rw_odp_flow(&flows[i]);
}
- error = dpif->class->flow_get(dpif, flows, n);
+ error = dpif->dpif_class->flow_get(dpif, flows, n);
log_operation(dpif, "flow_get_multiple", error);
return error;
}
COVERAGE_INC(dpif_flow_put);
- error = dpif->class->flow_put(dpif, put);
+ error = dpif->dpif_class->flow_put(dpif, put);
if (should_log_flow_message(error)) {
log_flow_put(dpif, error, put);
}
check_rw_odp_flow(flow);
memset(&flow->stats, 0, sizeof flow->stats);
- error = dpif->class->flow_del(dpif, flow);
+ error = dpif->dpif_class->flow_del(dpif, flow);
if (should_log_flow_message(error)) {
log_flow_operation(dpif, "delete flow", error, flow);
}
flows[i].n_actions = 0;
}
}
- retval = dpif->class->flow_list(dpif, flows, n);
+ retval = dpif->dpif_class->flow_list(dpif, flows, n);
if (retval < 0) {
*n_out = 0;
VLOG_WARN_RL(&error_rl, "%s: flow list failed (%s)",
COVERAGE_INC(dpif_execute);
if (n_actions > 0) {
- error = dpif->class->execute(dpif, in_port, actions, n_actions, buf);
+ error = dpif->dpif_class->execute(dpif, in_port, actions,
+ n_actions, buf);
} else {
error = 0;
}
int
dpif_recv_get_mask(const struct dpif *dpif, int *listen_mask)
{
- int error = dpif->class->recv_get_mask(dpif, listen_mask);
+ int error = dpif->dpif_class->recv_get_mask(dpif, listen_mask);
if (error) {
*listen_mask = 0;
}
int
dpif_recv_set_mask(struct dpif *dpif, int listen_mask)
{
- int error = dpif->class->recv_set_mask(dpif, listen_mask);
+ int error = dpif->dpif_class->recv_set_mask(dpif, listen_mask);
log_operation(dpif, "recv_set_mask", error);
return error;
}
int
dpif_recv(struct dpif *dpif, struct ofpbuf **packetp)
{
- int error = dpif->class->recv(dpif, packetp);
+ int error = dpif->dpif_class->recv(dpif, packetp);
if (!error) {
if (VLOG_IS_DBG_ENABLED()) {
struct ofpbuf *buf = *packetp;
void
dpif_recv_wait(struct dpif *dpif)
{
- dpif->class->recv_wait(dpif);
+ dpif->dpif_class->recv_wait(dpif);
}
/* Obtains the NetFlow engine type and engine ID for 'dpif' into '*engine_type'
}
\f
void
-dpif_init(struct dpif *dpif, const struct dpif_class *class, const char *name,
+dpif_init(struct dpif *dpif, const struct dpif_class *dpif_class,
+ const char *name,
uint8_t netflow_engine_type, uint8_t netflow_engine_id)
{
- dpif->class = class;
+ dpif->dpif_class = dpif_class;
dpif->name = xstrdup(name);
dpif->netflow_engine_type = netflow_engine_type;
dpif->netflow_engine_id = netflow_engine_id;