@@ -34,6 +34,10 @@ AM_CFLAGS = -Wstrict-prototypes
AM_CFLAGS += $(WARNING_FLAGS)
AM_CFLAGS += $(OVS_CFLAGS)
+if WIN32
+AM_CFLAGS += -mno-ms-bitfields
+endif
+
if DPDK_NETDEV
AM_CFLAGS += -D_FILE_OFFSET_BITS=64
DPDKSTRIP_FLAGS = --dpdk
@@ -49,7 +53,7 @@ endif
AM_CTAGSFLAGS = $(OVS_CTAGS_IDENTIFIERS_LIST)
if WIN32
-psep=";"
+psep=
else
psep=":"
endif
@@ -20,6 +20,11 @@
#include <stddef.h>
#include <stdbool.h>
+#ifdef _WIN32
+#define __USE_MINGW_ANSI_STDIO 1
+#include <stdio.h>
+#endif
+
#ifndef __has_feature
#define __has_feature(x) 0
#endif
@@ -39,8 +44,13 @@
#if __GNUC__ && !__CHECKER__
#define OVS_UNUSED __attribute__((__unused__))
+#ifdef _WIN32
+#define OVS_PRINTF_FORMAT(FMT, ARG1) __attribute__((__format__(__MINGW_PRINTF_FORMAT, FMT, ARG1)))
+#define OVS_SCANF_FORMAT(FMT, ARG1) __attribute__((__format__(__MINGW_SCANF_FORMAT, FMT, ARG1)))
+#else
#define OVS_PRINTF_FORMAT(FMT, ARG1) __attribute__((__format__(printf, FMT, ARG1)))
#define OVS_SCANF_FORMAT(FMT, ARG1) __attribute__((__format__(scanf, FMT, ARG1)))
+#endif
#define OVS_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#define OVS_LIKELY(CONDITION) __builtin_expect(!!(CONDITION), 1)
#define OVS_UNLIKELY(CONDITION) __builtin_expect(!!(CONDITION), 0)
@@ -17,7 +17,7 @@
#ifndef __NET_IF_H
#define __NET_IF_H 1
-#include <Netioapi.h>
+#include <netioapi.h>
#define IFNAMSIZ IF_NAMESIZE
@@ -86,6 +86,8 @@ struct icmp6_hdr {
#define icmp6_seq icmp6_data16[1] /* echo request/reply */
#define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */
+#include <iprtrmib.h>
+#if 0
#define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */
#define ICMP6_PACKET_TOO_BIG 2 /* packet too big */
#define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */
@@ -93,6 +95,8 @@ struct icmp6_hdr {
#define ICMP6_ECHO_REQUEST 128 /* echo service */
#define ICMP6_ECHO_REPLY 129 /* echo reply */
+#endif
+
#define MLD_LISTENER_QUERY 130 /* multicast listener query */
#define MLD_LISTENER_REPORT 131 /* multicast listener report */
#define MLD_LISTENER_DONE 132 /* multicast listener done */
@@ -17,15 +17,21 @@
#ifndef WINDEFS_H
#define WINDEFS_H 1
-#include <Winsock2.h>
-#include <In6addr.h>
-#include <WS2tcpip.h>
+#define _WIN32_WINNT 0x600 /* Windows Visa above */
+
+#define __USE_MINGW_ANSI_STDIO 1
+
+#include <winsock2.h>
+#include <in6addr.h>
+#include <ws2tcpip.h>
#include <windows.h>
-#include <BaseTsd.h>
+#include <basetsd.h>
+#include <shlwapi.h>
#include <io.h>
#include <inttypes.h>
+#include <sys/types.h>
-#pragma comment(lib, "advapi32")
+//#pragma comment(lib, "advapi32")
#undef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
@@ -38,7 +44,7 @@
#define u_int32_t uint32_t
#define u_int64_t uint64_t
-typedef int pid_t;
+//typedef int pid_t;
char *strsep(char **stringp, const char *delim);
@@ -22,6 +22,22 @@
#include <inttypes.h>
#include "openvswitch/types.h"
+#ifdef _WIN32
+static unsigned __int64 ntohll(
+ unsigned __int64 n
+ )
+{
+ return htonl(1) == 1 ? n : ((uint64_t) ntohl(n) << 32) | ntohl(n >> 32);
+}
+static unsigned __int64 htonll(
+ unsigned __int64 n
+ )
+{
+ return htonl(1) == 1 ? n : ((uint64_t) htonl(n) << 32) | htonl(n >> 32);
+}
+
+#endif
+
#ifndef __CHECKER__
#if !(defined(_WIN32) || defined(htonll))
static inline ovs_be64
@@ -30,20 +30,20 @@ bool dpif_netlink_rtnl_probe_oot_tunnels(void);
#ifndef __linux__
/* Dummy implementations for non Linux builds. */
-static inline int
+inline int
dpif_netlink_rtnl_port_create(struct netdev *netdev OVS_UNUSED)
{
return EOPNOTSUPP;
}
-static inline int
+inline int
dpif_netlink_rtnl_port_destroy(const char *name OVS_UNUSED,
const char *type OVS_UNUSED)
{
return EOPNOTSUPP;
}
-static inline bool
+inline bool
dpif_netlink_rtnl_probe_oot_tunnels(void)
{
return true;
@@ -21,7 +21,7 @@
#include <fcntl.h>
#include <unistd.h>
#ifdef _WIN32
-#include <Wincrypt.h>
+#include <wincrypt.h>
#endif
#include "util.h"
#include "socket-util.h"
@@ -50,13 +50,13 @@ getrusage(int who, struct rusage *usage)
ovs_lasterror_to_string());
return -1;
}
-
+#ifndef _WIN32
if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
VLOG_ERR("failed at GetProcessMemoryInfo: %s",
ovs_lasterror_to_string());
return -1;
}
-
+#endif
usage_to_timeval(&kernel_time, &usage->ru_stime);
usage_to_timeval(&user_time, &usage->ru_utime);
usage->ru_majflt = pmc.PageFaultCount;
@@ -39,6 +39,10 @@
#include "util.h"
#include "openvswitch/vlog.h"
+#ifdef _WIN32
+#include <mswsock.h>
+#endif
+
VLOG_DEFINE_THIS_MODULE(netlink_socket);
COVERAGE_DEFINE(netlink_overflow);
@@ -749,18 +749,21 @@ struct ip_header {
BUILD_ASSERT_DECL(IP_HEADER_LEN == sizeof(struct ip_header));
/* ICMPv4 types. */
+#include <iprtrmib.h>
+#if 0
#define ICMP4_ECHO_REPLY 0
#define ICMP4_DST_UNREACH 3
-#define ICMP4_SOURCEQUENCH 4
#define ICMP4_REDIRECT 5
#define ICMP4_ECHO_REQUEST 8
#define ICMP4_TIME_EXCEEDED 11
#define ICMP4_PARAM_PROB 12
+#endif
+
+#define ICMP4_SOURCEQUENCH 4
#define ICMP4_TIMESTAMP 13
#define ICMP4_TIMESTAMPREPLY 14
#define ICMP4_INFOREQUEST 15
#define ICMP4_INFOREPLY 16
-
#define ICMP_HEADER_LEN 8
struct icmp_header {
uint8_t icmp_type;
@@ -18,43 +18,3 @@
#include <stdio.h>
#include <sys/types.h>
-
-#ifdef _WIN32
-#undef snprintf
-#undef vsnprintf
-
-int
-ovs_snprintf(char *s, size_t n, const char *format, ... )
-{
- va_list args;
- int len;
-
- va_start(args, format);
- len = ovs_vsnprintf(s, n, format, args);
- va_end(args);
-
- return len;
-}
-
-int
-ovs_vsnprintf(char *s, size_t n, const char *format, va_list args)
-{
- int needed = _vscprintf(format, args);
- if (s && n) {
- vsnprintf(s, n, format, args);
- s[n - 1] = '\0';
- }
- return needed;
-}
-
-int
-fseeko(FILE *stream, off_t offset, int whence)
-{
- int error;
- error = _fseeki64(stream, offset, whence);
- if (error) {
- return -1;
- }
- return error;
-}
-#endif /* _WIN32 */
@@ -24,23 +24,9 @@
#include <stdarg.h>
#include <stddef.h>
#include <sys/types.h>
+#define __USE_MINGW_ANSI_STDIO 1
+#include <stdio.h>
-/* Windows libc has defective snprintf() and vsnprintf():
- *
- * - They return -1 if the output won't fit.
- *
- * - They don't null-terminate the output if it won't fit.
- *
- * We need working versions so here we define substitutes. */
-#undef snprintf
-#define snprintf ovs_snprintf
-int ovs_snprintf(char *, size_t, const char *, ...);
-
-#undef vsnprintf
-#define vsnprintf ovs_vsnprintf
-int ovs_vsnprintf(char *, size_t, const char *, va_list);
-
-int fseeko(FILE *stream, off_t offset, int whence);
#endif /* _WIN32 */
#endif /* stdio.h wrapper */
@@ -148,14 +148,14 @@ windows_open(const char *name, char *suffix, struct stream **streamp,
}
if (!retry && npipe == INVALID_HANDLE_VALUE) {
- VLOG_ERR_RL(&rl, "Could not connect to named pipe: %s",
- ovs_lasterror_to_string());
+ VLOG_ERR_RL(&rl, "Could not connect to named pipe: %s at %s",
+ ovs_lasterror_to_string(), connect_path);
free(connect_path);
return ENOENT;
}
if (!retry && !SetNamedPipeHandleState(npipe, &mode, NULL, NULL)) {
- VLOG_ERR_RL(&rl, "Could not set named pipe options: %s",
- ovs_lasterror_to_string());
+ VLOG_ERR_RL(&rl, "Could not set named pipe options: %s at %s",
+ ovs_lasterror_to_string(), connect_path);
free(connect_path);
CloseHandle(npipe);
return ENOENT;
@@ -239,7 +239,7 @@ windows_recv(struct stream *stream, void *buffer, size_t n)
/* If the read operation was pending, we verify its result. */
if (s->read_pending) {
- if (!GetOverlappedResult(s->fd, ov, &(DWORD)retval, FALSE)) {
+ if (!GetOverlappedResult(s->fd, ov, (LPDWORD)retval, FALSE)) {
last_error = GetLastError();
if (last_error == ERROR_IO_INCOMPLETE) {
/* If the operation is still pending, retry again. */
@@ -261,7 +261,7 @@ windows_recv(struct stream *stream, void *buffer, size_t n)
return retval;
}
- result = ReadFile(s->fd, buffer, n, &(DWORD)retval, ov);
+ result = ReadFile(s->fd, buffer, n, (LPDWORD)retval, ov);
if (!result && GetLastError() == ERROR_IO_PENDING) {
/* Mark the read operation as pending. */
@@ -297,7 +297,7 @@ windows_send(struct stream *stream, const void *buffer, size_t n)
/* If the send operation was pending, we verify the result. */
if (s->write_pending) {
- if (!GetOverlappedResult(s->fd, ov, &(DWORD)retval, FALSE)) {
+ if (!GetOverlappedResult(s->fd, ov, (LPDWORD)retval, FALSE)) {
last_error = GetLastError();
if (last_error == ERROR_IO_INCOMPLETE) {
/* If the operation is still pending, retry again. */
@@ -319,7 +319,7 @@ windows_send(struct stream *stream, const void *buffer, size_t n)
return retval;
}
- result = WriteFile(s->fd, buffer, n, &(DWORD)retval, ov);
+ result = WriteFile(s->fd, buffer, n, (LPDWORD)retval, ov);
last_error = GetLastError();
if (!result && last_error == ERROR_IO_PENDING) {
/* Mark the send operation as pending. */
@@ -418,39 +418,6 @@ xgetfiletime(void)
return current_time;
}
-static int
-clock_gettime(clock_t id, struct timespec *ts)
-{
- if (id == CLOCK_MONOTONIC) {
- static LARGE_INTEGER freq;
- LARGE_INTEGER count;
- long long int ns;
-
- if (!freq.QuadPart) {
- /* Number of counts per second. */
- QueryPerformanceFrequency(&freq);
- }
- /* Total number of counts from a starting point. */
- QueryPerformanceCounter(&count);
-
- /* Total nano seconds from a starting point. */
- ns = (double) count.QuadPart / freq.QuadPart * 1000000000;
-
- ts->tv_sec = count.QuadPart / freq.QuadPart;
- ts->tv_nsec = ns % 1000000000;
- } else if (id == CLOCK_REALTIME) {
- ULARGE_INTEGER current_time = xgetfiletime();
-
- /* Time from Epoch to now. */
- ts->tv_sec = (current_time.QuadPart - unix_epoch) / 10000000;
- ts->tv_nsec = ((current_time.QuadPart - unix_epoch) %
- 10000000) * 100;
- } else {
- return -1;
- }
-
- return 0;
-}
#endif /* _WIN32 */
#if defined(__MACH__) && !defined(HAVE_CLOCK_GETTIME)
@@ -18,7 +18,7 @@
#define WMI_H 1
#include <windefs.h>
-#include <Wbemidl.h>
+#include <wbemidl.h>
static inline void fill_context(IWbemContext *pContext)
{
@@ -111,7 +111,7 @@ AC_DEFUN([OVS_CHECK_WIN32],
fi
PTHREAD_INCLUDES=-I$withval/include
PTHREAD_LDFLAGS=-L$PTHREAD_WIN32_DIR
- PTHREAD_LIBS="-lpthreadVC2"
+ PTHREAD_LIBS="-lpthread"
AC_SUBST([PTHREAD_WIN32_DIR_DLL_WIN_FORM])
AC_SUBST([PTHREAD_WIN32_DIR_DLL])
AC_SUBST([PTHREAD_INCLUDES])
@@ -136,7 +136,6 @@ AC_DEFUN([OVS_CHECK_WIN32],
)
AC_DEFINE([WIN32], [1], [Define to 1 if building on WIN32.])
- AC_CHECK_TYPES([struct timespec], [], [], [[#include <time.h>]])
AH_BOTTOM([#ifdef WIN32
#include "include/windows/windefs.h"
#endif])
Currently we use MSVC to compile OVS on Windows. The patch tries to cross-compile OVS for windows using gcc from mingw-w64. The patch still shows lots of warnings I haven't fixed, but now it can generate all the .exe and I tested on windows 10 (no kernel module). To try it on: 1) download mingw-w64 2) configure and build ./boot.sh LIBS="-lws2_32 -lshlwapi -liphlpapi -lwbemuuid -lole32 -loleaut32 " \ ./configure \ --with-pthread=/disk2/ovs-win32/pthreads-win32/Pre-built.2 \ --with-openssl=/usr/x86_64-w64-mingw32/include \ CC=x86_64-w64-mingw32-gcc --host=x86_64-w64-mingw32 \ CXX=x86_64-w64-mingw32-g++ \ CXXCPP=x86_64-w64-mingw32-cpp-win32 \ --includedir=/usr/x86_64-w64-mingw32/include \ --prefix="C:/openvswitch/usr" \ --localstatedir="C:/openvswitch/var" \ --sysconfdir="C:/openvswitch/etc" Signed-off-by: William Tu <u9012063@gmail.com> --- Makefile.am | 6 +++++- include/openvswitch/compiler.h | 10 ++++++++++ include/windows/net/if.h | 2 +- include/windows/netinet/icmp6.h | 4 ++++ include/windows/windefs.h | 18 ++++++++++++------ lib/byte-order.h | 16 ++++++++++++++++ lib/dpif-netlink-rtnl.h | 6 +++--- lib/entropy.c | 2 +- lib/getrusage-windows.c | 4 ++-- lib/netlink-socket.c | 4 ++++ lib/packets.h | 7 +++++-- lib/stdio.c | 40 ---------------------------------------- lib/stdio.h.in | 18 ++---------------- lib/stream-windows.c | 16 ++++++++-------- lib/timeval.c | 33 --------------------------------- lib/wmi.h | 2 +- m4/openvswitch.m4 | 3 +-- 17 files changed, 75 insertions(+), 116 deletions(-)