VDE networking support
Adds VDE (https://github.com/virtualsquare/vde-2) support to 86Box. - Adds new networking type - Modifies networking configuration dialog - Adds CMake Presets to build and debug under MacOS
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -56,3 +56,6 @@ CMakeLists.txt.user
|
||||
/debian/debhelper-build-stamp
|
||||
/debian/files
|
||||
/obj-*-linux-gnu
|
||||
|
||||
# MacOS Finder stuff
|
||||
.DS_Store
|
||||
|
@@ -56,6 +56,72 @@
|
||||
"NEW_DYNAREC": "ON"
|
||||
},
|
||||
"inherits": "base"
|
||||
},
|
||||
{
|
||||
"name": "llvm-macos-aarch64.cmake",
|
||||
"displayName": "MacOS clang regular",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "cmake/llvm-macos-aarch64.cmake",
|
||||
"NEW_DYNAREC": "ON",
|
||||
"QT": "ON",
|
||||
"USE_QT6": "OFF",
|
||||
"Qt5_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5",
|
||||
"MOLTENVK_DIR": "/opt/homebrew/opt/molten-vk",
|
||||
"Qt5LinguistTools_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5LinguistTools",
|
||||
"OpenAL_ROOT": "/opt/homebrew/opt/openal-soft"
|
||||
},
|
||||
"inherits": "regular"
|
||||
},
|
||||
{
|
||||
"name": "llvm-macos-aarch64-debug",
|
||||
"displayName": "MacOS clang debug",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "cmake/llvm-macos-aarch64.cmake",
|
||||
"NEW_DYNAREC": "ON",
|
||||
"QT": "ON",
|
||||
"USE_QT6": "OFF",
|
||||
"Qt5_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5",
|
||||
"MOLTENVK_DIR": "/opt/homebrew/opt/molten-vk",
|
||||
"Qt5LinguistTools_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5LinguistTools",
|
||||
"OpenAL_ROOT": "/opt/homebrew/opt/openal-soft",
|
||||
"CMAKE_CXX_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG",
|
||||
"CMAKE_C_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG"
|
||||
},
|
||||
"inherits": "debug"
|
||||
},
|
||||
{
|
||||
"name": "flags-gcc-aarch64-debug",
|
||||
"displayName": "Linux ARM 64 - Debug",
|
||||
"description": "Linux ARM64 - Debug build",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"cacheVariables": {
|
||||
"NEW_DYNAREC": "ON",
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_TOOLCHAIN_FILE": "cmake/flags-gcc-aarch64.cmake",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
|
||||
"CMAKE_CXX_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG",
|
||||
"CMAKE_C_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG"
|
||||
},
|
||||
"inherits": "debug"
|
||||
},
|
||||
{
|
||||
"name": "flags-gcc-aarch64-regular",
|
||||
"displayName": "Linux ARM 64 - Regular",
|
||||
"description": "Linux ARM64 - Release build",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"cacheVariables": {
|
||||
"NEW_DYNAREC": "ON",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_TOOLCHAIN_FILE": "cmake/flags-gcc-aarch64.cmake",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
|
||||
},
|
||||
"inherits": "regular"
|
||||
}
|
||||
],
|
||||
"buildPresets": [],
|
||||
|
52
src/config.c
52
src/config.c
@@ -783,6 +783,8 @@ load_network(void)
|
||||
net_cards_conf[c].net_type = NET_TYPE_PCAP;
|
||||
else if (!strcmp(p, "slirp") || !strcmp(p, "2"))
|
||||
net_cards_conf[c].net_type = NET_TYPE_SLIRP;
|
||||
else if (!strcmp(p, "vde") || !strcmp(p, "2"))
|
||||
net_cards_conf[c].net_type = NET_TYPE_VDE;
|
||||
else
|
||||
net_cards_conf[c].net_type = NET_TYPE_NONE;
|
||||
} else {
|
||||
@@ -791,13 +793,17 @@ load_network(void)
|
||||
|
||||
p = ini_section_get_string(cat, "net_host_device", NULL);
|
||||
if (p != NULL) {
|
||||
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
|
||||
if (network_ndev == 1) {
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
|
||||
} else if (network_dev_to_id(p) == -1) {
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
|
||||
if (net_cards_conf[c].net_type == NET_TYPE_PCAP) {
|
||||
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
|
||||
if (network_ndev == 1) {
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
|
||||
} else if (network_dev_to_id(p) == -1) {
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
|
||||
}
|
||||
strcpy(net_cards_conf[c].host_dev_name, "none");
|
||||
} else {
|
||||
strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1);
|
||||
}
|
||||
strcpy(net_cards_conf[c].host_dev_name, "none");
|
||||
} else {
|
||||
strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1);
|
||||
}
|
||||
@@ -828,6 +834,8 @@ load_network(void)
|
||||
net_cards_conf[c].net_type = NET_TYPE_PCAP;
|
||||
} else if (!strcmp(p, "slirp") || !strcmp(p, "2")) {
|
||||
net_cards_conf[c].net_type = NET_TYPE_SLIRP;
|
||||
} else if (!strcmp(p, "vde") || !strcmp(p, "2")) {
|
||||
net_cards_conf[c].net_type = NET_TYPE_VDE;
|
||||
} else {
|
||||
net_cards_conf[c].net_type = NET_TYPE_NONE;
|
||||
}
|
||||
@@ -838,13 +846,15 @@ load_network(void)
|
||||
sprintf(temp, "net_%02i_host_device", c + 1);
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p != NULL) {
|
||||
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
|
||||
if (network_ndev == 1) {
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
|
||||
} else if (network_dev_to_id(p) == -1) {
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
|
||||
if (net_cards_conf[c].net_type == NET_TYPE_PCAP) {
|
||||
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
|
||||
if (network_ndev == 1) {
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
|
||||
} else if (network_dev_to_id(p) == -1) {
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
|
||||
}
|
||||
strcpy(net_cards_conf[c].host_dev_name, "none");
|
||||
}
|
||||
strcpy(net_cards_conf[c].host_dev_name, "none");
|
||||
} else {
|
||||
strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1);
|
||||
}
|
||||
@@ -2469,11 +2479,19 @@ save_network(void)
|
||||
}
|
||||
|
||||
sprintf(temp, "net_%02i_net_type", c + 1);
|
||||
if (net_cards_conf[c].net_type == NET_TYPE_NONE) {
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
ini_section_set_string(cat, temp,
|
||||
(net_cards_conf[c].net_type == NET_TYPE_SLIRP) ? "slirp" : "pcap");
|
||||
switch(net_cards_conf[c].net_type) {
|
||||
case NET_TYPE_NONE:
|
||||
ini_section_delete_var(cat, temp);
|
||||
break;
|
||||
case NET_TYPE_SLIRP:
|
||||
ini_section_set_string(cat, temp, "slirp");
|
||||
break;
|
||||
case NET_TYPE_PCAP:
|
||||
ini_section_set_string(cat, temp, "pcap");
|
||||
break;
|
||||
case NET_TYPE_VDE:
|
||||
ini_section_set_string(cat, temp, "vde");
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(temp, "net_%02i_host_device", c + 1);
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#define NET_TYPE_NONE 0 /* networking disabled */
|
||||
#define NET_TYPE_SLIRP 1 /* use the SLiRP port forwarder */
|
||||
#define NET_TYPE_PCAP 2 /* use the (Win)Pcap API */
|
||||
#define NET_TYPE_VDE 3 /* use the VDE plug API */
|
||||
|
||||
#define NET_MAX_FRAME 1518
|
||||
/* Queue size must be a power of 2 */
|
||||
@@ -123,6 +124,7 @@ typedef struct netdrv_t {
|
||||
|
||||
extern const netdrv_t net_pcap_drv;
|
||||
extern const netdrv_t net_slirp_drv;
|
||||
extern const netdrv_t net_vde_drv;
|
||||
|
||||
struct _netcard_t {
|
||||
const device_t *device;
|
||||
@@ -147,15 +149,27 @@ typedef struct {
|
||||
char description[128];
|
||||
} netdev_t;
|
||||
|
||||
typedef struct {
|
||||
int has_slirp: 1;
|
||||
int has_pcap: 1;
|
||||
int has_vde: 1;
|
||||
} network_devmap_t;
|
||||
|
||||
|
||||
#define HAS_NOSLIRP_NET(x) (x.has_pcap || x.has_vde)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Global variables. */
|
||||
extern int nic_do_log; /* config */
|
||||
extern int network_ndev;
|
||||
extern network_devmap_t network_devmap;
|
||||
extern int network_ndev; // Number of pcap devices
|
||||
extern network_devmap_t network_devmap; // Bitmap of available network types
|
||||
extern netdev_t network_devs[NET_HOST_INTF_MAX];
|
||||
|
||||
|
||||
/* Function prototypes. */
|
||||
extern void network_init(void);
|
||||
extern netcard_t *network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_link_state);
|
||||
@@ -166,6 +180,8 @@ extern int network_available(void);
|
||||
extern void network_tx(netcard_t *card, uint8_t *, int);
|
||||
|
||||
extern int net_pcap_prepare(netdev_t *);
|
||||
extern int net_vde_prepare(void);
|
||||
|
||||
|
||||
extern void network_connect(int id, int connect);
|
||||
extern int network_is_connected(int id);
|
||||
|
@@ -12,8 +12,8 @@
|
||||
#
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(net OBJECT network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c
|
||||
set(net_sources)
|
||||
list(APPEND net_sources network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c
|
||||
net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c)
|
||||
|
||||
option(SLIRP_EXTERNAL "Link against the system-provided libslirp library" OFF)
|
||||
@@ -39,3 +39,13 @@ endif()
|
||||
if(WIN32)
|
||||
target_link_libraries(86Box ws2_32)
|
||||
endif()
|
||||
|
||||
if (UNIX)
|
||||
find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" )
|
||||
if(HAS_VDE)
|
||||
add_compile_definitions(HAS_VDE)
|
||||
list(APPEND net_sources net_vde.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(net OBJECT ${net_sources})
|
||||
|
310
src/network/net_vde.c
Normal file
310
src/network/net_vde.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* VDE networking for 86box
|
||||
* See https://wiki.virtualsquare.org/#!tutorials/vdebasics.md
|
||||
* for basic information about VDE. You can browse the source
|
||||
* code at https://github.com/virtualsquare/vde-2
|
||||
*
|
||||
* VDE support is only available in Linux and MacOS. It _should_
|
||||
* be available in BSD*, and if someday there is a BSD version of
|
||||
* 86box this _could_ work out of the box.
|
||||
*
|
||||
* Authors: jguillaumes <jguillaumes@gmail.com>
|
||||
* Copyright 2023 jguillaumes.
|
||||
*
|
||||
* See the COPYING file at the top of the 86box for license details.
|
||||
* TL;DR: GPL version 2.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#error VDE is not supported under windows
|
||||
#endif
|
||||
|
||||
#include <libvdeplug.h>
|
||||
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_dynld.h>
|
||||
#include <86box/thread.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/network.h>
|
||||
#include <86box/net_event.h>
|
||||
|
||||
#define VDE_PKT_BATCH NET_QUEUE_LEN
|
||||
#define VDE_DESCRIPTION "86Box virtual card"
|
||||
|
||||
enum {
|
||||
NET_EVENT_STOP = 0,
|
||||
NET_EVENT_TX,
|
||||
NET_EVENT_RX,
|
||||
NET_EVENT_VDE,
|
||||
NET_EVENT_MAX
|
||||
};
|
||||
|
||||
static volatile void *libvde_handle = NULL;
|
||||
|
||||
//+
|
||||
// VDE connection structure
|
||||
//-
|
||||
typedef struct {
|
||||
void *vdeconn; // VDEPLUG Connection
|
||||
netcard_t *card; // NIC linked to
|
||||
thread_t *poll_tid; // Polling thread
|
||||
net_evt_t tx_event; // Packets to transmit event
|
||||
net_evt_t stop_event; // Stop thread event
|
||||
netpkt_t pkt; // Packet read/sent
|
||||
netpkt_t pktv[VDE_PKT_BATCH]; // Packet queue
|
||||
uint8_t mac_addr[6]; // MAC Address
|
||||
} net_vde_t;
|
||||
|
||||
//+
|
||||
// VDE libvdeplug function pointers
|
||||
//-
|
||||
static VDECONN *(*f_vde_open)(char *, char *, int, struct vde_open_args *); // This is vde_open_real()
|
||||
static void (*f_vde_close)(VDECONN *);
|
||||
static int (*f_vde_datafd)(VDECONN *); // Get the data (read/write) handle
|
||||
static int (*f_vde_ctlfd)(VDECONN *); // Get the control handle
|
||||
static ssize_t (*f_vde_recv)(VDECONN *, void *, size_t, int); // Receive a packet
|
||||
static ssize_t (*f_vde_send)(VDECONN *, const void *, size_t, int); // Send a packet
|
||||
|
||||
//+
|
||||
// VDE libvdeplug function table (for import)
|
||||
//-
|
||||
static dllimp_t vde_imports[] = {
|
||||
{"vde_open_real", &f_vde_open},
|
||||
{"vde_close", &f_vde_close},
|
||||
{"vde_datafd", &f_vde_datafd},
|
||||
{"vde_ctlfd", &f_vde_ctlfd},
|
||||
{"vde_recv", &f_vde_recv},
|
||||
{"vde_send", &f_vde_send},
|
||||
{ NULL, NULL}
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VDE_LOG
|
||||
#include <stdarg.h>
|
||||
int vde_do_log = ENABLE_VDE_LOG;
|
||||
|
||||
static void
|
||||
vde_log(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
if (vde_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define vde_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#error VDE networking is not supported under windows
|
||||
#else
|
||||
|
||||
//+
|
||||
// VDE thread
|
||||
//-
|
||||
static void net_vde_thread(void *priv) {
|
||||
net_vde_t *vde = (net_vde_t *) priv;
|
||||
vde_log("VDE: Polling started.\n");
|
||||
|
||||
struct pollfd pfd[NET_EVENT_MAX];
|
||||
pfd[NET_EVENT_STOP].fd = net_event_get_fd(&vde->stop_event);
|
||||
pfd[NET_EVENT_STOP].events = POLLIN | POLLPRI;
|
||||
|
||||
pfd[NET_EVENT_TX].fd = net_event_get_fd(&vde->tx_event);
|
||||
pfd[NET_EVENT_TX].events = POLLIN | POLLPRI;
|
||||
|
||||
pfd[NET_EVENT_RX].fd = f_vde_datafd(vde->vdeconn);
|
||||
pfd[NET_EVENT_RX].events = POLLIN;
|
||||
|
||||
pfd[NET_EVENT_VDE].fd = f_vde_ctlfd(vde->vdeconn);
|
||||
pfd[NET_EVENT_VDE].events = POLLIN;
|
||||
|
||||
while(1) {
|
||||
poll(pfd, NET_EVENT_MAX, -1);
|
||||
|
||||
// Acvity in the control handle means the link is closed
|
||||
// We send ourselves a STOP event
|
||||
if (pfd[NET_EVENT_VDE].revents & POLLIN) {
|
||||
net_event_set(&vde->stop_event);
|
||||
}
|
||||
|
||||
// There are packets queued to transmit
|
||||
if (pfd[NET_EVENT_TX].revents & POLLIN) {
|
||||
net_event_clear(&vde->tx_event);
|
||||
int packets = network_tx_popv(vde->card, vde->pktv, VDE_PKT_BATCH);
|
||||
for (int i=0; i<packets; i++) {
|
||||
int nc = f_vde_send(vde->vdeconn, vde->pktv[i].data,vde->pktv[i].len, 0 );
|
||||
if (nc == 0) {
|
||||
vde_log("VDE: Problem, no bytes sent.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Packets are available for reading. Read packet and queue it
|
||||
if (pfd[NET_EVENT_RX].revents & POLLIN) {
|
||||
int nc = f_vde_recv(vde->vdeconn, vde->pkt.data, NET_MAX_FRAME, 0);
|
||||
vde->pkt.len = nc;
|
||||
network_rx_put_pkt(vde->card, &vde->pkt);
|
||||
}
|
||||
|
||||
// We have been told to close
|
||||
if (pfd[NET_EVENT_STOP].revents & POLLIN) {
|
||||
net_event_clear(&vde->stop_event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
vde_log("VDE: Polling stopped.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//+
|
||||
// Prepare the VDE libvdeplug interface.
|
||||
// Load the dynamic library libvdeplug.
|
||||
// Returns zero if the library has been loaded, -1 in case of error.
|
||||
//-
|
||||
int net_vde_prepare(void) {
|
||||
|
||||
#if defined(_WIN32)
|
||||
#error VDE is not supported in Windows
|
||||
#elif defined(__APPLE__)
|
||||
libvde_handle = dynld_module("libvdeplug.dylib", vde_imports);
|
||||
#else
|
||||
libvde_handle = dynld_module("libvdeplug.so", vde_imports);
|
||||
#endif
|
||||
|
||||
if (libvde_handle == NULL) {
|
||||
vde_log("VDE: error loading VDEPLUG module\n");
|
||||
return -1;
|
||||
} else {
|
||||
network_devmap.has_vde = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//+
|
||||
// Close a VDE socket connection
|
||||
//-
|
||||
void net_vde_close(void *priv) {
|
||||
int i;
|
||||
|
||||
if (!priv) return;
|
||||
|
||||
net_vde_t *vde = (net_vde_t *) priv;
|
||||
vde_log("VDE: closing.\n");
|
||||
net_event_set(&vde->stop_event); // Tell the thread to finish
|
||||
vde_log("VDE: Waiting for the thread to finish...\n");
|
||||
thread_wait(vde->poll_tid);
|
||||
vde_log("VDE: Thread finished.\n");
|
||||
|
||||
// Free all the mallocs!
|
||||
for(i=0;i<VDE_PKT_BATCH; i++) {
|
||||
free(vde->pktv[i].data);
|
||||
}
|
||||
free(vde->pkt.data);
|
||||
f_vde_close((void *) vde->vdeconn);
|
||||
net_event_close(&vde->tx_event);
|
||||
net_event_close(&vde->stop_event);
|
||||
free(vde);
|
||||
}
|
||||
|
||||
//+
|
||||
// Signal packets are available to be transmitted
|
||||
//-
|
||||
void net_vde_in_available(void *priv) {
|
||||
net_vde_t *vde = (net_vde_t *) priv;
|
||||
net_event_set(&vde->tx_event);
|
||||
}
|
||||
|
||||
//+
|
||||
// Initialize VDE for use
|
||||
// At this point the vdeplug library is already loaded
|
||||
// card: network card we are attaching
|
||||
// mac_addr: MAC address we are using
|
||||
// priv: Name of the VDE contol socket directory
|
||||
//-
|
||||
void *net_vde_init(const netcard_t *card, const uint8_t *mac_addr, void *priv) {
|
||||
struct vde_open_args vde_args;
|
||||
int i;
|
||||
|
||||
char *socket_name = (char *) priv;
|
||||
|
||||
if (libvde_handle == NULL) {
|
||||
vde_log("VDE: net_vde_init without library handle!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((socket_name[0] == '\0') || !strcmp(socket_name, "none")) {
|
||||
vde_log("VDE: No socket name configured!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vde_log("VDE: Attaching to virtual switch at %s\n", socket_name);
|
||||
|
||||
net_vde_t *vde = calloc(1, sizeof(net_vde_t));
|
||||
vde->card = (netcard_t *) card;
|
||||
memcpy(vde->mac_addr, mac_addr, sizeof(vde->mac_addr));
|
||||
|
||||
vde_args.group = 0;
|
||||
vde_args.port = 0;
|
||||
vde_args.mode = 0;
|
||||
|
||||
// We are calling vde_open_real(), not the vde_open() macro...
|
||||
if ((vde->vdeconn = f_vde_open(socket_name, VDE_DESCRIPTION,
|
||||
LIBVDEPLUG_INTERFACE_VERSION, &vde_args)) == NULL) {
|
||||
vde_log("VDE: Unable to open socket %s (%s)!\n", socket_name, strerror(errno));
|
||||
free(vde);
|
||||
//+
|
||||
// There is a bug upstream that causes an uncontrolled crash if the network is not
|
||||
// properly initialized.
|
||||
// To avoid that crash, we tell the user we cannot continue and exit the program.
|
||||
// TODO: Once there is a solution for the mentioned crash, this should be removed
|
||||
// and/or replaced by proper error handling code.
|
||||
//-
|
||||
fatal("Could not open the specified VDE socket (%s). Please fix your networking configuration.", socket_name);
|
||||
// It makes no sense to issue this warning since the program will crash anyway...
|
||||
// ui_msgbox_header(MBX_WARNING, (wchar_t *) IDS_2167, (wchar_t *) IDS_2168);
|
||||
return NULL;
|
||||
}
|
||||
vde_log("VDE: Socket opened (%s).\n", socket_name);
|
||||
|
||||
for(i=0; i < VDE_PKT_BATCH; i++) {
|
||||
vde->pktv[i].data = calloc(1, NET_MAX_FRAME);
|
||||
}
|
||||
vde->pkt.data = calloc(1,NET_MAX_FRAME);
|
||||
net_event_init(&vde->tx_event);
|
||||
net_event_init(&vde->stop_event);
|
||||
vde->poll_tid = thread_create(net_vde_thread, vde); // Fire up the read-write thread!
|
||||
|
||||
return vde;
|
||||
}
|
||||
|
||||
//+
|
||||
// VDE Driver structure
|
||||
//-
|
||||
const netdrv_t net_vde_drv = {
|
||||
&net_vde_in_available,
|
||||
&net_vde_init,
|
||||
&net_vde_close,
|
||||
NULL
|
||||
};
|
||||
|
@@ -123,7 +123,8 @@ netcard_conf_t net_cards_conf[NET_CARD_MAX];
|
||||
uint16_t net_card_current = 0;
|
||||
|
||||
/* Global variables. */
|
||||
int network_ndev;
|
||||
network_devmap_t network_devmap;
|
||||
int network_ndev;
|
||||
netdev_t network_devs[NET_HOST_INTF_MAX];
|
||||
|
||||
/* Local variables. */
|
||||
@@ -214,9 +215,20 @@ network_init(void)
|
||||
network_ndev = 1;
|
||||
|
||||
/* Initialize the Pcap system module, if present. */
|
||||
|
||||
network_devmap.has_slirp = 1;
|
||||
i = net_pcap_prepare(&network_devs[network_ndev]);
|
||||
if (i > 0)
|
||||
if (i > 0) {
|
||||
network_devmap.has_pcap = 1;
|
||||
network_ndev += i;
|
||||
}
|
||||
|
||||
#ifdef HAS_VDE
|
||||
// Try to load the VDE plug library
|
||||
if(net_vde_prepare()==0) {
|
||||
network_devmap.has_vde = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined ENABLE_NETWORK_LOG && !defined(_WIN32)
|
||||
/* Start packet dump. */
|
||||
@@ -286,6 +298,17 @@ int
|
||||
network_queue_put_swap(netqueue_t *queue, netpkt_t *src_pkt)
|
||||
{
|
||||
if (src_pkt->len == 0 || src_pkt->len > NET_MAX_FRAME || network_queue_full(queue)) {
|
||||
#ifdef DEBUG
|
||||
if (src_pkt->len == 0) {
|
||||
network_log("Discarded zero length packet.\n");
|
||||
} else if (src_pkt->len > NET_MAX_FRAME) {
|
||||
network_log("Discarded oversized packet of len=%d.\n", src_pkt->len);
|
||||
network_dump_packet(src_pkt);
|
||||
} else {
|
||||
network_log("Discarded %d bytes packet because the queue is full.\n", src_pkt->len);
|
||||
network_dump_packet(src_pkt);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -434,6 +457,12 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin
|
||||
card->host_drv = net_pcap_drv;
|
||||
card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name);
|
||||
break;
|
||||
#ifdef HAS_VDE
|
||||
case NET_TYPE_VDE:
|
||||
card->host_drv = net_vde_drv;
|
||||
card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!card->host_drv.priv) {
|
||||
@@ -617,6 +646,8 @@ network_dev_available(int id)
|
||||
if ((net_cards_conf[id].net_type == NET_TYPE_PCAP && (network_dev_to_id(net_cards_conf[id].host_dev_name) <= 0)))
|
||||
available = 0;
|
||||
|
||||
// TODO: Handle VDE device
|
||||
|
||||
return available;
|
||||
}
|
||||
|
||||
|
@@ -37,13 +37,17 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui)
|
||||
auto *net_type_cbox = findChild<QComboBox *>(QString("comboBoxNet%1").arg(i + 1));
|
||||
auto *intf_cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
|
||||
auto *conf_btn = findChild<QPushButton *>(QString("pushButtonConf%1").arg(i + 1));
|
||||
auto *socket_line = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i + 1));
|
||||
|
||||
int netType = net_type_cbox->currentData().toInt();
|
||||
bool adaptersEnabled = netType == NET_TYPE_SLIRP || (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0);
|
||||
bool adaptersEnabled = netType == NET_TYPE_SLIRP
|
||||
|| NET_TYPE_VDE
|
||||
|| (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0);
|
||||
|
||||
intf_cbox->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_PCAP);
|
||||
nic_cbox->setEnabled(adaptersEnabled);
|
||||
conf_btn->setEnabled(adaptersEnabled && network_card_has_config(nic_cbox->currentData().toInt()));
|
||||
socket_line->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_VDE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +63,7 @@ SettingsNetwork::SettingsNetwork(QWidget *parent)
|
||||
auto *nic_cbox = findChild<QComboBox *>(QString("comboBoxNIC%1").arg(i + 1));
|
||||
auto *net_type_cbox = findChild<QComboBox *>(QString("comboBoxNet%1").arg(i + 1));
|
||||
auto *intf_cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
|
||||
auto *socket_line = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i + 1));
|
||||
connect(nic_cbox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged);
|
||||
connect(net_type_cbox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged);
|
||||
connect(intf_cbox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged);
|
||||
@@ -75,12 +80,18 @@ SettingsNetwork::save()
|
||||
{
|
||||
for (int i = 0; i < NET_CARD_MAX; ++i) {
|
||||
auto *cbox = findChild<QComboBox *>(QString("comboBoxNIC%1").arg(i + 1));
|
||||
auto *socket_line = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i + 1));
|
||||
net_cards_conf[i].device_num = cbox->currentData().toInt();
|
||||
cbox = findChild<QComboBox *>(QString("comboBoxNet%1").arg(i + 1));
|
||||
net_cards_conf[i].net_type = cbox->currentData().toInt();
|
||||
cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
|
||||
memset(net_cards_conf[i].host_dev_name, '\0', sizeof(net_cards_conf[i].host_dev_name));
|
||||
strncpy(net_cards_conf[i].host_dev_name, network_devs[cbox->currentData().toInt()].device, sizeof(net_cards_conf[i].host_dev_name) - 1);
|
||||
if (net_cards_conf[i].net_type == NET_TYPE_PCAP) {
|
||||
strncpy(net_cards_conf[i].host_dev_name, network_devs[cbox->currentData().toInt()].device, sizeof(net_cards_conf[i].host_dev_name) - 1);
|
||||
} else if (net_cards_conf[i].net_type == NET_TYPE_VDE) {
|
||||
const char *str_socket = socket_line->text().toStdString().c_str();
|
||||
strncpy(net_cards_conf[i].host_dev_name, str_socket, strlen(str_socket));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,26 +135,37 @@ SettingsNetwork::onCurrentMachineChanged(int machineId)
|
||||
removeRows = model->rowCount();
|
||||
Models::AddEntry(model, tr("None"), NET_TYPE_NONE);
|
||||
Models::AddEntry(model, "SLiRP", NET_TYPE_SLIRP);
|
||||
|
||||
if (network_ndev > 1) {
|
||||
Models::AddEntry(model, "PCap", NET_TYPE_PCAP);
|
||||
}
|
||||
if (network_devmap.has_vde) {
|
||||
Models::AddEntry(model, "VDE", NET_TYPE_VDE);
|
||||
}
|
||||
|
||||
model->removeRows(0, removeRows);
|
||||
cbox->setCurrentIndex(net_cards_conf[i].net_type);
|
||||
|
||||
selectedRow = 0;
|
||||
|
||||
QString currentPcapDevice = net_cards_conf[i].host_dev_name;
|
||||
cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
|
||||
model = cbox->model();
|
||||
removeRows = model->rowCount();
|
||||
for (int c = 0; c < network_ndev; c++) {
|
||||
Models::AddEntry(model, tr(network_devs[c].description), c);
|
||||
if (QString(network_devs[c].device) == currentPcapDevice) {
|
||||
selectedRow = c;
|
||||
if (net_cards_conf[i].net_type == NET_TYPE_PCAP) {
|
||||
QString currentPcapDevice = net_cards_conf[i].host_dev_name;
|
||||
cbox = findChild<QComboBox *>(QString("comboBoxIntf%1").arg(i + 1));
|
||||
model = cbox->model();
|
||||
removeRows = model->rowCount();
|
||||
for (int c = 0; c < network_ndev; c++) {
|
||||
Models::AddEntry(model, tr(network_devs[c].description), c);
|
||||
if (QString(network_devs[c].device) == currentPcapDevice) {
|
||||
selectedRow = c;
|
||||
}
|
||||
}
|
||||
model->removeRows(0, removeRows);
|
||||
cbox->setCurrentIndex(selectedRow);
|
||||
} else if (net_cards_conf[i].net_type == NET_TYPE_VDE) {
|
||||
QString currentVdeSocket = net_cards_conf[i].host_dev_name;
|
||||
auto editline = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i+1));
|
||||
editline->setText(currentVdeSocket);
|
||||
}
|
||||
model->removeRows(0, removeRows);
|
||||
cbox->setCurrentIndex(selectedRow);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -36,19 +36,6 @@
|
||||
<string>Network Card #1</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxNIC1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
@@ -62,14 +49,17 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxNet1">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxNIC1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
@@ -98,17 +88,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxNet1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
@@ -121,7 +108,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -134,6 +121,33 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="socketVDENIC1">
|
||||
<property name="maxLength">
|
||||
<number>127</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>VDE Socket</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
@@ -141,6 +155,36 @@
|
||||
<string>Network Card #2</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="5" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxIntf2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConf2">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
@@ -154,19 +198,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="sizePolicy">
|
||||
@@ -193,6 +224,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxNet2">
|
||||
<property name="sizePolicy">
|
||||
@@ -203,25 +247,28 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxIntf2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConf2">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
<string>VDE Socket</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="socketVDENIC2"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Network Card #3</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="socketVDENIC3"/>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@@ -233,23 +280,6 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Network Card #3</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxNet3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="sizePolicy">
|
||||
@@ -263,17 +293,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxNet3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
@@ -299,19 +326,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConf3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxNIC3">
|
||||
<property name="sizePolicy">
|
||||
@@ -325,41 +339,8 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>Network Card #4</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxNIC4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConf4">
|
||||
<widget class="QPushButton" name="pushButtonConf3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -371,14 +352,44 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxNet4">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>VDE Socket </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>Network Card #4</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Adapter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
@@ -394,29 +405,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Adapter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxIntf4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="sizePolicy">
|
||||
@@ -430,7 +418,43 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxNIC4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxNet4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConf4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -443,6 +467,26 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBoxIntf4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="socketVDENIC4"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>VDE Socket</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
Reference in New Issue
Block a user