X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif-linux.c;h=b5590c447889bfef264e5986884d56871f9f18b6;hb=e34c9ddcc8f09925ff44879316f62897f172c30e;hp=f1d42dc230275351bba8cbf5a73d4ca58ad1b155;hpb=3005302426764a2f701bb3507ad9602e3fe2dbb9;p=openvswitch diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index f1d42dc2..b5590c44 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -45,7 +45,7 @@ #include "rtnetlink.h" #include "rtnetlink-link.h" #include "shash.h" -#include "svec.h" +#include "sset.h" #include "unaligned.h" #include "util.h" #include "vlog.h" @@ -125,7 +125,7 @@ struct dpif_linux { unsigned int listen_mask; /* Change notification. */ - struct shash changed_ports; /* Ports that have changed. */ + struct sset changed_ports; /* Ports that have changed. */ struct rtnetlink_notifier port_notifier; bool change_error; }; @@ -159,7 +159,7 @@ dpif_linux_cast(const struct dpif *dpif) } static int -dpif_linux_enumerate(struct svec *all_dps) +dpif_linux_enumerate(struct sset *all_dps) { struct nl_dump dump; struct ofpbuf msg; @@ -175,7 +175,7 @@ dpif_linux_enumerate(struct svec *all_dps) struct dpif_linux_dp dp; if (!dpif_linux_dp_from_ofpbuf(&dp, &msg)) { - svec_add(all_dps, dp.name); + sset_add(all_dps, dp.name); } } return nl_dump_done(&dump); @@ -231,7 +231,7 @@ open_dpif(const struct dpif_linux_dp *dp, struct dpif **dpifp) } dpif->listen_mask = 0; dpif->dp_ifindex = dp->dp_ifindex; - shash_init(&dpif->changed_ports); + sset_init(&dpif->changed_ports); dpif->change_error = false; *dpifp = &dpif->dpif; @@ -247,7 +247,7 @@ dpif_linux_close(struct dpif *dpif_) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); rtnetlink_link_notifier_unregister(&dpif->port_notifier); - shash_destroy(&dpif->changed_ports); + sset_destroy(&dpif->changed_ports); free(dpif); } @@ -483,11 +483,10 @@ dpif_linux_port_poll(const struct dpif *dpif_, char **devnamep) if (dpif->change_error) { dpif->change_error = false; - shash_clear(&dpif->changed_ports); + sset_clear(&dpif->changed_ports); return ENOBUFS; - } else if (!shash_is_empty(&dpif->changed_ports)) { - struct shash_node *node = shash_first(&dpif->changed_ports); - *devnamep = shash_steal(&dpif->changed_ports, node); + } else if (!sset_is_empty(&dpif->changed_ports)) { + *devnamep = sset_pop(&dpif->changed_ports); return 0; } else { return EAGAIN; @@ -498,7 +497,7 @@ static void dpif_linux_port_poll_wait(const struct dpif *dpif_) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); - if (!shash_is_empty(&dpif->changed_ports) || dpif->change_error) { + if (!sset_is_empty(&dpif->changed_ports) || dpif->change_error) { poll_immediate_wake(); } else { rtnetlink_link_notifier_wait(); @@ -1028,6 +1027,34 @@ dpif_linux_is_internal_device(const char *name) return reply.type == ODP_VPORT_TYPE_INTERNAL; } +int +dpif_linux_vport_send(int dp_ifindex, uint32_t port_no, + const void *data, size_t size) +{ + struct odp_header *execute; + struct ofpbuf *buf; + size_t actions_ofs; + int error; + + buf = ofpbuf_new(128 + size); + + nl_msg_put_genlmsghdr(buf, 0, odp_packet_family, NLM_F_REQUEST, + ODP_PACKET_CMD_EXECUTE, 1); + + execute = ofpbuf_put_uninit(buf, sizeof *execute); + execute->dp_ifindex = dp_ifindex; + + nl_msg_put_unspec(buf, ODP_PACKET_ATTR_PACKET, data, size); + + actions_ofs = nl_msg_start_nested(buf, ODP_PACKET_ATTR_ACTIONS); + nl_msg_put_u32(buf, ODP_ACTION_ATTR_OUTPUT, port_no); + nl_msg_end_nested(buf, actions_ofs); + + error = nl_sock_transact(genl_sock, buf, NULL); + ofpbuf_delete(buf); + return error; +} + static void dpif_linux_port_changed(const struct rtnetlink_link_change *change, void *dpif_) @@ -1041,7 +1068,7 @@ dpif_linux_port_changed(const struct rtnetlink_link_change *change, { /* Our datapath changed, either adding a new port or deleting an * existing one. */ - shash_add_once(&dpif->changed_ports, change->ifname, NULL); + sset_add(&dpif->changed_ports, change->ifname); } } else { dpif->change_error = true; @@ -1108,6 +1135,8 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport, } if (a[ODP_VPORT_ATTR_MTU]) { vport->mtu = nl_attr_get_u32(a[ODP_VPORT_ATTR_MTU]); + } else { + vport->mtu = INT_MAX; } if (a[ODP_VPORT_ATTR_OPTIONS]) { vport->options = nl_attr_get(a[ODP_VPORT_ATTR_OPTIONS]); @@ -1158,7 +1187,7 @@ dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *vport, vport->address, ETH_ADDR_LEN); } - if (vport->mtu) { + if (vport->mtu && vport->mtu != INT_MAX) { nl_msg_put_u32(buf, ODP_VPORT_ATTR_MTU, vport->mtu); }