the right compiler, linker, libraries, Open vSwitch component installation
directories, etc. For example,
- % ./configure CC=./build-aux/cccl LD="`which link`" LIBS="-lws2_32" \
- --prefix="C:/openvswitch/usr" --localstatedir="C:/openvswitch/var" \
- --sysconfdir="C:/openvswitch/etc" --with-pthread="C:/pthread"
+ % ./configure CC=./build-aux/cccl LD="`which link`" \
+ LIBS="-lws2_32 -liphlpapi" --prefix="C:/openvswitch/usr" \
+ --localstatedir="C:/openvswitch/var" --sysconfdir="C:/openvswitch/etc" \
+ --with-pthread="C:/pthread"
By default, the above enables compiler optimization for fast code.
For default compiler optimization, pass the "--with-debug" configure
* While configuring the package, specify the OpenSSL directory path.
For example,
- % ./configure CC=./build-aux/cccl LD="`which link`" LIBS="-lws2_32" \
- --prefix="C:/openvswitch/usr" --localstatedir="C:/openvswitch/var" \
- --sysconfdir="C:/openvswitch/etc" --with-pthread="C:/pthread" \
- --enable-ssl --with-openssl="C:/OpenSSL-Win32"
+ % ./configure CC=./build-aux/cccl LD="`which link`" \
+ LIBS="-lws2_32 -liphlpapi" --prefix="C:/openvswitch/usr" \
+ --localstatedir="C:/openvswitch/var" --sysconfdir="C:/openvswitch/etc" \
+ --with-pthread="C:/pthread" --enable-ssl --with-openssl="C:/OpenSSL-Win32"
* Run make for the ported executables.
'--with-vstudioddk' argument is specified while configuring the package.
For example,
- % ./configure CC=./build-aux/cccl LD="`which link`" LIBS="-lws2_32" \
- --prefix="C:/openvswitch/usr" --localstatedir="C:/openvswitch/var" \
- --sysconfdir="C:/openvswitch/etc" --with-pthread="C:/pthread" \
- --enable-ssl --with-openssl="C:/OpenSSL-Win32" \
- --with-vstudioddk="<WDK to use>"
+ % ./configure CC=./build-aux/cccl LD="`which link`" \
+ LIBS="-lws2_32 -liphlpapi" --prefix="C:/openvswitch/usr" \
+ --localstatedir="C:/openvswitch/var" --sysconfdir="C:/openvswitch/etc" \
+ --with-pthread="C:/pthread" --enable-ssl \
+ --with-openssl="C:/OpenSSL-Win32" --with-vstudioddk="<WDK to use>"
Possible values for "<WDK to use>" are:
"Win8.1 Debug", "Win8.1 Release", "Win8 Debug" and "Win8 Release".
#include <stdlib.h>
#include <config.h>
#include <errno.h>
+#include <iphlpapi.h>
#include <net/if.h>
return 0;
}
+/* Looks up in the ARP table entry for a given 'ip'. If it is found, the
+ * corresponding MAC address will be copied in 'mac' and return 0. If no
+ * matching entry is found or an error occurs it will log it and return ENXIO.
+ */
+static int
+netdev_windows_arp_lookup(const struct netdev *netdev,
+ ovs_be32 ip, uint8_t mac[ETH_ADDR_LEN])
+{
+ PMIB_IPNETTABLE arp_table = NULL;
+ /* The buffer length of all ARP entries */
+ uint32_t buffer_length = 0;
+ uint32_t ret_val = 0;
+ uint32_t counter = 0;
+
+ ret_val = GetIpNetTable(arp_table, &buffer_length, false);
+
+ if (ret_val != ERROR_INSUFFICIENT_BUFFER ) {
+ VLOG_ERR("Call to GetIpNetTable failed with error: %s",
+ ovs_format_message(ret_val));
+ return ENXIO;
+ }
+
+ arp_table = (MIB_IPNETTABLE *) malloc(buffer_length);
+
+ if (arp_table == NULL) {
+ VLOG_ERR("Could not allocate memory for all the interfaces");
+ return ENXIO;
+ }
+
+ ret_val = GetIpNetTable(arp_table, &buffer_length, false);
+
+ if (ret_val == NO_ERROR) {
+ for (counter = 0; counter < arp_table->dwNumEntries; counter++) {
+ if (arp_table->table[counter].dwAddr == ip) {
+ memcpy(mac, arp_table->table[counter].bPhysAddr, ETH_ADDR_LEN);
+
+ free(arp_table);
+ return 0;
+ }
+ }
+ } else {
+ VLOG_ERR("Call to GetIpNetTable failed with error: %s",
+ ovs_format_message(ret_val));
+ }
+
+ free(arp_table);
+ return ENXIO;
+}
+
+static int
+netdev_windows_get_next_hop(const struct in_addr *host,
+ struct in_addr *next_hop,
+ char **netdev_name)
+{
+ uint32_t ret_val = 0;
+ /* The buffer length of all addresses */
+ uint32_t buffer_length = 1000;
+ PIP_ADAPTER_ADDRESSES all_addr = NULL;
+ PIP_ADAPTER_ADDRESSES cur_addr = NULL;
+
+ ret_val = GetAdaptersAddresses(AF_INET,
+ GAA_FLAG_INCLUDE_PREFIX |
+ GAA_FLAG_INCLUDE_GATEWAYS,
+ NULL, all_addr, &buffer_length);
+
+ if (ret_val != ERROR_INSUFFICIENT_BUFFER ) {
+ VLOG_ERR("Call to GetAdaptersAddresses failed with error: %s",
+ ovs_format_message(ret_val));
+ return ENXIO;
+ }
+
+ all_addr = (IP_ADAPTER_ADDRESSES *) malloc(buffer_length);
+
+ if (all_addr == NULL) {
+ VLOG_ERR("Could not allocate memory for all the interfaces");
+ return ENXIO;
+ }
+
+ ret_val = GetAdaptersAddresses(AF_INET,
+ GAA_FLAG_INCLUDE_PREFIX |
+ GAA_FLAG_INCLUDE_GATEWAYS,
+ NULL, all_addr, &buffer_length);
+
+ if (ret_val == NO_ERROR) {
+ cur_addr = all_addr;
+ while (cur_addr) {
+ if(cur_addr->FirstGatewayAddress &&
+ cur_addr->FirstGatewayAddress->Address.lpSockaddr) {
+ struct sockaddr_in *ipv4 = (struct sockaddr_in *)
+ cur_addr->FirstGatewayAddress->Address.lpSockaddr;
+ next_hop->s_addr = ipv4->sin_addr.S_un.S_addr;
+ *netdev_name = xstrdup((char *)cur_addr->FriendlyName);
+
+ free(all_addr);
+
+ return 0;
+ }
+
+ cur_addr = cur_addr->Next;
+ }
+ } else {
+ VLOG_ERR("Call to GetAdaptersAddresses failed with error: %s",
+ ovs_format_message(ret_val));
+ }
+
+ if (all_addr) {
+ free(all_addr);
+ }
+ return ENXIO;
+}
+
static int
netdev_windows_internal_construct(struct netdev *netdev_)
{
.get_etheraddr = netdev_windows_get_etheraddr, \
.set_etheraddr = netdev_windows_set_etheraddr, \
.update_flags = netdev_windows_update_flags, \
+ .get_next_hop = netdev_windows_get_next_hop, \
+ .arp_lookup = netdev_windows_arp_lookup, \
}
const struct netdev_class netdev_windows_class =