X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif.c;h=649c2464c8aae38a11a3f0e7f23ab10640ad448f;hb=8b681e6fdffe4ebd68dc259544abc87d4cccf0cb;hp=0e83a9e2afaea4403284360cbd41974983be0e24;hpb=72865317a41d065fcc47a33fc68cdd2081cecb3d;p=openvswitch diff --git a/lib/dpif.c b/lib/dpif.c index 0e83a9e2..649c2464 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -33,6 +33,7 @@ #include "ofpbuf.h" #include "packets.h" #include "poll-loop.h" +#include "svec.h" #include "util.h" #include "valgrind.h" @@ -64,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) { @@ -80,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) { @@ -94,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) { @@ -166,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(). */ @@ -342,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 (;;) {