X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif.c;h=649c2464c8aae38a11a3f0e7f23ab10640ad448f;hb=fcf78c4ff96920a988b954def9ab054bef672612;hp=d2ef845da8bf1655cef7cb1d9ab21c05176a90cb;hpb=e9e28be359f64c03944c0a282c17e714fcb0afc4;p=openvswitch diff --git a/lib/dpif.c b/lib/dpif.c index d2ef845d..649c2464 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -33,14 +33,16 @@ #include "ofpbuf.h" #include "packets.h" #include "poll-loop.h" +#include "svec.h" #include "util.h" #include "valgrind.h" #include "vlog.h" #define THIS_MODULE VLM_dpif -static struct dpif_class *dpif_classes[] = { +static const struct dpif_class *dpif_classes[] = { &dpif_linux_class, + &dpif_netdev_class, }; enum { N_DPIF_CLASSES = ARRAY_SIZE(dpif_classes) }; @@ -63,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) { @@ -79,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) { @@ -93,6 +95,34 @@ dp_wait(void) } } +/* 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. */ +int +dp_enumerate(struct svec *all_dps) +{ + int error; + int i; + + svec_clear(all_dps); + error = 0; + for (i = 0; i < N_DPIF_CLASSES; i++) { + const struct dpif_class *class = dpif_classes[i]; + int retval = class->enumerate ? class->enumerate(all_dps) : 0; + if (retval) { + VLOG_WARN("failed to enumerate %s datapaths: %s", + class->name, strerror(retval)); + if (!error) { + error = retval; + } + } + } + return error; +} + static int do_open(const char *name_, bool create, struct dpif **dpifp) { @@ -165,6 +195,32 @@ dpif_name(const struct dpif *dpif) return dpif->name; } +/* Enumerates all names that may be used to open 'dpif' into 'all_names'. The + * Linux datapath, for example, supports opening a datapath both by number, + * e.g. "dp0", and by the name of the datapath's local port. For some + * datapaths, this might be an infinite set (e.g. in a file name, slashes may + * be duplicated any number of times), in which case only the names most likely + * to be used will be enumerated. + * + * The caller must already have initialized 'all_names'. Any existing names in + * 'all_names' will not be disturbed. */ +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 (error) { + VLOG_WARN_RL(&error_rl, + "failed to retrieve names for datpath %s: %s", + dpif_name(dpif), strerror(error)); + } + return error; + } else { + svec_add(all_names, dpif_name(dpif)); + return 0; + } +} + /* Destroys the datapath that 'dpif' is connected to, first removing all of its * ports. After calling this function, it does not make sense to pass 'dpif' * to any functions other than dpif_name() or dpif_close(). */ @@ -341,7 +397,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 (;;) {