networking: add Linux-specific TAP mode to network interface

This addition was motivated by my lack of knowledge of VDE and my
familiarity with the Linux networking stack. The driver automatically
manages the creation of TAP devices and their association with bridges,
such that configurations which specify the same bridge will be connected
together. It also automatically handles the creation of bridge devices for
convenience's sake.
This commit is contained in:
Doug Johnson
2023-08-06 20:11:36 -06:00
parent 80f5c47221
commit 45bcbc75fd
8 changed files with 463 additions and 18 deletions

View File

@@ -1061,6 +1061,9 @@ MediaMenu::nicUpdateMenu(int i)
case NET_TYPE_VDE:
netType = "VDE";
break;
case NET_TYPE_TAP:
netType = "TAP";
break;
}
QString devName = DeviceConfig::DeviceName(network_card_getdevice(net_cards_conf[i].device_num), network_card_get_internal_name(net_cards_conf[i].device_num), 1);

View File

@@ -38,12 +38,13 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui)
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));
auto *bridge_line = findChild<QLineEdit *>(QString("bridgeTAPNIC%1").arg(i + 1));
int netType = net_type_cbox->currentData().toInt();
bool adaptersEnabled = netType == NET_TYPE_NONE
|| netType == NET_TYPE_SLIRP
|| netType == NET_TYPE_VDE
|| (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0);
|| (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0)
|| netType == NET_TYPE_TAP;
intf_cbox->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_PCAP);
nic_cbox->setEnabled(adaptersEnabled);
@@ -54,6 +55,7 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui)
else
conf_btn->setEnabled(adaptersEnabled && network_card_has_config(nic_cbox->currentData().toInt()));
socket_line->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_VDE);
bridge_line->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_TAP);
}
}
@@ -86,6 +88,7 @@ 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));
auto *bridge_line = findChild<QLineEdit *>(QString("bridgeTAPNIC%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();
@@ -95,6 +98,8 @@ SettingsNetwork::save()
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) {
strncpy(net_cards_conf[i].host_dev_name, socket_line->text().toUtf8().constData(), sizeof(net_cards_conf[i].host_dev_name));
} else if (net_cards_conf[i].net_type == NET_TYPE_TAP) {
strncpy(net_cards_conf[i].host_dev_name, bridge_line->text().toUtf8().constData(), sizeof(net_cards_conf[i].host_dev_name));
}
}
}
@@ -152,7 +157,7 @@ SettingsNetwork::onCurrentMachineChanged(int machineId)
if (network_devmap.has_vde) {
Models::AddEntry(model, "VDE", NET_TYPE_VDE);
}
Models::AddEntry(model, "TAP", NET_TYPE_TAP);
model->removeRows(0, removeRows);
cbox->setCurrentIndex(net_cards_conf[i].net_type);
@@ -171,12 +176,17 @@ SettingsNetwork::onCurrentMachineChanged(int machineId)
}
model->removeRows(0, removeRows);
cbox->setCurrentIndex(selectedRow);
}
}
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);
}
else if (net_cards_conf[i].net_type == NET_TYPE_TAP) {
QString currentTapDevice = net_cards_conf[i].host_dev_name;
auto editline = findChild<QLineEdit *>(QString("bridgeTAPNIC%1").arg(i+1));
editline->setText(currentTapDevice);
}
}
}

View File

@@ -144,7 +144,21 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="4" column="0">
<widget class="QLabel" name="labelBridgeTAPNIC1">
<property name="text">
<string>TAP Bridge Device</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QLineEdit" name="bridgeTAPNIC1">
<property name="maxLength">
<number>127</number>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -259,6 +273,13 @@
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QLineEdit" name="bridgeTAPNIC2">
<property name="maxLength">
<number>127</number>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="socketVDENIC2">
<property name="maxLength">
@@ -266,7 +287,14 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="4" column="0">
<widget class="QLabel" name="labelBridgeTAPNIC2">
<property name="text">
<string>TAP Bridge Device</string>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -394,7 +422,21 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="4" column="0">
<widget class="QLabel" name="labelBridgeTAPNIC3">
<property name="text">
<string>TAP Bridge Device</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QLineEdit" name="bridgeTAPNIC3">
<property name="maxLength">
<number>127</number>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -508,13 +550,6 @@
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="socketVDENIC4">
<property name="maxLength">
<number>127</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
@@ -522,7 +557,28 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="socketVDENIC4">
<property name="maxLength">
<number>127</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelBridgeTAPNIC4">
<property name="text">
<string>TAP Bridge Device</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QLineEdit" name="bridgeTAPNIC4">
<property name="maxLength">
<number>127</number>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>