Rename dpif_linux -> dpif_netlink the actual file can be renamed as well in the future.
Bypass all epoll functionality. Treat dpif_netlink_recv__ with lazy polling using GetOverlappedResult with the newly added overlapped structure in netlink.c Initialize dpif_netlink_class on MSVC as well and dpif-linux and add files needed to automake.mk Signed-off-by: Alin Gabriel Serdean <aserd...@cloudbasesolutions.com> --- lib/automake.mk | 2 + lib/dpif-linux.c | 639 ++++++++++++++++++++++++++------------------------- lib/dpif-linux.h | 12 +- lib/dpif-provider.h | 2 +- lib/dpif.c | 4 +- lib/netlink-socket.c | 22 +- lib/netlink-socket.h | 5 + 7 files changed, 368 insertions(+), 318 deletions(-) diff --git a/lib/automake.mk b/lib/automake.mk index d46613f..84c2de8 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -326,6 +326,8 @@ endif if WIN32 lib_libopenvswitch_la_SOURCES += \ + lib/dpif-linux.c \ + lib/dpif-linux.h \ lib/netlink-notifier.c \ lib/netlink-notifier.h \ lib/netlink-protocol.h \ diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index e5067ba..566b521 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -55,14 +55,14 @@ #include "util.h" #include "vlog.h" -VLOG_DEFINE_THIS_MODULE(dpif_linux); +VLOG_DEFINE_THIS_MODULE(dpif_netlink); enum { MAX_PORTS = USHRT_MAX }; /* This ethtool flag was introduced in Linux 2.6.24, so it might be * missing if we have old headers. */ #define ETH_FLAG_LRO (1 << 15) /* LRO is enabled */ -struct dpif_linux_dp { +struct dpif_netlink_dp { /* Generic Netlink header. */ uint8_t cmd; @@ -78,17 +78,17 @@ struct dpif_linux_dp { /* OVS_DP_ATTR_MEGAFLOW_STATS.*/ }; -static void dpif_linux_dp_init(struct dpif_linux_dp *); -static int dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp *, +static void dpif_netlink_dp_init(struct dpif_netlink_dp *); +static int dpif_netlink_dp_from_ofpbuf(struct dpif_netlink_dp *, const struct ofpbuf *); -static void dpif_linux_dp_dump_start(struct nl_dump *); -static int dpif_linux_dp_transact(const struct dpif_linux_dp *request, - struct dpif_linux_dp *reply, +static void dpif_netlink_dp_dump_start(struct nl_dump *); +static int dpif_netlink_dp_transact(const struct dpif_netlink_dp *request, + struct dpif_netlink_dp *reply, struct ofpbuf **bufp); -static int dpif_linux_dp_get(const struct dpif *, struct dpif_linux_dp *reply, +static int dpif_netlink_dp_get(const struct dpif *, struct dpif_netlink_dp *reply, struct ofpbuf **bufp); -struct dpif_linux_flow { +struct dpif_netlink_flow { /* Generic Netlink header. */ uint8_t cmd; @@ -116,18 +116,18 @@ struct dpif_linux_flow { bool clear; /* OVS_FLOW_ATTR_CLEAR. */ }; -static void dpif_linux_flow_init(struct dpif_linux_flow *); -static int dpif_linux_flow_from_ofpbuf(struct dpif_linux_flow *, +static void dpif_netlink_flow_init(struct dpif_netlink_flow *); +static int dpif_netlink_flow_from_ofpbuf(struct dpif_netlink_flow *, const struct ofpbuf *); -static void dpif_linux_flow_to_ofpbuf(const struct dpif_linux_flow *, +static void dpif_netlink_flow_to_ofpbuf(const struct dpif_netlink_flow *, struct ofpbuf *); -static int dpif_linux_flow_transact(struct dpif_linux_flow *request, - struct dpif_linux_flow *reply, +static int dpif_netlink_flow_transact(struct dpif_netlink_flow *request, + struct dpif_netlink_flow *reply, struct ofpbuf **bufp); -static void dpif_linux_flow_get_stats(const struct dpif_linux_flow *, +static void dpif_netlink_flow_get_stats(const struct dpif_netlink_flow *, struct dpif_flow_stats *); -static void dpif_linux_flow_to_dpif_flow(struct dpif_flow *, - const struct dpif_linux_flow *); +static void dpif_netlink_flow_to_dpif_flow(struct dpif_flow *, + const struct dpif_netlink_flow *); /* One of the dpif channels between the kernel and userspace. */ struct dpif_channel { @@ -144,7 +144,7 @@ struct dpif_handler { }; /* Datapath interface for the openvswitch Linux kernel module. */ -struct dpif_linux { +struct dpif_netlink { struct dpif dpif; int dp_ifindex; @@ -160,14 +160,14 @@ struct dpif_linux { bool refresh_channels; }; -static void report_loss(struct dpif_linux *, struct dpif_channel *, +static void report_loss(struct dpif_netlink *, struct dpif_channel *, uint32_t ch_idx, uint32_t handler_id); static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(9999, 5); /* Generic Netlink family numbers for OVS. * - * Initialized by dpif_linux_init(). */ + * Initialized by dpif_netlink_init(). */ static int ovs_datapath_family; static int ovs_vport_family; static int ovs_flow_family; @@ -175,29 +175,29 @@ static int ovs_packet_family; /* Generic Netlink multicast groups for OVS. * - * Initialized by dpif_linux_init(). */ + * Initialized by dpif_netlink_init(). */ static unsigned int ovs_vport_mcgroup; -static int dpif_linux_init(void); -static int open_dpif(const struct dpif_linux_dp *, struct dpif **); -static uint32_t dpif_linux_port_get_pid(const struct dpif *, +static int dpif_netlink_init(void); +static int open_dpif(const struct dpif_netlink_dp *, struct dpif **); +static uint32_t dpif_netlink_port_get_pid(const struct dpif *, odp_port_t port_no, uint32_t hash); -static int dpif_linux_refresh_channels(struct dpif_linux *, +static int dpif_netlink_refresh_channels(struct dpif_netlink *, uint32_t n_handlers); -static void dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *, +static void dpif_netlink_vport_to_ofpbuf(const struct dpif_netlink_vport *, struct ofpbuf *); -static int dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *, +static int dpif_netlink_vport_from_ofpbuf(struct dpif_netlink_vport *, const struct ofpbuf *); -static struct dpif_linux * -dpif_linux_cast(const struct dpif *dpif) +static struct dpif_netlink * +dpif_netlink_cast(const struct dpif *dpif) { - dpif_assert_class(dpif, &dpif_linux_class); - return CONTAINER_OF(dpif, struct dpif_linux, dpif); + dpif_assert_class(dpif, &dpif_netlink_class); + return CONTAINER_OF(dpif, struct dpif_netlink, dpif); } static int -dpif_linux_enumerate(struct sset *all_dps, +dpif_netlink_enumerate(struct sset *all_dps, const struct dpif_class *dpif_class OVS_UNUSED) { struct nl_dump dump; @@ -205,17 +205,17 @@ dpif_linux_enumerate(struct sset *all_dps, struct ofpbuf msg, buf; int error; - error = dpif_linux_init(); + error = dpif_netlink_init(); if (error) { return error; } ofpbuf_use_stub(&buf, reply_stub, sizeof reply_stub); - dpif_linux_dp_dump_start(&dump); + dpif_netlink_dp_dump_start(&dump); while (nl_dump_next(&dump, &msg, &buf)) { - struct dpif_linux_dp dp; + struct dpif_netlink_dp dp; - if (!dpif_linux_dp_from_ofpbuf(&dp, &msg)) { + if (!dpif_netlink_dp_from_ofpbuf(&dp, &msg)) { sset_add(all_dps, dp.name); } } @@ -224,21 +224,21 @@ dpif_linux_enumerate(struct sset *all_dps, } static int -dpif_linux_open(const struct dpif_class *class OVS_UNUSED, const char *name, +dpif_netlink_open(const struct dpif_class *class OVS_UNUSED, const char *name, bool create, struct dpif **dpifp) { - struct dpif_linux_dp dp_request, dp; + struct dpif_netlink_dp dp_request, dp; struct ofpbuf *buf; uint32_t upcall_pid; int error; - error = dpif_linux_init(); + error = dpif_netlink_init(); if (error) { return error; } /* Create or look up datapath. */ - dpif_linux_dp_init(&dp_request); + dpif_netlink_dp_init(&dp_request); if (create) { dp_request.cmd = OVS_DP_CMD_NEW; upcall_pid = 0; @@ -250,7 +250,7 @@ dpif_linux_open(const struct dpif_class *class OVS_UNUSED, const char *name, dp_request.name = name; dp_request.user_features |= OVS_DP_F_UNALIGNED; dp_request.user_features |= OVS_DP_F_VPORT_PIDS; - error = dpif_linux_dp_transact(&dp_request, &dp, &buf); + error = dpif_netlink_dp_transact(&dp_request, &dp, &buf); if (error) { return error; } @@ -261,15 +261,15 @@ dpif_linux_open(const struct dpif_class *class OVS_UNUSED, const char *name, } static int -open_dpif(const struct dpif_linux_dp *dp, struct dpif **dpifp) +open_dpif(const struct dpif_netlink_dp *dp, struct dpif **dpifp) { - struct dpif_linux *dpif; + struct dpif_netlink *dpif; dpif = xzalloc(sizeof *dpif); dpif->port_notifier = NULL; fat_rwlock_init(&dpif->upcall_lock); - dpif_init(&dpif->dpif, &dpif_linux_class, dp->name, + dpif_init(&dpif->dpif, &dpif_netlink_class, dp->name, dp->dp_ifindex, dp->dp_ifindex); dpif->dp_ifindex = dp->dp_ifindex; @@ -340,7 +340,7 @@ vport_socksp_to_pids(struct nl_sock **socksp, uint32_t n_socks) /* Given the port number 'port_idx', extracts the pids of netlink sockets * associated to the port and assigns it to 'upcall_pids'. */ static bool -vport_get_pids(struct dpif_linux *dpif, uint32_t port_idx, +vport_get_pids(struct dpif_netlink *dpif, uint32_t port_idx, uint32_t **upcall_pids) { uint32_t *pids; @@ -365,7 +365,7 @@ vport_get_pids(struct dpif_linux *dpif, uint32_t port_idx, } static int -vport_add_channels(struct dpif_linux *dpif, odp_port_t port_no, +vport_add_channels(struct dpif_netlink *dpif, odp_port_t port_no, struct nl_sock **socksp) { struct epoll_event event; @@ -412,12 +412,15 @@ vport_add_channels(struct dpif_linux *dpif, odp_port_t port_no, for (i = 0; i < dpif->n_handlers; i++) { struct dpif_handler *handler = &dpif->handlers[i]; - +#ifndef _WIN32 if (epoll_ctl(handler->epoll_fd, EPOLL_CTL_ADD, nl_sock_fd(socksp[i]), &event) < 0) { error = errno; goto error; } +#else + memcpy(&dpif->handlers[i].epoll_events[port_idx], &event, sizeof(event)); +#endif dpif->handlers[i].channels[port_idx].sock = socksp[i]; dpif->handlers[i].channels[port_idx].last_poll = LLONG_MIN; } @@ -426,8 +429,10 @@ vport_add_channels(struct dpif_linux *dpif, odp_port_t port_no, error: for (j = 0; j < i; j++) { +#ifndef _WIN32 epoll_ctl(dpif->handlers[j].epoll_fd, EPOLL_CTL_DEL, nl_sock_fd(socksp[j]), NULL); +#endif dpif->handlers[j].channels[port_idx].sock = NULL; } @@ -435,7 +440,7 @@ error: } static void -vport_del_channels(struct dpif_linux *dpif, odp_port_t port_no) +vport_del_channels(struct dpif_netlink *dpif, odp_port_t port_no) { uint32_t port_idx = odp_to_u32(port_no); size_t i; @@ -453,9 +458,10 @@ vport_del_channels(struct dpif_linux *dpif, odp_port_t port_no) for (i = 0; i < dpif->n_handlers; i++) { struct dpif_handler *handler = &dpif->handlers[i]; - +#ifndef _WIN32 epoll_ctl(handler->epoll_fd, EPOLL_CTL_DEL, nl_sock_fd(handler->channels[port_idx].sock), NULL); +#endif nl_sock_destroy(handler->channels[port_idx].sock); handler->channels[port_idx].sock = NULL; handler->event_offset = handler->n_events = 0; @@ -463,7 +469,7 @@ vport_del_channels(struct dpif_linux *dpif, odp_port_t port_no) } static void -destroy_all_channels(struct dpif_linux *dpif) OVS_REQ_WRLOCK(dpif->upcall_lock) +destroy_all_channels(struct dpif_netlink *dpif) OVS_REQ_WRLOCK(dpif->upcall_lock) { unsigned int i; @@ -472,7 +478,7 @@ destroy_all_channels(struct dpif_linux *dpif) OVS_REQ_WRLOCK(dpif->upcall_lock) } for (i = 0; i < dpif->uc_array_size; i++ ) { - struct dpif_linux_vport vport_request; + struct dpif_netlink_vport vport_request; uint32_t upcall_pids = 0; /* Since the sock can only be assigned in either all or none @@ -483,12 +489,12 @@ destroy_all_channels(struct dpif_linux *dpif) OVS_REQ_WRLOCK(dpif->upcall_lock) } /* Turn off upcalls. */ - dpif_linux_vport_init(&vport_request); + dpif_netlink_vport_init(&vport_request); vport_request.cmd = OVS_VPORT_CMD_SET; vport_request.dp_ifindex = dpif->dp_ifindex; vport_request.port_no = u32_to_odp(i); vport_request.upcall_pids = &upcall_pids; - dpif_linux_vport_transact(&vport_request, NULL, NULL); + dpif_netlink_vport_transact(&vport_request, NULL, NULL); vport_del_channels(dpif, u32_to_odp(i)); } @@ -508,9 +514,9 @@ destroy_all_channels(struct dpif_linux *dpif) OVS_REQ_WRLOCK(dpif->upcall_lock) } static void -dpif_linux_close(struct dpif *dpif_) +dpif_netlink_close(struct dpif *dpif_) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); nl_sock_destroy(dpif->port_notifier); @@ -523,38 +529,38 @@ dpif_linux_close(struct dpif *dpif_) } static int -dpif_linux_destroy(struct dpif *dpif_) +dpif_netlink_destroy(struct dpif *dpif_) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); - struct dpif_linux_dp dp; + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); + struct dpif_netlink_dp dp; - dpif_linux_dp_init(&dp); + dpif_netlink_dp_init(&dp); dp.cmd = OVS_DP_CMD_DEL; dp.dp_ifindex = dpif->dp_ifindex; - return dpif_linux_dp_transact(&dp, NULL, NULL); + return dpif_netlink_dp_transact(&dp, NULL, NULL); } static void -dpif_linux_run(struct dpif *dpif_) +dpif_netlink_run(struct dpif *dpif_) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); if (dpif->refresh_channels) { dpif->refresh_channels = false; fat_rwlock_wrlock(&dpif->upcall_lock); - dpif_linux_refresh_channels(dpif, dpif->n_handlers); + dpif_netlink_refresh_channels(dpif, dpif->n_handlers); fat_rwlock_unlock(&dpif->upcall_lock); } } static int -dpif_linux_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats) +dpif_netlink_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats) { - struct dpif_linux_dp dp; + struct dpif_netlink_dp dp; struct ofpbuf *buf; int error; - error = dpif_linux_dp_get(dpif_, &dp, &buf); + error = dpif_netlink_dp_get(dpif_, &dp, &buf); if (!error) { memset(stats, 0, sizeof *stats); @@ -579,7 +585,7 @@ dpif_linux_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats) } static const char * -get_vport_type(const struct dpif_linux_vport *vport) +get_vport_type(const struct dpif_netlink_vport *vport) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); @@ -643,7 +649,7 @@ netdev_to_ovs_vport_type(const struct netdev *netdev) } static int -dpif_linux_port_add__(struct dpif_linux *dpif, struct netdev *netdev, +dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev, odp_port_t *port_nop) OVS_REQ_WRLOCK(dpif->upcall_lock) { @@ -652,7 +658,7 @@ dpif_linux_port_add__(struct dpif_linux *dpif, struct netdev *netdev, const char *name = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf); const char *type = netdev_get_type(netdev); - struct dpif_linux_vport request, reply; + struct dpif_netlink_vport request, reply; struct ofpbuf *buf; uint64_t options_stub[64 / 8]; struct ofpbuf options; @@ -667,7 +673,7 @@ dpif_linux_port_add__(struct dpif_linux *dpif, struct netdev *netdev, } } - dpif_linux_vport_init(&request); + dpif_netlink_vport_init(&request); request.cmd = OVS_VPORT_CMD_NEW; request.dp_ifindex = dpif->dp_ifindex; request.type = netdev_to_ovs_vport_type(netdev); @@ -681,7 +687,9 @@ dpif_linux_port_add__(struct dpif_linux *dpif, struct netdev *netdev, request.name = name; if (request.type == OVS_VPORT_TYPE_NETDEV) { +#ifndef _WIN32 netdev_linux_ethtool_set_flag(netdev, ETH_FLAG_LRO, "LRO", false); +#endif } tnl_cfg = netdev_get_tunnel_config(netdev); @@ -698,7 +706,7 @@ dpif_linux_port_add__(struct dpif_linux *dpif, struct netdev *netdev, request.n_upcall_pids = socksp ? dpif->n_handlers : 1; request.upcall_pids = upcall_pids; - error = dpif_linux_vport_transact(&request, &reply, &buf); + error = dpif_netlink_vport_transact(&request, &reply, &buf); if (!error) { *port_nop = reply.port_no; } else { @@ -718,11 +726,11 @@ dpif_linux_port_add__(struct dpif_linux *dpif, struct netdev *netdev, dpif_name(&dpif->dpif), name); /* Delete the port. */ - dpif_linux_vport_init(&request); + dpif_netlink_vport_init(&request); request.cmd = OVS_VPORT_CMD_DEL; request.dp_ifindex = dpif->dp_ifindex; request.port_no = *port_nop; - dpif_linux_vport_transact(&request, NULL, NULL); + dpif_netlink_vport_transact(&request, NULL, NULL); vport_del_socksp(socksp, dpif->n_handlers); goto exit; } @@ -737,31 +745,31 @@ exit: } static int -dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, +dpif_netlink_port_add(struct dpif *dpif_, struct netdev *netdev, odp_port_t *port_nop) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); int error; fat_rwlock_wrlock(&dpif->upcall_lock); - error = dpif_linux_port_add__(dpif, netdev, port_nop); + error = dpif_netlink_port_add__(dpif, netdev, port_nop); fat_rwlock_unlock(&dpif->upcall_lock); return error; } static int -dpif_linux_port_del__(struct dpif_linux *dpif, odp_port_t port_no) +dpif_netlink_port_del__(struct dpif_netlink *dpif, odp_port_t port_no) OVS_REQ_WRLOCK(dpif->upcall_lock) { - struct dpif_linux_vport vport; + struct dpif_netlink_vport vport; int error; - dpif_linux_vport_init(&vport); + dpif_netlink_vport_init(&vport); vport.cmd = OVS_VPORT_CMD_DEL; vport.dp_ifindex = dpif->dp_ifindex; vport.port_no = port_no; - error = dpif_linux_vport_transact(&vport, NULL, NULL); + error = dpif_netlink_vport_transact(&vport, NULL, NULL); vport_del_channels(dpif, port_no); @@ -769,34 +777,34 @@ dpif_linux_port_del__(struct dpif_linux *dpif, odp_port_t port_no) } static int -dpif_linux_port_del(struct dpif *dpif_, odp_port_t port_no) +dpif_netlink_port_del(struct dpif *dpif_, odp_port_t port_no) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); int error; fat_rwlock_wrlock(&dpif->upcall_lock); - error = dpif_linux_port_del__(dpif, port_no); + error = dpif_netlink_port_del__(dpif, port_no); fat_rwlock_unlock(&dpif->upcall_lock); return error; } static int -dpif_linux_port_query__(const struct dpif_linux *dpif, odp_port_t port_no, +dpif_netlink_port_query__(const struct dpif_netlink *dpif, odp_port_t port_no, const char *port_name, struct dpif_port *dpif_port) { - struct dpif_linux_vport request; - struct dpif_linux_vport reply; + struct dpif_netlink_vport request; + struct dpif_netlink_vport reply; struct ofpbuf *buf; int error; - dpif_linux_vport_init(&request); + dpif_netlink_vport_init(&request); request.cmd = OVS_VPORT_CMD_GET; request.dp_ifindex = dpif->dp_ifindex; request.port_no = port_no; request.name = port_name; - error = dpif_linux_vport_transact(&request, &reply, &buf); + error = dpif_netlink_vport_transact(&request, &reply, &buf); if (!error) { if (reply.dp_ifindex != request.dp_ifindex) { /* A query by name reported that 'port_name' is in some datapath @@ -813,25 +821,25 @@ dpif_linux_port_query__(const struct dpif_linux *dpif, odp_port_t port_no, } static int -dpif_linux_port_query_by_number(const struct dpif *dpif_, odp_port_t port_no, +dpif_netlink_port_query_by_number(const struct dpif *dpif_, odp_port_t port_no, struct dpif_port *dpif_port) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); - return dpif_linux_port_query__(dpif, port_no, NULL, dpif_port); + return dpif_netlink_port_query__(dpif, port_no, NULL, dpif_port); } static int -dpif_linux_port_query_by_name(const struct dpif *dpif_, const char *devname, +dpif_netlink_port_query_by_name(const struct dpif *dpif_, const char *devname, struct dpif_port *dpif_port) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); - return dpif_linux_port_query__(dpif, 0, devname, dpif_port); + return dpif_netlink_port_query__(dpif, 0, devname, dpif_port); } static uint32_t -dpif_linux_port_get_pid__(const struct dpif_linux *dpif, odp_port_t port_no, +dpif_netlink_port_get_pid__(const struct dpif_netlink *dpif, odp_port_t port_no, uint32_t hash) OVS_REQ_RDLOCK(dpif->upcall_lock) { @@ -857,69 +865,69 @@ dpif_linux_port_get_pid__(const struct dpif_linux *dpif, odp_port_t port_no, } static uint32_t -dpif_linux_port_get_pid(const struct dpif *dpif_, odp_port_t port_no, +dpif_netlink_port_get_pid(const struct dpif *dpif_, odp_port_t port_no, uint32_t hash) { - const struct dpif_linux *dpif = dpif_linux_cast(dpif_); + const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); uint32_t ret; fat_rwlock_rdlock(&dpif->upcall_lock); - ret = dpif_linux_port_get_pid__(dpif, port_no, hash); + ret = dpif_netlink_port_get_pid__(dpif, port_no, hash); fat_rwlock_unlock(&dpif->upcall_lock); return ret; } static int -dpif_linux_flow_flush(struct dpif *dpif_) +dpif_netlink_flow_flush(struct dpif *dpif_) { - const struct dpif_linux *dpif = dpif_linux_cast(dpif_); - struct dpif_linux_flow flow; + const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); + struct dpif_netlink_flow flow; - dpif_linux_flow_init(&flow); + dpif_netlink_flow_init(&flow); flow.cmd = OVS_FLOW_CMD_DEL; flow.dp_ifindex = dpif->dp_ifindex; - return dpif_linux_flow_transact(&flow, NULL, NULL); + return dpif_netlink_flow_transact(&flow, NULL, NULL); } -struct dpif_linux_port_state { +struct dpif_netlink_port_state { struct nl_dump dump; struct ofpbuf buf; }; static void -dpif_linux_port_dump_start__(const struct dpif_linux *dpif, +dpif_netlink_port_dump_start__(const struct dpif_netlink *dpif, struct nl_dump *dump) { - struct dpif_linux_vport request; + struct dpif_netlink_vport request; struct ofpbuf *buf; - dpif_linux_vport_init(&request); + dpif_netlink_vport_init(&request); request.cmd = OVS_VPORT_CMD_GET; request.dp_ifindex = dpif->dp_ifindex; buf = ofpbuf_new(1024); - dpif_linux_vport_to_ofpbuf(&request, buf); + dpif_netlink_vport_to_ofpbuf(&request, buf); nl_dump_start(dump, NETLINK_GENERIC, buf); ofpbuf_delete(buf); } static int -dpif_linux_port_dump_start(const struct dpif *dpif_, void **statep) +dpif_netlink_port_dump_start(const struct dpif *dpif_, void **statep) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); - struct dpif_linux_port_state *state; + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); + struct dpif_netlink_port_state *state; *statep = state = xmalloc(sizeof *state); - dpif_linux_port_dump_start__(dpif, &state->dump); + dpif_netlink_port_dump_start__(dpif, &state->dump); ofpbuf_init(&state->buf, NL_DUMP_BUFSIZE); return 0; } static int -dpif_linux_port_dump_next__(const struct dpif_linux *dpif, struct nl_dump *dump, - struct dpif_linux_vport *vport, +dpif_netlink_port_dump_next__(const struct dpif_netlink *dpif, struct nl_dump *dump, + struct dpif_netlink_vport *vport, struct ofpbuf *buffer) { struct ofpbuf buf; @@ -929,7 +937,7 @@ dpif_linux_port_dump_next__(const struct dpif_linux *dpif, struct nl_dump *dump, return EOF; } - error = dpif_linux_vport_from_ofpbuf(vport, &buf); + error = dpif_netlink_vport_from_ofpbuf(vport, &buf); if (error) { VLOG_WARN_RL(&error_rl, "%s: failed to parse vport record (%s)", dpif_name(&dpif->dpif), ovs_strerror(error)); @@ -938,15 +946,15 @@ dpif_linux_port_dump_next__(const struct dpif_linux *dpif, struct nl_dump *dump, } static int -dpif_linux_port_dump_next(const struct dpif *dpif_, void *state_, +dpif_netlink_port_dump_next(const struct dpif *dpif_, void *state_, struct dpif_port *dpif_port) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); - struct dpif_linux_port_state *state = state_; - struct dpif_linux_vport vport; + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); + struct dpif_netlink_port_state *state = state_; + struct dpif_netlink_vport vport; int error; - error = dpif_linux_port_dump_next__(dpif, &state->dump, &vport, + error = dpif_netlink_port_dump_next__(dpif, &state->dump, &vport, &state->buf); if (error) { return error; @@ -958,9 +966,9 @@ dpif_linux_port_dump_next(const struct dpif *dpif_, void *state_, } static int -dpif_linux_port_dump_done(const struct dpif *dpif_ OVS_UNUSED, void *state_) +dpif_netlink_port_dump_done(const struct dpif *dpif_ OVS_UNUSED, void *state_) { - struct dpif_linux_port_state *state = state_; + struct dpif_netlink_port_state *state = state_; int error = nl_dump_done(&state->dump); ofpbuf_uninit(&state->buf); @@ -969,9 +977,9 @@ dpif_linux_port_dump_done(const struct dpif *dpif_ OVS_UNUSED, void *state_) } static int -dpif_linux_port_poll(const struct dpif *dpif_, char **devnamep) +dpif_netlink_port_poll(const struct dpif *dpif_, char **devnamep) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); /* Lazily create the Netlink socket to listen for notifications. */ if (!dpif->port_notifier) { @@ -1004,9 +1012,9 @@ dpif_linux_port_poll(const struct dpif *dpif_, char **devnamep) ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub); error = nl_sock_recv(dpif->port_notifier, &buf, false); if (!error) { - struct dpif_linux_vport vport; + struct dpif_netlink_vport vport; - error = dpif_linux_vport_from_ofpbuf(&vport, &buf); + error = dpif_netlink_vport_from_ofpbuf(&vport, &buf); if (!error) { if (vport.dp_ifindex == dpif->dp_ifindex && (vport.cmd == OVS_VPORT_CMD_NEW @@ -1037,9 +1045,9 @@ dpif_linux_port_poll(const struct dpif *dpif_, char **devnamep) } static void -dpif_linux_port_poll_wait(const struct dpif *dpif_) +dpif_netlink_port_poll_wait(const struct dpif *dpif_) { - const struct dpif_linux *dpif = dpif_linux_cast(dpif_); + const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); if (dpif->port_notifier) { nl_sock_wait(dpif->port_notifier, POLLIN); @@ -1049,11 +1057,11 @@ dpif_linux_port_poll_wait(const struct dpif *dpif_) } static void -dpif_linux_init_flow_get(const struct dpif_linux *dpif, +dpif_netlink_init_flow_get(const struct dpif_netlink *dpif, const struct nlattr *key, size_t key_len, - struct dpif_linux_flow *request) + struct dpif_netlink_flow *request) { - dpif_linux_flow_init(request); + dpif_netlink_flow_init(request); request->cmd = OVS_FLOW_CMD_GET; request->dp_ifindex = dpif->dp_ifindex; request->key = key; @@ -1061,23 +1069,23 @@ dpif_linux_init_flow_get(const struct dpif_linux *dpif, } static int -dpif_linux_flow_get(const struct dpif_linux *dpif, +dpif_netlink_flow_get(const struct dpif_netlink *dpif, const struct nlattr *key, size_t key_len, - struct dpif_linux_flow *reply, struct ofpbuf **bufp) + struct dpif_netlink_flow *reply, struct ofpbuf **bufp) { - struct dpif_linux_flow request; + struct dpif_netlink_flow request; - dpif_linux_init_flow_get(dpif, key, key_len, &request); - return dpif_linux_flow_transact(&request, reply, bufp); + dpif_netlink_init_flow_get(dpif, key, key_len, &request); + return dpif_netlink_flow_transact(&request, reply, bufp); } static void -dpif_linux_init_flow_put(struct dpif_linux *dpif, const struct dpif_flow_put *put, - struct dpif_linux_flow *request) +dpif_netlink_init_flow_put(struct dpif_netlink *dpif, const struct dpif_flow_put *put, + struct dpif_netlink_flow *request) { static const struct nlattr dummy_action; - dpif_linux_flow_init(request); + dpif_netlink_flow_init(request); request->cmd = (put->flags & DPIF_FP_CREATE ? OVS_FLOW_CMD_NEW : OVS_FLOW_CMD_SET); request->dp_ifindex = dpif->dp_ifindex; @@ -1097,45 +1105,45 @@ dpif_linux_init_flow_put(struct dpif_linux *dpif, const struct dpif_flow_put *pu } static void -dpif_linux_init_flow_del(struct dpif_linux *dpif, const struct dpif_flow_del *del, - struct dpif_linux_flow *request) +dpif_netlink_init_flow_del(struct dpif_netlink *dpif, const struct dpif_flow_del *del, + struct dpif_netlink_flow *request) { - dpif_linux_flow_init(request); + dpif_netlink_flow_init(request); request->cmd = OVS_FLOW_CMD_DEL; request->dp_ifindex = dpif->dp_ifindex; request->key = del->key; request->key_len = del->key_len; } -struct dpif_linux_flow_dump { +struct dpif_netlink_flow_dump { struct dpif_flow_dump up; struct nl_dump nl_dump; atomic_int status; }; -static struct dpif_linux_flow_dump * -dpif_linux_flow_dump_cast(struct dpif_flow_dump *dump) +static struct dpif_netlink_flow_dump * +dpif_netlink_flow_dump_cast(struct dpif_flow_dump *dump) { - return CONTAINER_OF(dump, struct dpif_linux_flow_dump, up); + return CONTAINER_OF(dump, struct dpif_netlink_flow_dump, up); } static struct dpif_flow_dump * -dpif_linux_flow_dump_create(const struct dpif *dpif_) +dpif_netlink_flow_dump_create(const struct dpif *dpif_) { - const struct dpif_linux *dpif = dpif_linux_cast(dpif_); - struct dpif_linux_flow_dump *dump; - struct dpif_linux_flow request; + const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); + struct dpif_netlink_flow_dump *dump; + struct dpif_netlink_flow request; struct ofpbuf *buf; dump = xmalloc(sizeof *dump); dpif_flow_dump_init(&dump->up, dpif_); - dpif_linux_flow_init(&request); + dpif_netlink_flow_init(&request); request.cmd = OVS_FLOW_CMD_GET; request.dp_ifindex = dpif->dp_ifindex; buf = ofpbuf_new(1024); - dpif_linux_flow_to_ofpbuf(&request, buf); + dpif_netlink_flow_to_ofpbuf(&request, buf); nl_dump_start(&dump->nl_dump, NETLINK_GENERIC, buf); ofpbuf_delete(buf); atomic_init(&dump->status, 0); @@ -1144,9 +1152,9 @@ dpif_linux_flow_dump_create(const struct dpif *dpif_) } static int -dpif_linux_flow_dump_destroy(struct dpif_flow_dump *dump_) +dpif_netlink_flow_dump_destroy(struct dpif_flow_dump *dump_) { - struct dpif_linux_flow_dump *dump = dpif_linux_flow_dump_cast(dump_); + struct dpif_netlink_flow_dump *dump = dpif_netlink_flow_dump_cast(dump_); unsigned int nl_status = nl_dump_done(&dump->nl_dump); int dump_status; @@ -1155,26 +1163,26 @@ dpif_linux_flow_dump_destroy(struct dpif_flow_dump *dump_) return dump_status ? dump_status : nl_status; } -struct dpif_linux_flow_dump_thread { +struct dpif_netlink_flow_dump_thread { struct dpif_flow_dump_thread up; - struct dpif_linux_flow_dump *dump; - struct dpif_linux_flow flow; + struct dpif_netlink_flow_dump *dump; + struct dpif_netlink_flow flow; struct dpif_flow_stats stats; struct ofpbuf nl_flows; /* Always used to store flows. */ struct ofpbuf *nl_actions; /* Used if kernel does not supply actions. */ }; -static struct dpif_linux_flow_dump_thread * -dpif_linux_flow_dump_thread_cast(struct dpif_flow_dump_thread *thread) +static struct dpif_netlink_flow_dump_thread * +dpif_netlink_flow_dump_thread_cast(struct dpif_flow_dump_thread *thread) { - return CONTAINER_OF(thread, struct dpif_linux_flow_dump_thread, up); + return CONTAINER_OF(thread, struct dpif_netlink_flow_dump_thread, up); } static struct dpif_flow_dump_thread * -dpif_linux_flow_dump_thread_create(struct dpif_flow_dump *dump_) +dpif_netlink_flow_dump_thread_create(struct dpif_flow_dump *dump_) { - struct dpif_linux_flow_dump *dump = dpif_linux_flow_dump_cast(dump_); - struct dpif_linux_flow_dump_thread *thread; + struct dpif_netlink_flow_dump *dump = dpif_netlink_flow_dump_cast(dump_); + struct dpif_netlink_flow_dump_thread *thread; thread = xmalloc(sizeof *thread); dpif_flow_dump_thread_init(&thread->up, &dump->up); @@ -1186,10 +1194,10 @@ dpif_linux_flow_dump_thread_create(struct dpif_flow_dump *dump_) } static void -dpif_linux_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread_) +dpif_netlink_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread_) { - struct dpif_linux_flow_dump_thread *thread - = dpif_linux_flow_dump_thread_cast(thread_); + struct dpif_netlink_flow_dump_thread *thread + = dpif_netlink_flow_dump_thread_cast(thread_); ofpbuf_uninit(&thread->nl_flows); ofpbuf_delete(thread->nl_actions); @@ -1197,8 +1205,8 @@ dpif_linux_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread_) } static void -dpif_linux_flow_to_dpif_flow(struct dpif_flow *dpif_flow, - const struct dpif_linux_flow *linux_flow) +dpif_netlink_flow_to_dpif_flow(struct dpif_flow *dpif_flow, + const struct dpif_netlink_flow *linux_flow) { dpif_flow->key = linux_flow->key; dpif_flow->key_len = linux_flow->key_len; @@ -1206,17 +1214,17 @@ dpif_linux_flow_to_dpif_flow(struct dpif_flow *dpif_flow, dpif_flow->mask_len = linux_flow->mask_len; dpif_flow->actions = linux_flow->actions; dpif_flow->actions_len = linux_flow->actions_len; - dpif_linux_flow_get_stats(linux_flow, &dpif_flow->stats); + dpif_netlink_flow_get_stats(linux_flow, &dpif_flow->stats); } static int -dpif_linux_flow_dump_next(struct dpif_flow_dump_thread *thread_, +dpif_netlink_flow_dump_next(struct dpif_flow_dump_thread *thread_, struct dpif_flow *flows, int max_flows) { - struct dpif_linux_flow_dump_thread *thread - = dpif_linux_flow_dump_thread_cast(thread_); - struct dpif_linux_flow_dump *dump = thread->dump; - struct dpif_linux *dpif = dpif_linux_cast(thread->up.dpif); + struct dpif_netlink_flow_dump_thread *thread + = dpif_netlink_flow_dump_thread_cast(thread_); + struct dpif_netlink_flow_dump *dump = thread->dump; + struct dpif_netlink *dpif = dpif_netlink_cast(thread->up.dpif); int n_flows; ofpbuf_delete(thread->nl_actions); @@ -1225,7 +1233,7 @@ dpif_linux_flow_dump_next(struct dpif_flow_dump_thread *thread_, n_flows = 0; while (!n_flows || (n_flows < max_flows && ofpbuf_size(&thread->nl_flows))) { - struct dpif_linux_flow linux_flow; + struct dpif_netlink_flow linux_flow; struct ofpbuf nl_flow; int error; @@ -1235,7 +1243,7 @@ dpif_linux_flow_dump_next(struct dpif_flow_dump_thread *thread_, } /* Convert the flow to our output format. */ - error = dpif_linux_flow_from_ofpbuf(&linux_flow, &nl_flow); + error = dpif_netlink_flow_from_ofpbuf(&linux_flow, &nl_flow); if (error) { atomic_store(&dump->status, error); break; @@ -1243,11 +1251,11 @@ dpif_linux_flow_dump_next(struct dpif_flow_dump_thread *thread_, if (linux_flow.actions) { /* Common case: the flow includes actions. */ - dpif_linux_flow_to_dpif_flow(&flows[n_flows++], &linux_flow); + dpif_netlink_flow_to_dpif_flow(&flows[n_flows++], &linux_flow); } else { /* Rare case: the flow does not include actions. Retrieve this * individual flow again to get the actions. */ - error = dpif_linux_flow_get(dpif, linux_flow.key, + error = dpif_netlink_flow_get(dpif, linux_flow.key, linux_flow.key_len, &linux_flow, &thread->nl_actions); if (error == ENOENT) { @@ -1262,7 +1270,7 @@ dpif_linux_flow_dump_next(struct dpif_flow_dump_thread *thread_, /* Save this flow. Then exit, because we only have one buffer to * handle this case. */ - dpif_linux_flow_to_dpif_flow(&flows[n_flows++], &linux_flow); + dpif_netlink_flow_to_dpif_flow(&flows[n_flows++], &linux_flow); break; } } @@ -1270,7 +1278,7 @@ dpif_linux_flow_dump_next(struct dpif_flow_dump_thread *thread_, } static void -dpif_linux_encode_execute(int dp_ifindex, const struct dpif_execute *d_exec, +dpif_netlink_encode_execute(int dp_ifindex, const struct dpif_execute *d_exec, struct ofpbuf *buf) { struct ovs_header *k_exec; @@ -1302,7 +1310,7 @@ dpif_linux_encode_execute(int dp_ifindex, const struct dpif_execute *d_exec, #define MAX_OPS 50 static void -dpif_linux_operate__(struct dpif_linux *dpif, +dpif_netlink_operate__(struct dpif_netlink *dpif, struct dpif_op **ops, size_t n_ops) { struct op_auxdata { @@ -1326,7 +1334,7 @@ dpif_linux_operate__(struct dpif_linux *dpif, struct dpif_flow_del *del; struct dpif_execute *execute; struct dpif_flow_get *get; - struct dpif_linux_flow flow; + struct dpif_netlink_flow flow; ofpbuf_use_stub(&aux->request, aux->request_stub, sizeof aux->request_stub); @@ -1338,35 +1346,35 @@ dpif_linux_operate__(struct dpif_linux *dpif, switch (op->type) { case DPIF_OP_FLOW_PUT: put = &op->u.flow_put; - dpif_linux_init_flow_put(dpif, put, &flow); + dpif_netlink_init_flow_put(dpif, put, &flow); if (put->stats) { flow.nlmsg_flags |= NLM_F_ECHO; aux->txn.reply = &aux->reply; } - dpif_linux_flow_to_ofpbuf(&flow, &aux->request); + dpif_netlink_flow_to_ofpbuf(&flow, &aux->request); break; case DPIF_OP_FLOW_DEL: del = &op->u.flow_del; - dpif_linux_init_flow_del(dpif, del, &flow); + dpif_netlink_init_flow_del(dpif, del, &flow); if (del->stats) { flow.nlmsg_flags |= NLM_F_ECHO; aux->txn.reply = &aux->reply; } - dpif_linux_flow_to_ofpbuf(&flow, &aux->request); + dpif_netlink_flow_to_ofpbuf(&flow, &aux->request); break; case DPIF_OP_EXECUTE: execute = &op->u.execute; - dpif_linux_encode_execute(dpif->dp_ifindex, execute, + dpif_netlink_encode_execute(dpif->dp_ifindex, execute, &aux->request); break; case DPIF_OP_FLOW_GET: get = &op->u.flow_get; - dpif_linux_init_flow_get(dpif, get->key, get->key_len, &flow); + dpif_netlink_init_flow_get(dpif, get->key, get->key_len, &flow); aux->txn.reply = get->buffer; - dpif_linux_flow_to_ofpbuf(&flow, &aux->request); + dpif_netlink_flow_to_ofpbuf(&flow, &aux->request); break; default: @@ -1394,12 +1402,12 @@ dpif_linux_operate__(struct dpif_linux *dpif, put = &op->u.flow_put; if (put->stats) { if (!op->error) { - struct dpif_linux_flow reply; + struct dpif_netlink_flow reply; - op->error = dpif_linux_flow_from_ofpbuf(&reply, + op->error = dpif_netlink_flow_from_ofpbuf(&reply, txn->reply); if (!op->error) { - dpif_linux_flow_get_stats(&reply, put->stats); + dpif_netlink_flow_get_stats(&reply, put->stats); } } } @@ -1409,12 +1417,12 @@ dpif_linux_operate__(struct dpif_linux *dpif, del = &op->u.flow_del; if (del->stats) { if (!op->error) { - struct dpif_linux_flow reply; + struct dpif_netlink_flow reply; - op->error = dpif_linux_flow_from_ofpbuf(&reply, + op->error = dpif_netlink_flow_from_ofpbuf(&reply, txn->reply); if (!op->error) { - dpif_linux_flow_get_stats(&reply, del->stats); + dpif_netlink_flow_get_stats(&reply, del->stats); } } } @@ -1426,11 +1434,11 @@ dpif_linux_operate__(struct dpif_linux *dpif, case DPIF_OP_FLOW_GET: get = &op->u.flow_get; if (!op->error) { - struct dpif_linux_flow reply; + struct dpif_netlink_flow reply; - op->error = dpif_linux_flow_from_ofpbuf(&reply, txn->reply); + op->error = dpif_netlink_flow_from_ofpbuf(&reply, txn->reply); if (!op->error) { - dpif_linux_flow_to_dpif_flow(get->flow, &reply); + dpif_netlink_flow_to_dpif_flow(get->flow, &reply); } } break; @@ -1445,13 +1453,13 @@ dpif_linux_operate__(struct dpif_linux *dpif, } static void -dpif_linux_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops) +dpif_netlink_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); while (n_ops > 0) { size_t chunk = MIN(n_ops, MAX_OPS); - dpif_linux_operate__(dpif, ops, chunk); + dpif_netlink_operate__(dpif, ops, chunk); ops += chunk; n_ops -= chunk; } @@ -1462,11 +1470,11 @@ dpif_linux_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops) * any kernel vport that lacks one and deleting any channels that have no * backing kernel vports. */ static int -dpif_linux_refresh_channels(struct dpif_linux *dpif, uint32_t n_handlers) +dpif_netlink_refresh_channels(struct dpif_netlink *dpif, uint32_t n_handlers) OVS_REQ_WRLOCK(dpif->upcall_lock) { unsigned long int *keep_channels; - struct dpif_linux_vport vport; + struct dpif_netlink_vport vport; size_t keep_channels_nbits; struct nl_dump dump; uint64_t reply_stub[NL_DUMP_BUFSIZE / 8]; @@ -1480,7 +1488,11 @@ dpif_linux_refresh_channels(struct dpif_linux *dpif, uint32_t n_handlers) for (i = 0; i < n_handlers; i++) { struct dpif_handler *handler = &dpif->handlers[i]; +#ifndef _WIN32 handler->epoll_fd = epoll_create(10); +#else + handler->epoll_fd = 0; +#endif if (handler->epoll_fd < 0) { size_t j; @@ -1506,8 +1518,8 @@ dpif_linux_refresh_channels(struct dpif_linux *dpif, uint32_t n_handlers) keep_channels = bitmap_allocate(keep_channels_nbits); ofpbuf_use_stub(&buf, reply_stub, sizeof reply_stub); - dpif_linux_port_dump_start__(dpif, &dump); - while (!dpif_linux_port_dump_next__(dpif, &dump, &vport, &buf)) { + dpif_netlink_port_dump_start__(dpif, &dump); + while (!dpif_netlink_port_dump_next__(dpif, &dump, &vport, &buf)) { uint32_t port_no = odp_to_u32(vport.port_no); uint32_t *upcall_pids = NULL; int error; @@ -1538,15 +1550,15 @@ dpif_linux_refresh_channels(struct dpif_linux *dpif, uint32_t n_handlers) || vport.n_upcall_pids != dpif->n_handlers || memcmp(upcall_pids, vport.upcall_pids, n_handlers * sizeof *upcall_pids)) { - struct dpif_linux_vport vport_request; + struct dpif_netlink_vport vport_request; - dpif_linux_vport_init(&vport_request); + dpif_netlink_vport_init(&vport_request); vport_request.cmd = OVS_VPORT_CMD_SET; vport_request.dp_ifindex = dpif->dp_ifindex; vport_request.port_no = vport.port_no; vport_request.n_upcall_pids = dpif->n_handlers; vport_request.upcall_pids = upcall_pids; - error = dpif_linux_vport_transact(&vport_request, NULL, NULL); + error = dpif_netlink_vport_transact(&vport_request, NULL, NULL); if (error) { VLOG_WARN_RL(&error_rl, "%s: failed to set upcall pid on port: %s", @@ -1588,7 +1600,7 @@ dpif_linux_refresh_channels(struct dpif_linux *dpif, uint32_t n_handlers) } static int -dpif_linux_recv_set__(struct dpif_linux *dpif, bool enable) +dpif_netlink_recv_set__(struct dpif_netlink *dpif, bool enable) OVS_REQ_WRLOCK(dpif->upcall_lock) { if ((dpif->handlers != NULL) == enable) { @@ -1597,32 +1609,32 @@ dpif_linux_recv_set__(struct dpif_linux *dpif, bool enable) destroy_all_channels(dpif); return 0; } else { - return dpif_linux_refresh_channels(dpif, 1); + return dpif_netlink_refresh_channels(dpif, 1); } } static int -dpif_linux_recv_set(struct dpif *dpif_, bool enable) +dpif_netlink_recv_set(struct dpif *dpif_, bool enable) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); int error; fat_rwlock_wrlock(&dpif->upcall_lock); - error = dpif_linux_recv_set__(dpif, enable); + error = dpif_netlink_recv_set__(dpif, enable); fat_rwlock_unlock(&dpif->upcall_lock); return error; } static int -dpif_linux_handlers_set(struct dpif *dpif_, uint32_t n_handlers) +dpif_netlink_handlers_set(struct dpif *dpif_, uint32_t n_handlers) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); int error = 0; fat_rwlock_wrlock(&dpif->upcall_lock); if (dpif->handlers) { - error = dpif_linux_refresh_channels(dpif, n_handlers); + error = dpif_netlink_refresh_channels(dpif, n_handlers); } fat_rwlock_unlock(&dpif->upcall_lock); @@ -1630,7 +1642,7 @@ dpif_linux_handlers_set(struct dpif *dpif_, uint32_t n_handlers) } static int -dpif_linux_queue_to_priority(const struct dpif *dpif OVS_UNUSED, +dpif_netlink_queue_to_priority(const struct dpif *dpif OVS_UNUSED, uint32_t queue_id, uint32_t *priority) { if (queue_id < 0xf000) { @@ -1706,7 +1718,7 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall, } static int -dpif_linux_recv__(struct dpif_linux *dpif, uint32_t handler_id, +dpif_netlink_recv__(struct dpif_netlink *dpif, uint32_t handler_id, struct dpif_upcall *upcall, struct ofpbuf *buf) OVS_REQ_RDLOCK(dpif->upcall_lock) { @@ -1724,8 +1736,13 @@ dpif_linux_recv__(struct dpif_linux *dpif, uint32_t handler_id, handler->event_offset = handler->n_events = 0; do { +#ifndef _WIN32 retval = epoll_wait(handler->epoll_fd, handler->epoll_events, dpif->uc_array_size, 0); +#else + retval = dpif->uc_array_size; + handler->event_offset = 0; +#endif } while (retval < 0 && errno == EINTR); if (retval < 0) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); @@ -1750,6 +1767,14 @@ dpif_linux_recv__(struct dpif_linux *dpif, uint32_t handler_id, } error = nl_sock_recv(ch->sock, buf, false); +#ifdef _WIN32 + DWORD bytes; + LPOVERLAPPED overlap = nl_sock_overlapped(ch->sock); + + if (overlap->Internal == STATUS_PENDING) { + GetOverlappedResult(nl_sock_fd(ch->sock), overlap, &bytes, TRUE); + } +#endif if (error == ENOBUFS) { /* ENOBUFS typically means that we've received so many * packets that the buffer overflowed. Try again @@ -1780,21 +1805,21 @@ dpif_linux_recv__(struct dpif_linux *dpif, uint32_t handler_id, } static int -dpif_linux_recv(struct dpif *dpif_, uint32_t handler_id, +dpif_netlink_recv(struct dpif *dpif_, uint32_t handler_id, struct dpif_upcall *upcall, struct ofpbuf *buf) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); int error; fat_rwlock_rdlock(&dpif->upcall_lock); - error = dpif_linux_recv__(dpif, handler_id, upcall, buf); + error = dpif_netlink_recv__(dpif, handler_id, upcall, buf); fat_rwlock_unlock(&dpif->upcall_lock); return error; } static void -dpif_linux_recv_wait__(struct dpif_linux *dpif, uint32_t handler_id) +dpif_netlink_recv_wait__(struct dpif_netlink *dpif, uint32_t handler_id) OVS_REQ_RDLOCK(dpif->upcall_lock) { if (dpif->handlers && handler_id < dpif->n_handlers) { @@ -1805,17 +1830,17 @@ dpif_linux_recv_wait__(struct dpif_linux *dpif, uint32_t handler_id) } static void -dpif_linux_recv_wait(struct dpif *dpif_, uint32_t handler_id) +dpif_netlink_recv_wait(struct dpif *dpif_, uint32_t handler_id) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); fat_rwlock_rdlock(&dpif->upcall_lock); - dpif_linux_recv_wait__(dpif, handler_id); + dpif_netlink_recv_wait__(dpif, handler_id); fat_rwlock_unlock(&dpif->upcall_lock); } static void -dpif_linux_recv_purge__(struct dpif_linux *dpif) +dpif_netlink_recv_purge__(struct dpif_netlink *dpif) OVS_REQ_WRLOCK(dpif->upcall_lock) { if (dpif->handlers) { @@ -1834,55 +1859,55 @@ dpif_linux_recv_purge__(struct dpif_linux *dpif) } static void -dpif_linux_recv_purge(struct dpif *dpif_) +dpif_netlink_recv_purge(struct dpif *dpif_) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); fat_rwlock_wrlock(&dpif->upcall_lock); - dpif_linux_recv_purge__(dpif); + dpif_netlink_recv_purge__(dpif); fat_rwlock_unlock(&dpif->upcall_lock); } -const struct dpif_class dpif_linux_class = { +const struct dpif_class dpif_netlink_class = { "system", - dpif_linux_enumerate, + dpif_netlink_enumerate, NULL, - dpif_linux_open, - dpif_linux_close, - dpif_linux_destroy, - dpif_linux_run, + dpif_netlink_open, + dpif_netlink_close, + dpif_netlink_destroy, + dpif_netlink_run, NULL, /* wait */ - dpif_linux_get_stats, - dpif_linux_port_add, - dpif_linux_port_del, - dpif_linux_port_query_by_number, - dpif_linux_port_query_by_name, - dpif_linux_port_get_pid, - dpif_linux_port_dump_start, - dpif_linux_port_dump_next, - dpif_linux_port_dump_done, - dpif_linux_port_poll, - dpif_linux_port_poll_wait, - dpif_linux_flow_flush, - dpif_linux_flow_dump_create, - dpif_linux_flow_dump_destroy, - dpif_linux_flow_dump_thread_create, - dpif_linux_flow_dump_thread_destroy, - dpif_linux_flow_dump_next, - dpif_linux_operate, - dpif_linux_recv_set, - dpif_linux_handlers_set, - dpif_linux_queue_to_priority, - dpif_linux_recv, - dpif_linux_recv_wait, - dpif_linux_recv_purge, + dpif_netlink_get_stats, + dpif_netlink_port_add, + dpif_netlink_port_del, + dpif_netlink_port_query_by_number, + dpif_netlink_port_query_by_name, + dpif_netlink_port_get_pid, + dpif_netlink_port_dump_start, + dpif_netlink_port_dump_next, + dpif_netlink_port_dump_done, + dpif_netlink_port_poll, + dpif_netlink_port_poll_wait, + dpif_netlink_flow_flush, + dpif_netlink_flow_dump_create, + dpif_netlink_flow_dump_destroy, + dpif_netlink_flow_dump_thread_create, + dpif_netlink_flow_dump_thread_destroy, + dpif_netlink_flow_dump_next, + dpif_netlink_operate, + dpif_netlink_recv_set, + dpif_netlink_handlers_set, + dpif_netlink_queue_to_priority, + dpif_netlink_recv, + dpif_netlink_recv_wait, + dpif_netlink_recv_purge, NULL, /* register_upcall_cb */ NULL, /* enable_upcall */ NULL, /* disable_upcall */ }; static int -dpif_linux_init(void) +dpif_netlink_init(void) { static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; static int error; @@ -1917,13 +1942,13 @@ dpif_linux_init(void) } bool -dpif_linux_is_internal_device(const char *name) +dpif_netlink_is_internal_device(const char *name) { - struct dpif_linux_vport reply; + struct dpif_netlink_vport reply; struct ofpbuf *buf; int error; - error = dpif_linux_vport_get(name, &reply, &buf); + error = dpif_netlink_vport_get(name, &reply, &buf); if (!error) { ofpbuf_delete(buf); } else if (error != ENODEV && error != ENOENT) { @@ -1941,7 +1966,7 @@ dpif_linux_is_internal_device(const char *name) * 'vport' will contain pointers into 'buf', so the caller should not free * 'buf' while 'vport' is still in use. */ static int -dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport, +dpif_netlink_vport_from_ofpbuf(struct dpif_netlink_vport *vport, const struct ofpbuf *buf) { static const struct nl_policy ovs_vport_policy[] = { @@ -1960,7 +1985,7 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport, struct genlmsghdr *genl; struct ofpbuf b; - dpif_linux_vport_init(vport); + dpif_netlink_vport_init(vport); ofpbuf_use_const(&b, ofpbuf_data(buf), ofpbuf_size(buf)); nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); @@ -1997,7 +2022,7 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport, /* Appends to 'buf' (which must initially be empty) a "struct ovs_header" * followed by Netlink attributes corresponding to 'vport'. */ static void -dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *vport, +dpif_netlink_vport_to_ofpbuf(const struct dpif_netlink_vport *vport, struct ofpbuf *buf) { struct ovs_header *ovs_header; @@ -2039,7 +2064,7 @@ dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *vport, /* Clears 'vport' to "empty" values. */ void -dpif_linux_vport_init(struct dpif_linux_vport *vport) +dpif_netlink_vport_init(struct dpif_netlink_vport *vport) { memset(vport, 0, sizeof *vport); vport->port_no = ODPP_NONE; @@ -2052,8 +2077,8 @@ dpif_linux_vport_init(struct dpif_linux_vport *vport) * and stored in '*reply' and '*bufp'. The caller must free '*bufp' when the * reply is no longer needed ('reply' will contain pointers into '*bufp'). */ int -dpif_linux_vport_transact(const struct dpif_linux_vport *request, - struct dpif_linux_vport *reply, +dpif_netlink_vport_transact(const struct dpif_netlink_vport *request, + struct dpif_netlink_vport *reply, struct ofpbuf **bufp) { struct ofpbuf *request_buf; @@ -2061,26 +2086,26 @@ dpif_linux_vport_transact(const struct dpif_linux_vport *request, ovs_assert((reply != NULL) == (bufp != NULL)); - error = dpif_linux_init(); + error = dpif_netlink_init(); if (error) { if (reply) { *bufp = NULL; - dpif_linux_vport_init(reply); + dpif_netlink_vport_init(reply); } return error; } request_buf = ofpbuf_new(1024); - dpif_linux_vport_to_ofpbuf(request, request_buf); + dpif_netlink_vport_to_ofpbuf(request, request_buf); error = nl_transact(NETLINK_GENERIC, request_buf, bufp); ofpbuf_delete(request_buf); if (reply) { if (!error) { - error = dpif_linux_vport_from_ofpbuf(reply, *bufp); + error = dpif_netlink_vport_from_ofpbuf(reply, *bufp); } if (error) { - dpif_linux_vport_init(reply); + dpif_netlink_vport_init(reply); ofpbuf_delete(*bufp); *bufp = NULL; } @@ -2092,16 +2117,16 @@ dpif_linux_vport_transact(const struct dpif_linux_vport *request, * '*reply' and '*bufp'. The caller must free '*bufp' when the reply is no * longer needed ('reply' will contain pointers into '*bufp'). */ int -dpif_linux_vport_get(const char *name, struct dpif_linux_vport *reply, +dpif_netlink_vport_get(const char *name, struct dpif_netlink_vport *reply, struct ofpbuf **bufp) { - struct dpif_linux_vport request; + struct dpif_netlink_vport request; - dpif_linux_vport_init(&request); + dpif_netlink_vport_init(&request); request.cmd = OVS_VPORT_CMD_GET; request.name = name; - return dpif_linux_vport_transact(&request, reply, bufp); + return dpif_netlink_vport_transact(&request, reply, bufp); } /* Parses the contents of 'buf', which contains a "struct ovs_header" followed @@ -2111,7 +2136,7 @@ dpif_linux_vport_get(const char *name, struct dpif_linux_vport *reply, * 'dp' will contain pointers into 'buf', so the caller should not free 'buf' * while 'dp' is still in use. */ static int -dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp *dp, const struct ofpbuf *buf) +dpif_netlink_dp_from_ofpbuf(struct dpif_netlink_dp *dp, const struct ofpbuf *buf) { static const struct nl_policy ovs_datapath_policy[] = { [OVS_DP_ATTR_NAME] = { .type = NL_A_STRING, .max_len = IFNAMSIZ }, @@ -2128,7 +2153,7 @@ dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp *dp, const struct ofpbuf *buf) struct genlmsghdr *genl; struct ofpbuf b; - dpif_linux_dp_init(dp); + dpif_netlink_dp_init(dp); ofpbuf_use_const(&b, ofpbuf_data(buf), ofpbuf_size(buf)); nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); @@ -2157,7 +2182,7 @@ dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp *dp, const struct ofpbuf *buf) /* Appends to 'buf' the Generic Netlink message described by 'dp'. */ static void -dpif_linux_dp_to_ofpbuf(const struct dpif_linux_dp *dp, struct ofpbuf *buf) +dpif_netlink_dp_to_ofpbuf(const struct dpif_netlink_dp *dp, struct ofpbuf *buf) { struct ovs_header *ovs_header; @@ -2185,22 +2210,22 @@ dpif_linux_dp_to_ofpbuf(const struct dpif_linux_dp *dp, struct ofpbuf *buf) /* Clears 'dp' to "empty" values. */ static void -dpif_linux_dp_init(struct dpif_linux_dp *dp) +dpif_netlink_dp_init(struct dpif_netlink_dp *dp) { memset(dp, 0, sizeof *dp); } static void -dpif_linux_dp_dump_start(struct nl_dump *dump) +dpif_netlink_dp_dump_start(struct nl_dump *dump) { - struct dpif_linux_dp request; + struct dpif_netlink_dp request; struct ofpbuf *buf; - dpif_linux_dp_init(&request); + dpif_netlink_dp_init(&request); request.cmd = OVS_DP_CMD_GET; buf = ofpbuf_new(1024); - dpif_linux_dp_to_ofpbuf(&request, buf); + dpif_netlink_dp_to_ofpbuf(&request, buf); nl_dump_start(dump, NETLINK_GENERIC, buf); ofpbuf_delete(buf); } @@ -2212,8 +2237,8 @@ dpif_linux_dp_dump_start(struct nl_dump *dump) * and stored in '*reply' and '*bufp'. The caller must free '*bufp' when the * reply is no longer needed ('reply' will contain pointers into '*bufp'). */ static int -dpif_linux_dp_transact(const struct dpif_linux_dp *request, - struct dpif_linux_dp *reply, struct ofpbuf **bufp) +dpif_netlink_dp_transact(const struct dpif_netlink_dp *request, + struct dpif_netlink_dp *reply, struct ofpbuf **bufp) { struct ofpbuf *request_buf; int error; @@ -2221,14 +2246,14 @@ dpif_linux_dp_transact(const struct dpif_linux_dp *request, ovs_assert((reply != NULL) == (bufp != NULL)); request_buf = ofpbuf_new(1024); - dpif_linux_dp_to_ofpbuf(request, request_buf); + dpif_netlink_dp_to_ofpbuf(request, request_buf); error = nl_transact(NETLINK_GENERIC, request_buf, bufp); ofpbuf_delete(request_buf); if (reply) { - dpif_linux_dp_init(reply); + dpif_netlink_dp_init(reply); if (!error) { - error = dpif_linux_dp_from_ofpbuf(reply, *bufp); + error = dpif_netlink_dp_from_ofpbuf(reply, *bufp); } if (error) { ofpbuf_delete(*bufp); @@ -2242,17 +2267,17 @@ dpif_linux_dp_transact(const struct dpif_linux_dp *request, * The caller must free '*bufp' when the reply is no longer needed ('reply' * will contain pointers into '*bufp'). */ static int -dpif_linux_dp_get(const struct dpif *dpif_, struct dpif_linux_dp *reply, +dpif_netlink_dp_get(const struct dpif *dpif_, struct dpif_netlink_dp *reply, struct ofpbuf **bufp) { - struct dpif_linux *dpif = dpif_linux_cast(dpif_); - struct dpif_linux_dp request; + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); + struct dpif_netlink_dp request; - dpif_linux_dp_init(&request); + dpif_netlink_dp_init(&request); request.cmd = OVS_DP_CMD_GET; request.dp_ifindex = dpif->dp_ifindex; - return dpif_linux_dp_transact(&request, reply, bufp); + return dpif_netlink_dp_transact(&request, reply, bufp); } /* Parses the contents of 'buf', which contains a "struct ovs_header" followed @@ -2262,7 +2287,7 @@ dpif_linux_dp_get(const struct dpif *dpif_, struct dpif_linux_dp *reply, * 'flow' will contain pointers into 'buf', so the caller should not free 'buf' * while 'flow' is still in use. */ static int -dpif_linux_flow_from_ofpbuf(struct dpif_linux_flow *flow, +dpif_netlink_flow_from_ofpbuf(struct dpif_netlink_flow *flow, const struct ofpbuf *buf) { static const struct nl_policy ovs_flow_policy[] = { @@ -2282,7 +2307,7 @@ dpif_linux_flow_from_ofpbuf(struct dpif_linux_flow *flow, struct genlmsghdr *genl; struct ofpbuf b; - dpif_linux_flow_init(flow); + dpif_netlink_flow_init(flow); ofpbuf_use_const(&b, ofpbuf_data(buf), ofpbuf_size(buf)); nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); @@ -2323,7 +2348,7 @@ dpif_linux_flow_from_ofpbuf(struct dpif_linux_flow *flow, /* Appends to 'buf' (which must initially be empty) a "struct ovs_header" * followed by Netlink attributes corresponding to 'flow'. */ static void -dpif_linux_flow_to_ofpbuf(const struct dpif_linux_flow *flow, +dpif_netlink_flow_to_ofpbuf(const struct dpif_netlink_flow *flow, struct ofpbuf *buf) { struct ovs_header *ovs_header; @@ -2360,7 +2385,7 @@ dpif_linux_flow_to_ofpbuf(const struct dpif_linux_flow *flow, /* Clears 'flow' to "empty" values. */ static void -dpif_linux_flow_init(struct dpif_linux_flow *flow) +dpif_netlink_flow_init(struct dpif_netlink_flow *flow) { memset(flow, 0, sizeof *flow); } @@ -2372,8 +2397,8 @@ dpif_linux_flow_init(struct dpif_linux_flow *flow) * stored in '*reply' and '*bufp'. The caller must free '*bufp' when the reply * is no longer needed ('reply' will contain pointers into '*bufp'). */ static int -dpif_linux_flow_transact(struct dpif_linux_flow *request, - struct dpif_linux_flow *reply, struct ofpbuf **bufp) +dpif_netlink_flow_transact(struct dpif_netlink_flow *request, + struct dpif_netlink_flow *reply, struct ofpbuf **bufp) { struct ofpbuf *request_buf; int error; @@ -2385,16 +2410,16 @@ dpif_linux_flow_transact(struct dpif_linux_flow *request, } request_buf = ofpbuf_new(1024); - dpif_linux_flow_to_ofpbuf(request, request_buf); + dpif_netlink_flow_to_ofpbuf(request, request_buf); error = nl_transact(NETLINK_GENERIC, request_buf, bufp); ofpbuf_delete(request_buf); if (reply) { if (!error) { - error = dpif_linux_flow_from_ofpbuf(reply, *bufp); + error = dpif_netlink_flow_from_ofpbuf(reply, *bufp); } if (error) { - dpif_linux_flow_init(reply); + dpif_netlink_flow_init(reply); ofpbuf_delete(*bufp); *bufp = NULL; } @@ -2403,7 +2428,7 @@ dpif_linux_flow_transact(struct dpif_linux_flow *request, } static void -dpif_linux_flow_get_stats(const struct dpif_linux_flow *flow, +dpif_netlink_flow_get_stats(const struct dpif_netlink_flow *flow, struct dpif_flow_stats *stats) { if (flow->stats) { @@ -2420,7 +2445,7 @@ dpif_linux_flow_get_stats(const struct dpif_linux_flow *flow, /* Logs information about a packet that was recently lost in 'ch' (in * 'dpif_'). */ static void -report_loss(struct dpif_linux *dpif, struct dpif_channel *ch, uint32_t ch_idx, +report_loss(struct dpif_netlink *dpif, struct dpif_channel *ch, uint32_t ch_idx, uint32_t handler_id) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); diff --git a/lib/dpif-linux.h b/lib/dpif-linux.h index a35826c..4d6b2de 100644 --- a/lib/dpif-linux.h +++ b/lib/dpif-linux.h @@ -26,7 +26,7 @@ struct ofpbuf; -struct dpif_linux_vport { +struct dpif_netlink_vport { /* Generic Netlink header. */ uint8_t cmd; @@ -48,14 +48,14 @@ struct dpif_linux_vport { size_t options_len; }; -void dpif_linux_vport_init(struct dpif_linux_vport *); +void dpif_netlink_vport_init(struct dpif_netlink_vport *); -int dpif_linux_vport_transact(const struct dpif_linux_vport *request, - struct dpif_linux_vport *reply, +int dpif_netlink_vport_transact(const struct dpif_netlink_vport *request, + struct dpif_netlink_vport *reply, struct ofpbuf **bufp); -int dpif_linux_vport_get(const char *name, struct dpif_linux_vport *reply, +int dpif_netlink_vport_get(const char *name, struct dpif_netlink_vport *reply, struct ofpbuf **bufp); -bool dpif_linux_is_internal_device(const char *name); +bool dpif_netlink_is_internal_device(const char *name); #endif /* dpif-linux.h */ diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 89b32dd..3f57049 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -358,7 +358,7 @@ struct dpif_class { void (*disable_upcall)(struct dpif *); }; -extern const struct dpif_class dpif_linux_class; +extern const struct dpif_class dpif_netlink_class; extern const struct dpif_class dpif_netdev_class; #ifdef __cplusplus diff --git a/lib/dpif.c b/lib/dpif.c index b2a1972..6e0f135 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -59,8 +59,8 @@ COVERAGE_DEFINE(dpif_purge); COVERAGE_DEFINE(dpif_execute_with_help); static const struct dpif_class *base_dpif_classes[] = { -#ifdef __linux__ - &dpif_linux_class, +#if defined(__linux__) || defined(_WIN32) + &dpif_netlink_class, #endif &dpif_netdev_class, }; diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c index a6be186..f76b5b2 100644 --- a/lib/netlink-socket.c +++ b/lib/netlink-socket.c @@ -80,6 +80,7 @@ static int get_sock_pid_from_kernel(struct nl_sock *sock); struct nl_sock { #ifdef _WIN32 HANDLE handle; + OVERLAPPED overlapped; #else int fd; #endif @@ -143,7 +144,8 @@ nl_sock_create(int protocol, struct nl_sock **sockp) GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL); int last_error = GetLastError(); @@ -151,6 +153,8 @@ nl_sock_create(int protocol, struct nl_sock **sockp) VLOG_ERR("fcntl: %s", ovs_strerror(last_error)); goto error; } + + memset(&sock->overlapped, 0, sizeof(sock->overlapped)); #else sock->fd = socket(AF_NETLINK, SOCK_RAW, protocol); if (sock->fd < 0) { @@ -522,7 +526,8 @@ nl_sock_recv__(struct nl_sock *sock, struct ofpbuf *buf, bool wait) #ifdef _WIN32 DWORD bytes; if (!DeviceIoControl(sock->handle, OVS_IOCTL_READ, - NULL, 0, tail, sizeof tail, &bytes, NULL)) { + NULL, 0, tail, sizeof tail, &bytes, + &sock->overlapped)) { retval = -1; errno = EINVAL; } else { @@ -1059,7 +1064,11 @@ nl_sock_wait(const struct nl_sock *sock, short int events) * "copy on write" to allow a single nl_sock to be used for notifications, * transactions, and dumps. If 'sock' is used only for notifications and * transactions (and never for dump) then the usage is safe. */ +#ifdef _WIN32 +HANDLE +#else int +#endif nl_sock_fd(const struct nl_sock *sock) { #ifdef _WIN32 @@ -1069,6 +1078,15 @@ nl_sock_fd(const struct nl_sock *sock) #endif } +/* Returns the OVERLAPPED structure associated with this handle. */ +#ifdef _WIN32 +LPOVERLAPPED +nl_sock_overlapped(const struct nl_sock *sock) +{ + return &sock->overlapped; +} +#endif + /* Returns the PID associated with this socket. */ uint32_t nl_sock_pid(const struct nl_sock *sock) diff --git a/lib/netlink-socket.h b/lib/netlink-socket.h index 93dc9c8..9a2972a 100644 --- a/lib/netlink-socket.h +++ b/lib/netlink-socket.h @@ -213,7 +213,12 @@ int nl_sock_recv(struct nl_sock *, struct ofpbuf *, bool wait); int nl_sock_drain(struct nl_sock *); void nl_sock_wait(const struct nl_sock *, short int events); +#ifdef _WIN32 +LPOVERLAPPED nl_sock_overlapped(const struct nl_sock *sock); +HANDLE nl_sock_fd(const struct nl_sock *); +#else int nl_sock_fd(const struct nl_sock *); +#endif uint32_t nl_sock_pid(const struct nl_sock *); -- 1.9.0.msysgit.0 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev