X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif-linux.c;h=87c9f327c79bf95b5357d64e3cd923c78df5bcd0;hb=3abc4a1a6c29ebecffeecedd582c64e0bb7d4c53;hp=94c3cf5c5a756af34c100d4facc3b4bc4bdf30d5;hpb=999401aa9caf241400406192ca7e55d7732a1c44;p=openvswitch diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 94c3cf5c..87c9f327 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -31,6 +31,7 @@ #include #include "dpif-provider.h" +#include "netdev.h" #include "ofpbuf.h" #include "poll-loop.h" #include "rtnetlink.h" @@ -107,7 +108,7 @@ dpif_linux_enumerate(struct svec *all_dps) } static int -dpif_linux_open(const char *name, const char *type UNUSED, bool create, +dpif_linux_open(const char *name, const char *type OVS_UNUSED, bool create, struct dpif **dpifp) { int minor; @@ -188,14 +189,37 @@ dpif_linux_get_all_names(const struct dpif *dpif_, struct svec *all_names) } static int -dpif_linux_delete(struct dpif *dpif_) +dpif_linux_destroy(struct dpif *dpif_) { + struct odp_port *ports; + size_t n_ports; + int err; + int i; + + err = dpif_port_list(dpif_, &ports, &n_ports); + if (err) { + return err; + } + + for (i = 0; i < n_ports; i++) { + if (ports[i].port != ODPP_LOCAL) { + err = do_ioctl(dpif_, ODP_VPORT_DEL, ports[i].devname); + if (err) { + VLOG_WARN_RL(&error_rl, "%s: error deleting port %s (%s)", + dpif_name(dpif_), ports[i].devname, strerror(err)); + } + } + } + + free(ports); + return do_ioctl(dpif_, ODP_DP_DESTROY, NULL); } static int dpif_linux_get_stats(const struct dpif *dpif_, struct odp_stats *stats) { + memset(stats, 0, sizeof *stats); return do_ioctl(dpif_, ODP_DP_STATS, stats); } @@ -229,7 +253,7 @@ dpif_linux_port_add(struct dpif *dpif_, const char *devname, uint16_t flags, memset(&port, 0, sizeof port); strncpy(port.devname, devname, sizeof port.devname); port.flags = flags; - error = do_ioctl(dpif_, ODP_PORT_ADD, &port); + error = do_ioctl(dpif_, ODP_PORT_ATTACH, &port); if (!error) { *port_no = port.port; } @@ -240,7 +264,27 @@ static int dpif_linux_port_del(struct dpif *dpif_, uint16_t port_no) { int tmp = port_no; - return do_ioctl(dpif_, ODP_PORT_DEL, &tmp); + int err; + struct odp_port port; + + err = dpif_port_query_by_number(dpif_, port_no, &port); + if (err) { + return err; + } + + err = do_ioctl(dpif_, ODP_PORT_DETACH, &tmp); + if (err) { + return err; + } + + if (!netdev_is_open(port.devname)) { + /* Try deleting the port if no one has it open. This shouldn't + * actually be necessary unless the config changed while we weren't + * running but it won't hurt anything if the port is already gone. */ + do_ioctl(dpif_, ODP_VPORT_DEL, port.devname); + } + + return 0; } static int @@ -395,6 +439,19 @@ dpif_linux_recv_set_mask(struct dpif *dpif_, int listen_mask) return do_ioctl(dpif_, ODP_SET_LISTEN_MASK, &listen_mask); } +static int +dpif_linux_get_sflow_probability(const struct dpif *dpif_, + uint32_t *probability) +{ + return do_ioctl(dpif_, ODP_GET_SFLOW_PROBABILITY, probability); +} + +static int +dpif_linux_set_sflow_probability(struct dpif *dpif_, uint32_t probability) +{ + return do_ioctl(dpif_, ODP_SET_SFLOW_PROBABILITY, &probability); +} + static int dpif_linux_recv(struct dpif *dpif_, struct ofpbuf **bufp) { @@ -453,7 +510,7 @@ const struct dpif_class dpif_linux_class = { dpif_linux_open, dpif_linux_close, dpif_linux_get_all_names, - dpif_linux_delete, + dpif_linux_destroy, dpif_linux_get_stats, dpif_linux_get_drop_frags, dpif_linux_set_drop_frags, @@ -474,6 +531,8 @@ const struct dpif_class dpif_linux_class = { dpif_linux_execute, dpif_linux_recv_get_mask, dpif_linux_recv_set_mask, + dpif_linux_get_sflow_probability, + dpif_linux_set_sflow_probability, dpif_linux_recv, dpif_linux_recv_wait, }; @@ -554,13 +613,14 @@ make_openvswitch_device(int minor, char **fnp) struct stat s; char fn[128]; + *fnp = NULL; + major = get_openvswitch_major(); if (major < 0) { return -major; } dev = makedev(major, minor); - *fnp = NULL; sprintf(fn, "%s/dp%d", dirname, minor); if (!stat(fn, &s)) { if (!S_ISCHR(s.st_mode)) { @@ -660,6 +720,8 @@ get_major(const char *target) } } + fclose(file); + VLOG_ERR("%s: %s major not found (is the module loaded?)", fn, target); return -ENODEV; }