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: '', // Второй сервер (опциональный) serverId2: '', // Второй сервер (опциональный)
ipsecPasswordId: '', // ID IPSec пароля (опционально, только для IPSec) ipsecPasswordId: '', // ID IPSec пароля (опционально, только для IPSec)
ipPoolId: '', // ID IP пула для выбора IP адресов (опционально) ipPoolId: '', // ID IP пула для выбора IP адресов (опционально)
mtu: '', // MTU (опционально)
}); });
const getEmptyIpPool = () => ({ const getEmptyIpPool = () => ({
@@ -145,6 +146,7 @@ function NetworkConfigManager() {
const [templateName2, setTemplateName2] = useState(''); // Опциональное имя для сервера 2 const [templateName2, setTemplateName2] = useState(''); // Опциональное имя для сервера 2
const [templateIpsecPasswordId, setTemplateIpsecPasswordId] = useState(''); // Выбранный IPSec пароль const [templateIpsecPasswordId, setTemplateIpsecPasswordId] = useState(''); // Выбранный IPSec пароль
const [templateIpPoolId, setTemplateIpPoolId] = useState(''); // Выбранный IP пул const [templateIpPoolId, setTemplateIpPoolId] = useState(''); // Выбранный IP пул
const [templateMtu, setTemplateMtu] = useState(''); // MTU для шаблона
const [templateTunnelCount, setTemplateTunnelCount] = useState(1); // Количество туннелей для создания const [templateTunnelCount, setTemplateTunnelCount] = useState(1); // Количество туннелей для создания
const [templateServerPairs, setTemplateServerPairs] = useState([]); // Массив пар серверов для множественного создания const [templateServerPairs, setTemplateServerPairs] = useState([]); // Массив пар серверов для множественного создания
@@ -554,6 +556,9 @@ function NetworkConfigManager() {
const name1 = (pair.name1?.trim() || baseName1).toUpperCase(); const name1 = (pair.name1?.trim() || baseName1).toUpperCase();
const name2 = (pair.name2?.trim() || baseName2).toUpperCase(); const name2 = (pair.name2?.trim() || baseName2).toUpperCase();
// Используем настройки из пары или глобальные для MTU
const pairMtu = pair.mtu || templateMtu;
// Используем настройки из пары или глобальные // Используем настройки из пары или глобальные
const pairIpsecPasswordId = pair.ipsecPasswordId || templateIpsecPasswordId; const pairIpsecPasswordId = pair.ipsecPasswordId || templateIpsecPasswordId;
const pairIpPoolId = pair.ipPoolId || templateIpPoolId; const pairIpPoolId = pair.ipPoolId || templateIpPoolId;
@@ -586,6 +591,9 @@ function NetworkConfigManager() {
return; return;
} }
// Используем настройки из пары или глобальные для MTU
const pairMtu = pair.mtu || templateMtu;
// Создаем интерфейс // Создаем интерфейс
const newInterface = { const newInterface = {
...getEmptyInterface(), ...getEmptyInterface(),
@@ -597,7 +605,8 @@ function NetworkConfigManager() {
serverId: pair.server1, serverId: pair.server1,
serverId2: pair.server2, serverId2: pair.server2,
ipsecPasswordId: (templateType === 'IPSec' || templateType === 'GRE') && pairIpsecPasswordId ? pairIpsecPasswordId : '', ipsecPasswordId: (templateType === 'IPSec' || templateType === 'GRE') && pairIpsecPasswordId ? pairIpsecPasswordId : '',
ipPoolId: pairIpPoolId || '' ipPoolId: pairIpPoolId || '',
mtu: pairMtu || ''
}; };
// Проверяем конфликты с существующими интерфейсами // Проверяем конфликты с существующими интерфейсами
@@ -632,6 +641,7 @@ function NetworkConfigManager() {
setTemplateName2(''); setTemplateName2('');
setTemplateIpsecPasswordId(''); setTemplateIpsecPasswordId('');
setTemplateIpPoolId(''); setTemplateIpPoolId('');
setTemplateMtu('');
setTemplateTunnelCount(1); setTemplateTunnelCount(1);
setTemplateServerPairs([]); setTemplateServerPairs([]);
return; return;
@@ -684,7 +694,8 @@ function NetworkConfigManager() {
serverId: templateServer1, serverId: templateServer1,
serverId2: templateServer2, serverId2: templateServer2,
ipsecPasswordId: (templateType === 'IPSec' || templateType === 'GRE') && templateIpsecPasswordId ? templateIpsecPasswordId : '', ipsecPasswordId: (templateType === 'IPSec' || templateType === 'GRE') && templateIpsecPasswordId ? templateIpsecPasswordId : '',
ipPoolId: templateIpPoolId || '' ipPoolId: templateIpPoolId || '',
mtu: templateMtu || ''
}; };
const conflicts = checkInterfaceIpConflict(newInterface); const conflicts = checkInterfaceIpConflict(newInterface);
@@ -711,6 +722,7 @@ function NetworkConfigManager() {
setTemplateName2(''); setTemplateName2('');
setTemplateIpsecPasswordId(''); setTemplateIpsecPasswordId('');
setTemplateIpPoolId(''); setTemplateIpPoolId('');
setTemplateMtu('');
setTemplateTunnelCount(1); setTemplateTunnelCount(1);
}; };
@@ -1383,7 +1395,8 @@ function NetworkConfigManager() {
server2Name, server2Name,
server2Info: server2, server2Info: server2,
ipsecPasswordId: (iface.ipsecPasswordId && iface.ipsecPasswordId.trim() !== '') ? iface.ipsecPasswordId.trim() : null, 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 // Для второго сервера - МЕНЯЕМ МЕСТАМИ: remoteIp становится localIp, localIp становится remoteIp
@@ -1445,12 +1458,14 @@ function NetworkConfigManager() {
if (hasIpsecPassword) { if (hasIpsecPassword) {
// GRE туннель с IPSec через ipsec-secret (автоматическая настройка) // GRE туннель с IPSec через ipsec-secret (автоматическая настройка)
code += `# Создание GRE туннеля с IPSec (автоматическая настройка через ipsec-secret)\n`; 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'; code += '\n';
} else { } else {
// GRE туннель без IPSec (голый GRE) // GRE туннель без IPSec (голый GRE)
code += `# Создание GRE туннеля (без IPSec)\n`; 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'; code += '\n';
} }
} }
@@ -3162,6 +3177,17 @@ function NetworkConfigManager() {
Выберите IP пул для подбора адресов или оставьте автоматический подбор Выберите IP пул для подбора адресов или оставьте автоматический подбор
</div> </div>
</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"> <div className="col-md-3">
<label className="form-label">Local IP</label> <label className="form-label">Local IP</label>
<div className="input-group"> <div className="input-group">
@@ -3317,6 +3343,7 @@ function NetworkConfigManager() {
setTemplateName2(''); setTemplateName2('');
setTemplateIpsecPasswordId(''); setTemplateIpsecPasswordId('');
setTemplateIpPoolId(''); setTemplateIpPoolId('');
setTemplateMtu('');
setTemplateTunnelCount(1); setTemplateTunnelCount(1);
setTemplateServerPairs([]); setTemplateServerPairs([]);
}} }}
@@ -3643,6 +3670,19 @@ function NetworkConfigManager() {
Выберите IP пул для подбора адресов или оставьте автоматический подбор. Будет использован для всех туннелей, если не указан индивидуально. Выберите IP пул для подбора адресов или оставьте автоматический подбор. Будет использован для всех туннелей, если не указан индивидуально.
</div> </div>
</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 && (() => { {templateTunnelCount === 1 && templateServer1 && templateServer2 && templateServer1 !== templateServer2 && (() => {
const server1 = getServerInfo(templateServer1); const server1 = getServerInfo(templateServer1);
const server2 = getServerInfo(templateServer2); const server2 = getServerInfo(templateServer2);