X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif-linux.c;h=15283b282cb398642f40ea7d111694db8e607d42;hb=3bcf3e33e9cfb7fd837086bfa8e627110d84dce8;hp=4c34325651fdd6efef0594b876ebb9699324d5c9;hpb=c69ee87c10818267f991236201150b1fa51ae519;p=openvswitch diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 4c343256..15283b28 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" @@ -190,6 +191,28 @@ dpif_linux_get_all_names(const struct dpif *dpif_, struct svec *all_names) static int 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); } @@ -230,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; } @@ -241,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 @@ -417,7 +460,8 @@ dpif_linux_recv(struct dpif *dpif_, struct ofpbuf **bufp) int retval; int error; - buf = ofpbuf_new(65536); + buf = ofpbuf_new(65536 + DPIF_RECV_MSG_PADDING); + ofpbuf_reserve(buf, DPIF_RECV_MSG_PADDING); retval = read(dpif->fd, ofpbuf_tail(buf), ofpbuf_tailroom(buf)); if (retval < 0) { error = errno; @@ -677,6 +721,8 @@ get_major(const char *target) } } + fclose(file); + VLOG_ERR("%s: %s major not found (is the module loaded?)", fn, target); return -ENODEV; }