feat(NetworkConfigManager): add MTU configuration support for interfaces, enhancing flexibility in tunnel settings and improving user input handling
Publish Fast Tabler Docker image / build-and-push-fast (push) Failing after 1m9s

This commit is contained in:
2026-01-22 23:59:01 +07:00
parent 26f8a97c21
commit 2157c6a3c7
+45 -5
View File
@@ -84,6 +84,7 @@ const getEmptyInterface = () => ({
serverId2: '', // Второй сервер (опциональный)
ipsecPasswordId: '', // ID IPSec пароля (опционально, только для IPSec)
ipPoolId: '', // ID IP пула для выбора IP адресов (опционально)
mtu: '', // MTU (опционально)
});
const getEmptyIpPool = () => ({
@@ -145,6 +146,7 @@ function NetworkConfigManager() {
const [templateName2, setTemplateName2] = useState(''); // Опциональное имя для сервера 2
const [templateIpsecPasswordId, setTemplateIpsecPasswordId] = useState(''); // Выбранный IPSec пароль
const [templateIpPoolId, setTemplateIpPoolId] = useState(''); // Выбранный IP пул
const [templateMtu, setTemplateMtu] = useState(''); // MTU для шаблона
const [templateTunnelCount, setTemplateTunnelCount] = useState(1); // Количество туннелей для создания
const [templateServerPairs, setTemplateServerPairs] = useState([]); // Массив пар серверов для множественного создания
@@ -554,6 +556,9 @@ function NetworkConfigManager() {
const name1 = (pair.name1?.trim() || baseName1).toUpperCase();
const name2 = (pair.name2?.trim() || baseName2).toUpperCase();
// Используем настройки из пары или глобальные для MTU
const pairMtu = pair.mtu || templateMtu;
// Используем настройки из пары или глобальные
const pairIpsecPasswordId = pair.ipsecPasswordId || templateIpsecPasswordId;
const pairIpPoolId = pair.ipPoolId || templateIpPoolId;
@@ -586,6 +591,9 @@ function NetworkConfigManager() {
return;
}
// Используем настройки из пары или глобальные для MTU
const pairMtu = pair.mtu || templateMtu;
// Создаем интерфейс
const newInterface = {
...getEmptyInterface(),
@@ -597,7 +605,8 @@ function NetworkConfigManager() {
serverId: pair.server1,
serverId2: pair.server2,
ipsecPasswordId: (templateType === 'IPSec' || templateType === 'GRE') && pairIpsecPasswordId ? pairIpsecPasswordId : '',
ipPoolId: pairIpPoolId || ''
ipPoolId: pairIpPoolId || '',
mtu: pairMtu || ''
};
// Проверяем конфликты с существующими интерфейсами
@@ -632,6 +641,7 @@ function NetworkConfigManager() {
setTemplateName2('');
setTemplateIpsecPasswordId('');
setTemplateIpPoolId('');
setTemplateMtu('');
setTemplateTunnelCount(1);
setTemplateServerPairs([]);
return;
@@ -684,7 +694,8 @@ function NetworkConfigManager() {
serverId: templateServer1,
serverId2: templateServer2,
ipsecPasswordId: (templateType === 'IPSec' || templateType === 'GRE') && templateIpsecPasswordId ? templateIpsecPasswordId : '',
ipPoolId: templateIpPoolId || ''
ipPoolId: templateIpPoolId || '',
mtu: templateMtu || ''
};
const conflicts = checkInterfaceIpConflict(newInterface);
@@ -711,6 +722,7 @@ function NetworkConfigManager() {
setTemplateName2('');
setTemplateIpsecPasswordId('');
setTemplateIpPoolId('');
setTemplateMtu('');
setTemplateTunnelCount(1);
};
@@ -1383,7 +1395,8 @@ function NetworkConfigManager() {
server2Name,
server2Info: server2,
ipsecPasswordId: (iface.ipsecPasswordId && iface.ipsecPasswordId.trim() !== '') ? iface.ipsecPasswordId.trim() : null,
ipsecPassword: (iface.ipsecPasswordId && iface.ipsecPasswordId.trim() !== '') ? (passwordMap[iface.ipsecPasswordId.trim()] || null) : null
ipsecPassword: (iface.ipsecPasswordId && iface.ipsecPasswordId.trim() !== '') ? (passwordMap[iface.ipsecPasswordId.trim()] || null) : null,
mtu: iface.mtu || null
});
// Для второго сервера - МЕНЯЕМ МЕСТАМИ: remoteIp становится localIp, localIp становится remoteIp
@@ -1445,12 +1458,14 @@ function NetworkConfigManager() {
if (hasIpsecPassword) {
// GRE туннель с IPSec через ipsec-secret (автоматическая настройка)
code += `# Создание GRE туннеля с IPSec (автоматическая настройка через ipsec-secret)\n`;
code += `/interface gre add name="${iface.interfaceName}" remote-address=${remoteAddress} keepalive=10s ipsec-secret="${iface.ipsecPassword}"\n`;
const mtuParam = iface.mtu ? ` mtu=${iface.mtu}` : '';
code += `/interface gre add name="${iface.interfaceName}" remote-address=${remoteAddress} keepalive=10s allow-fast-path=no ipsec-secret="${iface.ipsecPassword}"${mtuParam}\n`;
code += '\n';
} else {
// GRE туннель без IPSec (голый GRE)
code += `# Создание GRE туннеля (без IPSec)\n`;
code += `/interface gre add name="${iface.interfaceName}" remote-address=${remoteAddress} keepalive=10s\n`;
const mtuParam = iface.mtu ? ` mtu=${iface.mtu}` : '';
code += `/interface gre add name="${iface.interfaceName}" remote-address=${remoteAddress} keepalive=10s allow-fast-path=no${mtuParam}\n`;
code += '\n';
}
}
@@ -3162,6 +3177,17 @@ function NetworkConfigManager() {
Выберите IP пул для подбора адресов или оставьте автоматический подбор
</div>
</div>
<div className="col-md-6">
<FormField
label="MTU"
name="mtu"
value={editingInterface.mtu || ''}
onChange={(val) => setEditingInterface({ ...editingInterface, mtu: val })}
placeholder="1500"
type="number"
/>
<div className="form-text">Максимальный размер передаваемого пакета (опционально)</div>
</div>
<div className="col-md-3">
<label className="form-label">Local IP</label>
<div className="input-group">
@@ -3317,6 +3343,7 @@ function NetworkConfigManager() {
setTemplateName2('');
setTemplateIpsecPasswordId('');
setTemplateIpPoolId('');
setTemplateMtu('');
setTemplateTunnelCount(1);
setTemplateServerPairs([]);
}}
@@ -3643,6 +3670,19 @@ function NetworkConfigManager() {
Выберите IP пул для подбора адресов или оставьте автоматический подбор. Будет использован для всех туннелей, если не указан индивидуально.
</div>
</div>
<div className="col-md-6">
<label className="form-label">MTU (глобальный, используется если не указан для пары)</label>
<input
type="number"
className="form-control"
value={templateMtu}
onChange={(e) => setTemplateMtu(e.target.value)}
placeholder="1500"
/>
<div className="form-text">
Максимальный размер передаваемого пакета (опционально). Будет использован для всех туннелей, если не указан индивидуально.
</div>
</div>
{templateTunnelCount === 1 && templateServer1 && templateServer2 && templateServer1 !== templateServer2 && (() => {
const server1 = getServerInfo(templateServer1);
const server2 = getServerInfo(templateServer2);