X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fdpif.c;h=72184c8408512f82d3373b485fcf7b646bbb3eba;hb=ca9ca7537065f2d1b627ed9111e44c2c227258a7;hp=73fa4b98375d9614f8a0396df16487e1904a34b1;hpb=3b01baa3970139c3a195017ab1ea3e42761e3db2;p=sliver-openvswitch.git diff --git a/lib/dpif.c b/lib/dpif.c index 73fa4b983..72184c840 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -65,8 +65,8 @@ static void check_rw_odp_flow(struct odp_flow *); /* Performs periodic work needed by all the various kinds of dpifs. * - * If your program opens any dpifs, it must call this function within its main - * poll loop. */ + * If your program opens any dpifs, it must call both this function and + * netdev_run() within its main poll loop. */ void dp_run(void) { @@ -81,8 +81,8 @@ dp_run(void) /* Arranges for poll_block() to wake up when dp_run() needs to be called. * - * If your program opens any dpifs, it must call this function within its main - * poll loop. */ + * If your program opens any dpifs, it must call both this function and + * netdev_wait() within its main poll loop. */ void dp_wait(void) { @@ -95,9 +95,9 @@ dp_wait(void) } } -/* Initializes 'all_dps' and enumerates the names of all known created - * datapaths, where possible, into it. Returns 0 if successful, otherwise a - * positive errno value. +/* Clears 'all_dps' and enumerates the names of all known created datapaths, + * where possible, into it. The caller must first initialize 'all_dps'. + * Returns 0 if successful, otherwise a positive errno value. * * Some kinds of datapaths might not be practically enumerable. This is not * considered an error. */ @@ -107,7 +107,7 @@ dp_enumerate(struct svec *all_dps) int error; int i; - svec_init(all_dps); + svec_clear(all_dps); error = 0; for (i = 0; i < N_DPIF_CLASSES; i++) { const struct dpif_class *class = dpif_classes[i]; @@ -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 @@ -183,7 +205,7 @@ dpif_close(struct dpif *dpif) { if (dpif) { char *name = dpif->name; - dpif->class->close(dpif); + dpif->dpif_class->close(dpif); free(name); } } @@ -207,8 +229,8 @@ dpif_name(const struct dpif *dpif) 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", @@ -231,7 +253,7 @@ dpif_delete(struct dpif *dpif) COVERAGE_INC(dpif_destroy); - error = dpif->class->delete(dpif); + error = dpif->dpif_class->destroy(dpif); log_operation(dpif, "delete", error); return error; } @@ -241,7 +263,7 @@ dpif_delete(struct dpif *dpif) 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); } @@ -257,7 +279,7 @@ dpif_get_dp_stats(const struct dpif *dpif, struct odp_stats *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; } @@ -271,7 +293,7 @@ dpif_get_drop_frags(const struct dpif *dpif, bool *drop_frags) 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; } @@ -290,7 +312,7 @@ dpif_port_add(struct dpif *dpif, const char *devname, uint16_t flags, 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); @@ -314,7 +336,7 @@ dpif_port_del(struct dpif *dpif, uint16_t 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; } @@ -326,7 +348,7 @@ int 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); @@ -345,7 +367,7 @@ int 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); @@ -397,7 +419,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 (;;) { @@ -410,7 +432,7 @@ dpif_port_list(const struct dpif *dpif, } 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; @@ -458,7 +480,7 @@ exit: 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; } @@ -470,7 +492,7 @@ dpif_port_poll(const struct dpif *dpif, char **devnamep) 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'. @@ -491,8 +513,8 @@ dpif_port_group_get(const struct dpif *dpif, uint16_t group, *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; @@ -530,7 +552,7 @@ dpif_port_group_set(struct dpif *dpif, uint16_t group, 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; } @@ -544,7 +566,7 @@ dpif_flow_flush(struct dpif *dpif) 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; } @@ -570,7 +592,7 @@ dpif_flow_get(const struct dpif *dpif, struct odp_flow *flow) 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; } @@ -620,7 +642,7 @@ dpif_flow_get_multiple(const struct dpif *dpif, 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; } @@ -648,7 +670,7 @@ dpif_flow_put(struct dpif *dpif, struct odp_flow_put *put) 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); } @@ -670,7 +692,7 @@ dpif_flow_del(struct dpif *dpif, struct odp_flow *flow) 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); } @@ -699,7 +721,7 @@ dpif_flow_list(const struct dpif *dpif, struct odp_flow flows[], size_t n, 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)", @@ -776,7 +798,8 @@ dpif_execute(struct dpif *dpif, uint16_t in_port, 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; } @@ -803,7 +826,7 @@ dpif_execute(struct dpif *dpif, uint16_t in_port, 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; } @@ -817,7 +840,7 @@ dpif_recv_get_mask(const struct dpif *dpif, int *listen_mask) 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; } @@ -833,7 +856,7 @@ dpif_recv_set_mask(struct dpif *dpif, int listen_mask) 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; @@ -887,7 +910,7 @@ dpif_recv_purge(struct dpif *dpif) 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' @@ -901,10 +924,11 @@ dpif_get_netflow_ids(const struct dpif *dpif, } 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;