X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif-linux.c;h=af6eee4161c9abc73b3429854cf230b73ec88a9b;hb=10d3515aa4fc0d338df28d2760fae264c0cea40a;hp=87c9f327c79bf95b5357d64e3cd923c78df5bcd0;hpb=3abc4a1a6c29ebecffeecedd582c64e0bb7d4c53;p=openvswitch diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 87c9f327..af6eee41 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -23,11 +23,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include "dpif-provider.h" @@ -35,6 +37,7 @@ #include "ofpbuf.h" #include "poll-loop.h" #include "rtnetlink.h" +#include "shash.h" #include "svec.h" #include "util.h" @@ -52,7 +55,7 @@ struct dpif_linux { /* Change notification. */ int local_ifindex; /* Ifindex of local port. */ - struct svec changed_ports; /* Ports that have changed. */ + struct shash changed_ports; /* Ports that have changed. */ struct rtnetlink_notifier port_notifier; bool change_error; }; @@ -172,7 +175,7 @@ dpif_linux_close(struct dpif *dpif_) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); rtnetlink_notifier_unregister(&dpif->port_notifier); - svec_destroy(&dpif->changed_ports); + shash_destroy(&dpif->changed_ports); free(dpif->local_ifname); close(dpif->fd); free(dpif); @@ -330,10 +333,12 @@ dpif_linux_port_poll(const struct dpif *dpif_, char **devnamep) if (dpif->change_error) { dpif->change_error = false; - svec_clear(&dpif->changed_ports); + shash_clear(&dpif->changed_ports); return ENOBUFS; - } else if (dpif->changed_ports.n) { - *devnamep = dpif->changed_ports.names[--dpif->changed_ports.n]; + } else if (!shash_is_empty(&dpif->changed_ports)) { + struct shash_node *node = shash_first(&dpif->changed_ports); + *devnamep = xstrdup(node->name); + shash_delete(&dpif->changed_ports, node); return 0; } else { return EAGAIN; @@ -344,7 +349,7 @@ static void dpif_linux_port_poll_wait(const struct dpif *dpif_) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); - if (dpif->changed_ports.n || dpif->change_error) { + if (!shash_is_empty(&dpif->changed_ports) || dpif->change_error) { poll_immediate_wake(); } else { rtnetlink_notifier_wait(); @@ -460,7 +465,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; @@ -785,7 +791,7 @@ open_minor(int minor, struct dpif **dpifp) dpif->local_ifname = NULL; dpif->minor = minor; dpif->local_ifindex = 0; - svec_init(&dpif->changed_ports); + shash_init(&dpif->changed_ports); dpif->change_error = false; *dpifp = &dpif->dpif; } else { @@ -812,10 +818,7 @@ dpif_linux_port_changed(const struct rtnetlink_change *change, void *dpif_) { /* Our datapath changed, either adding a new port or deleting an * existing one. */ - if (!svec_contains(&dpif->changed_ports, change->ifname)) { - svec_add(&dpif->changed_ports, change->ifname); - svec_sort(&dpif->changed_ports); - } + shash_add_once(&dpif->changed_ports, change->ifname, NULL); } } else { dpif->change_error = true;