|
@@ -1762,7 +1762,86 @@ async function deleteWGPeer(iface, pubkey) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// ======================== IPSec Multi-Tunnel ========================
|
|
|
|
|
|
|
+// ======================== IPSec FortiGate Phase 1 & 2 Multi-Tunnel Engine ========================
|
|
|
|
|
+function switchIpsecModalTab(tab) {
|
|
|
|
|
+ const p1Tab = document.getElementById('tab-btn-ipsec-p1');
|
|
|
|
|
+ const p2Tab = document.getElementById('tab-btn-ipsec-p2');
|
|
|
|
|
+ const p1Content = document.getElementById('ipsec-tab-content-p1');
|
|
|
|
|
+ const p2Content = document.getElementById('ipsec-tab-content-p2');
|
|
|
|
|
+ const stepBtn = document.getElementById('btn-ipsec-switch-step');
|
|
|
|
|
+
|
|
|
|
|
+ if (tab === 'p1') {
|
|
|
|
|
+ if (p1Tab) {
|
|
|
|
|
+ p1Tab.className = 'px-4 py-2 text-xs font-bold border-b-2 border-amber-500 text-amber-300 transition flex items-center gap-2';
|
|
|
|
|
+ }
|
|
|
|
|
+ if (p2Tab) {
|
|
|
|
|
+ p2Tab.className = 'px-4 py-2 text-xs font-bold border-b-2 border-transparent text-slate-400 hover:text-slate-200 transition flex items-center gap-2';
|
|
|
|
|
+ }
|
|
|
|
|
+ if (p1Content) p1Content.classList.remove('hidden');
|
|
|
|
|
+ if (p2Content) p2Content.classList.add('hidden');
|
|
|
|
|
+ if (stepBtn) stepBtn.innerHTML = 'Next: Phase 2 Selectors →';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (p1Tab) {
|
|
|
|
|
+ p1Tab.className = 'px-4 py-2 text-xs font-bold border-b-2 border-transparent text-slate-400 hover:text-slate-200 transition flex items-center gap-2';
|
|
|
|
|
+ }
|
|
|
|
|
+ if (p2Tab) {
|
|
|
|
|
+ p2Tab.className = 'px-4 py-2 text-xs font-bold border-b-2 border-cyan-500 text-cyan-300 transition flex items-center gap-2';
|
|
|
|
|
+ }
|
|
|
|
|
+ if (p1Content) p1Content.classList.add('hidden');
|
|
|
|
|
+ if (p2Content) p2Content.classList.remove('hidden');
|
|
|
|
|
+ if (stepBtn) stepBtn.innerHTML = '← Back: Phase 1 (IKE)';
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function toggleIpsecPhaseStep() {
|
|
|
|
|
+ const p1Content = document.getElementById('ipsec-tab-content-p1');
|
|
|
|
|
+ if (p1Content && !p1Content.classList.contains('hidden')) {
|
|
|
|
|
+ switchIpsecModalTab('p2');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ switchIpsecModalTab('p1');
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function toggleIpsecPskVisibility() {
|
|
|
|
|
+ const pskInput = document.getElementById('ipsec-modal-psk');
|
|
|
|
|
+ if (!pskInput) return;
|
|
|
|
|
+ pskInput.type = pskInput.type === 'password' ? 'text' : 'password';
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function addIpsecLocalSubnet(val = '') {
|
|
|
|
|
+ const container = document.getElementById('ipsec-modal-local-subnets-container');
|
|
|
|
|
+ if (!container) return;
|
|
|
|
|
+ const row = document.createElement('div');
|
|
|
|
|
+ row.className = 'flex items-center gap-2 ipsec-subnet-row';
|
|
|
|
|
+ row.innerHTML = `
|
|
|
|
|
+ <input type="text" value="${escapeHtml(val)}" placeholder="e.g. 192.168.10.0/24 or 10.0.1.0/24" class="flex-1 bg-slate-900 border border-slate-700 rounded-lg px-3 py-1.5 text-white font-mono text-xs focus:outline-none focus:border-cyan-500">
|
|
|
|
|
+ <button type="button" onclick="this.closest('.ipsec-subnet-row').remove()" class="w-7 h-7 flex items-center justify-center bg-slate-800 hover:bg-rose-950 text-slate-400 hover:text-rose-400 border border-slate-700 rounded-lg text-base font-bold transition" title="Remove local subnet">-</button>
|
|
|
|
|
+ `;
|
|
|
|
|
+ container.appendChild(row);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function addIpsecRemoteSubnet(val = '') {
|
|
|
|
|
+ const container = document.getElementById('ipsec-modal-remote-subnets-container');
|
|
|
|
|
+ if (!container) return;
|
|
|
|
|
+ const row = document.createElement('div');
|
|
|
|
|
+ row.className = 'flex items-center gap-2 ipsec-subnet-row';
|
|
|
|
|
+ row.innerHTML = `
|
|
|
|
|
+ <input type="text" value="${escapeHtml(val)}" placeholder="e.g. 192.168.20.0/24 or 10.0.2.0/24" class="flex-1 bg-slate-900 border border-slate-700 rounded-lg px-3 py-1.5 text-white font-mono text-xs focus:outline-none focus:border-purple-500">
|
|
|
|
|
+ <button type="button" onclick="this.closest('.ipsec-subnet-row').remove()" class="w-7 h-7 flex items-center justify-center bg-slate-800 hover:bg-rose-950 text-slate-400 hover:text-rose-400 border border-slate-700 rounded-lg text-base font-bold transition" title="Remove remote subnet">-</button>
|
|
|
|
|
+ `;
|
|
|
|
|
+ container.appendChild(row);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function updateIpsecEspProposalFromPFS(val) {
|
|
|
|
|
+ const prop = document.getElementById('ipsec-modal-espprop');
|
|
|
|
|
+ if (!prop) return;
|
|
|
|
|
+ if (val === 'none') {
|
|
|
|
|
+ prop.value = 'aes256-sha256,aes128-sha256,default';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ prop.value = `aes256-sha256-${val},aes128-sha256-${val},default`;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
async function loadIPSec(populateInputs = true) {
|
|
async function loadIPSec(populateInputs = true) {
|
|
|
try {
|
|
try {
|
|
|
const res = await fetch(`${API_BASE}/vpn/ipsec/tunnels`);
|
|
const res = await fetch(`${API_BASE}/vpn/ipsec/tunnels`);
|
|
@@ -1785,28 +1864,82 @@ async function loadIPSec(populateInputs = true) {
|
|
|
state.ipsecTunnels.forEach(c => {
|
|
state.ipsecTunnels.forEach(c => {
|
|
|
const isEstablished = c.running || c.status === 'ESTABLISHED';
|
|
const isEstablished = c.running || c.status === 'ESTABLISHED';
|
|
|
const tr = document.createElement('tr');
|
|
const tr = document.createElement('tr');
|
|
|
- tr.className = 'hover:bg-slate-800/40 transition text-xs';
|
|
|
|
|
|
|
+ tr.className = 'hover:bg-slate-800/40 transition text-xs select-none';
|
|
|
|
|
+
|
|
|
|
|
+ // Local subnets tags
|
|
|
|
|
+ const localList = (c.local_subnets && c.local_subnets.length > 0) ? c.local_subnets : (c.local_subnet ? [c.local_subnet] : ['0.0.0.0/0']);
|
|
|
|
|
+ const localBadges = localList.map(s => `<span class="px-1.5 py-0.5 rounded bg-cyan-950/60 border border-cyan-800/60 text-cyan-300 font-mono text-[10px] mr-1">${escapeHtml(s)}</span>`).join('');
|
|
|
|
|
+
|
|
|
|
|
+ // Remote subnets tags
|
|
|
|
|
+ const remoteList = (c.remote_subnets && c.remote_subnets.length > 0) ? c.remote_subnets : (c.remote_subnet ? [c.remote_subnet] : ['0.0.0.0/0']);
|
|
|
|
|
+ const remoteBadges = remoteList.map(s => `<span class="px-1.5 py-0.5 rounded bg-purple-950/60 border border-purple-800/60 text-purple-300 font-mono text-[10px] mr-1">${escapeHtml(s)}</span>`).join('');
|
|
|
|
|
+
|
|
|
|
|
+ const ikeVersionBadge = (c.ike_version || 'ikev2').toUpperCase();
|
|
|
|
|
+ const p2Name = c.phase2_name || `${c.name}_p2`;
|
|
|
|
|
+
|
|
|
tr.innerHTML = `
|
|
tr.innerHTML = `
|
|
|
- <td class="py-2.5 px-3 text-center">${renderMikroTikFlag(isEstablished, c.disabled)}</td>
|
|
|
|
|
- <td class="py-2.5 px-4 font-bold text-white">${c.name}</td>
|
|
|
|
|
- <td class="py-2.5 px-4 text-emerald-400 font-mono">${c.local_subnet || '-'}</td>
|
|
|
|
|
- <td class="py-2.5 px-4 text-slate-300 font-mono">${c.remote_addrs || '-'}</td>
|
|
|
|
|
- <td class="py-2.5 px-4 text-cyan-400 font-mono">${c.remote_subnet || '-'}</td>
|
|
|
|
|
|
|
+ <td class="py-2.5 px-3 text-center">
|
|
|
|
|
+ ${isEstablished ? `
|
|
|
|
|
+ <span class="inline-flex items-center gap-1.5 text-emerald-400 font-mono font-bold text-[11px]" title="Active SA Established">
|
|
|
|
|
+ <span class="w-2.5 h-2.5 rounded-full bg-emerald-400 animate-pulse"></span>
|
|
|
|
|
+ <span>UP</span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ ` : (c.disabled ? `
|
|
|
|
|
+ <span class="inline-flex items-center gap-1.5 text-slate-500 font-mono text-[11px]" title="Tunnel Disabled">
|
|
|
|
|
+ <span class="w-2 h-2 rounded-full bg-rose-500"></span>
|
|
|
|
|
+ <span>DOWN</span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ ` : `
|
|
|
|
|
+ <span class="inline-flex items-center gap-1.5 text-amber-400 font-mono text-[11px]" title="Disconnected / Idle">
|
|
|
|
|
+ <span class="w-2 h-2 rounded-full bg-amber-400"></span>
|
|
|
|
|
+ <span>IDLE</span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ `)}
|
|
|
|
|
+ </td>
|
|
|
|
|
+ <td class="py-2.5 px-4 font-bold text-white">
|
|
|
|
|
+ <div class="flex items-center gap-2">
|
|
|
|
|
+ <span class="text-amber-400">🛡</span>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <div>${escapeHtml(c.name)}</div>
|
|
|
|
|
+ <div class="text-[10px] text-slate-500 font-normal">P2: ${escapeHtml(p2Name)}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ <td class="py-2.5 px-4 text-slate-300 font-mono font-medium">${escapeHtml(c.remote_addrs || '%any')}</td>
|
|
|
<td class="py-2.5 px-4 font-sans">
|
|
<td class="py-2.5 px-4 font-sans">
|
|
|
- <span class="px-2 py-0.5 rounded-full text-[10px] font-semibold ${
|
|
|
|
|
- isEstablished ? 'bg-emerald-500/10 text-emerald-400 border border-emerald-500/30' : 'bg-slate-800 text-slate-400'
|
|
|
|
|
- }">${c.status || (isEstablished ? 'ESTABLISHED' : 'DISCONNECTED')}</span>
|
|
|
|
|
|
|
+ <div class="flex items-center gap-1.5">
|
|
|
|
|
+ <span class="px-1.5 py-0.5 rounded bg-amber-500/10 text-amber-300 border border-amber-500/30 font-mono text-[10px] font-semibold">${ikeVersionBadge}</span>
|
|
|
|
|
+ <span class="text-[10px] text-slate-400">${c.auth_method || 'PSK'}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ <td class="py-2.5 px-4">
|
|
|
|
|
+ <div class="space-y-1">
|
|
|
|
|
+ <div class="flex items-center flex-wrap gap-1">
|
|
|
|
|
+ <span class="text-[9px] text-cyan-400 uppercase font-bold mr-1">Local:</span>
|
|
|
|
|
+ ${localBadges}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="flex items-center flex-wrap gap-1">
|
|
|
|
|
+ <span class="text-[9px] text-purple-400 uppercase font-bold mr-1">Remote:</span>
|
|
|
|
|
+ ${remoteBadges}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ <td class="py-2.5 px-4 font-mono text-[11px] text-slate-400">
|
|
|
|
|
+ <div class="truncate max-w-[140px]" title="${escapeHtml(c.esp_proposals || '')}">
|
|
|
|
|
+ ${escapeHtml(c.esp_proposals || 'aes256-sha256')}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text-[10px] text-slate-500">PFS: ${escapeHtml(c.pfs_group || 'modp2048')}</div>
|
|
|
</td>
|
|
</td>
|
|
|
<td class="py-2.5 px-4 text-right space-x-2 font-sans">
|
|
<td class="py-2.5 px-4 text-right space-x-2 font-sans">
|
|
|
${isEstablished ? `
|
|
${isEstablished ? `
|
|
|
- <button onclick="stopIPSecTunnel('${c.name}')" class="text-xs text-rose-400 hover:text-rose-300">Terminate</button>
|
|
|
|
|
|
|
+ <button onclick="stopIPSecTunnel('${c.name}')" class="px-2 py-0.5 text-xs bg-rose-500/20 text-rose-400 hover:bg-rose-500/30 rounded border border-rose-500/30 font-medium">Bring Down</button>
|
|
|
` : `
|
|
` : `
|
|
|
- <button onclick="startIPSecTunnel('${c.name}')" class="text-xs bg-amber-600/30 hover:bg-amber-600/50 text-amber-300 px-2 py-0.5 rounded border border-amber-500/30">Initiate</button>
|
|
|
|
|
|
|
+ <button onclick="startIPSecTunnel('${c.name}')" class="px-2 py-0.5 text-xs bg-emerald-500/20 text-emerald-400 hover:bg-emerald-500/30 rounded border border-emerald-500/30 font-semibold">Bring Up</button>
|
|
|
`}
|
|
`}
|
|
|
<button onclick="toggleIPSecState('${c.name}', ${c.disabled ? 'true' : 'false'})" class="text-xs text-slate-400 hover:text-white">
|
|
<button onclick="toggleIPSecState('${c.name}', ${c.disabled ? 'true' : 'false'})" class="text-xs text-slate-400 hover:text-white">
|
|
|
${c.disabled ? 'Enable' : 'Disable'}
|
|
${c.disabled ? 'Enable' : 'Disable'}
|
|
|
</button>
|
|
</button>
|
|
|
- <button onclick="openEditIPSecModal('${c.name}')" class="text-xs text-slate-400 hover:text-white">Edit</button>
|
|
|
|
|
|
|
+ <button onclick="openEditIPSecModal('${c.name}')" class="text-xs text-amber-400 hover:text-amber-300">Edit</button>
|
|
|
<button onclick="deleteIPSecConn('${c.name}')" class="text-xs text-slate-500 hover:text-rose-400">Delete</button>
|
|
<button onclick="deleteIPSecConn('${c.name}')" class="text-xs text-slate-500 hover:text-rose-400">Delete</button>
|
|
|
</td>
|
|
</td>
|
|
|
`;
|
|
`;
|
|
@@ -1819,18 +1952,40 @@ async function loadIPSec(populateInputs = true) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function openAddIPSecModal() {
|
|
function openAddIPSecModal() {
|
|
|
- document.getElementById('ipsec-modal-title').innerText = 'Configure IPSec IKEv2 Tunnel';
|
|
|
|
|
- document.getElementById('ipsec-modal-name').value = `ipsec-${(state.ipsecTunnels || []).length + 1}`;
|
|
|
|
|
|
|
+ document.getElementById('ipsec-modal-title').innerText = 'Configure IPSec Site-to-Site Tunnel';
|
|
|
|
|
+
|
|
|
|
|
+ // Phase 1 Fields
|
|
|
|
|
+ document.getElementById('ipsec-modal-name').value = `tunnel-${(state.ipsecTunnels || []).length + 1}`;
|
|
|
document.getElementById('ipsec-modal-name').readOnly = false;
|
|
document.getElementById('ipsec-modal-name').readOnly = false;
|
|
|
- document.getElementById('ipsec-modal-localts').value = '192.168.10.0/24';
|
|
|
|
|
- document.getElementById('ipsec-modal-remotets').value = '192.168.20.0/24';
|
|
|
|
|
|
|
+ document.getElementById('ipsec-modal-ikeversion').value = 'ikev2';
|
|
|
document.getElementById('ipsec-modal-remotegw').value = '';
|
|
document.getElementById('ipsec-modal-remotegw').value = '';
|
|
|
document.getElementById('ipsec-modal-psk').value = '';
|
|
document.getElementById('ipsec-modal-psk').value = '';
|
|
|
- document.getElementById('ipsec-modal-ikeprop').value = 'aes256-sha256-modp2048,default';
|
|
|
|
|
- document.getElementById('ipsec-modal-espprop').value = 'aes256-sha256-modp2048,default';
|
|
|
|
|
|
|
+ document.getElementById('ipsec-modal-ikeprop').value = 'aes256-sha256-modp2048,aes128-sha256-modp2048,default';
|
|
|
|
|
+ document.getElementById('ipsec-modal-ikekeylife').value = '86400';
|
|
|
|
|
+ document.getElementById('ipsec-modal-localid').value = '';
|
|
|
|
|
+ document.getElementById('ipsec-modal-remoteid').value = '';
|
|
|
|
|
+ document.getElementById('ipsec-modal-dpd').value = 'on-demand';
|
|
|
|
|
+
|
|
|
|
|
+ // Phase 2 Fields
|
|
|
|
|
+ document.getElementById('ipsec-modal-p2name').value = `tunnel-${(state.ipsecTunnels || []).length + 1}_p2`;
|
|
|
|
|
+ document.getElementById('ipsec-modal-espprop').value = 'aes256-sha256-modp2048,aes128-sha256-modp2048,default';
|
|
|
|
|
+ document.getElementById('ipsec-modal-pfsgroup').value = 'modp2048';
|
|
|
document.getElementById('ipsec-modal-autostart').checked = true;
|
|
document.getElementById('ipsec-modal-autostart').checked = true;
|
|
|
document.getElementById('ipsec-modal-disabled').checked = false;
|
|
document.getElementById('ipsec-modal-disabled').checked = false;
|
|
|
|
|
|
|
|
|
|
+ // Clear & Populate default dynamic subnets
|
|
|
|
|
+ const localContainer = document.getElementById('ipsec-modal-local-subnets-container');
|
|
|
|
|
+ const remoteContainer = document.getElementById('ipsec-modal-remote-subnets-container');
|
|
|
|
|
+ if (localContainer) {
|
|
|
|
|
+ localContainer.innerHTML = '';
|
|
|
|
|
+ addIpsecLocalSubnet('192.168.10.0/24');
|
|
|
|
|
+ }
|
|
|
|
|
+ if (remoteContainer) {
|
|
|
|
|
+ remoteContainer.innerHTML = '';
|
|
|
|
|
+ addIpsecRemoteSubnet('192.168.20.0/24');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ switchIpsecModalTab('p1');
|
|
|
document.getElementById('ipsec-modal').classList.remove('hidden');
|
|
document.getElementById('ipsec-modal').classList.remove('hidden');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1839,17 +1994,43 @@ function openEditIPSecModal(name) {
|
|
|
if (!conn) return;
|
|
if (!conn) return;
|
|
|
|
|
|
|
|
document.getElementById('ipsec-modal-title').innerText = `Edit IPSec Tunnel: ${name}`;
|
|
document.getElementById('ipsec-modal-title').innerText = `Edit IPSec Tunnel: ${name}`;
|
|
|
|
|
+
|
|
|
|
|
+ // Phase 1 Fields
|
|
|
document.getElementById('ipsec-modal-name').value = conn.name;
|
|
document.getElementById('ipsec-modal-name').value = conn.name;
|
|
|
document.getElementById('ipsec-modal-name').readOnly = true;
|
|
document.getElementById('ipsec-modal-name').readOnly = true;
|
|
|
- document.getElementById('ipsec-modal-localts').value = conn.local_subnet || '';
|
|
|
|
|
- document.getElementById('ipsec-modal-remotets').value = conn.remote_subnet || '';
|
|
|
|
|
|
|
+ document.getElementById('ipsec-modal-ikeversion').value = conn.ike_version || 'ikev2';
|
|
|
document.getElementById('ipsec-modal-remotegw').value = conn.remote_addrs || '';
|
|
document.getElementById('ipsec-modal-remotegw').value = conn.remote_addrs || '';
|
|
|
document.getElementById('ipsec-modal-psk').value = conn.preshared_key || '';
|
|
document.getElementById('ipsec-modal-psk').value = conn.preshared_key || '';
|
|
|
document.getElementById('ipsec-modal-ikeprop').value = conn.ike_proposals || 'aes256-sha256-modp2048,default';
|
|
document.getElementById('ipsec-modal-ikeprop').value = conn.ike_proposals || 'aes256-sha256-modp2048,default';
|
|
|
|
|
+ document.getElementById('ipsec-modal-ikekeylife').value = conn.ike_keylife || 86400;
|
|
|
|
|
+ document.getElementById('ipsec-modal-localid').value = conn.local_id || '';
|
|
|
|
|
+ document.getElementById('ipsec-modal-remoteid').value = conn.remote_id || '';
|
|
|
|
|
+ document.getElementById('ipsec-modal-dpd').value = conn.dpd || 'on-demand';
|
|
|
|
|
+
|
|
|
|
|
+ // Phase 2 Fields
|
|
|
|
|
+ document.getElementById('ipsec-modal-p2name').value = conn.phase2_name || `${conn.name}_p2`;
|
|
|
document.getElementById('ipsec-modal-espprop').value = conn.esp_proposals || 'aes256-sha256-modp2048,default';
|
|
document.getElementById('ipsec-modal-espprop').value = conn.esp_proposals || 'aes256-sha256-modp2048,default';
|
|
|
|
|
+ document.getElementById('ipsec-modal-pfsgroup').value = conn.pfs_group || 'modp2048';
|
|
|
document.getElementById('ipsec-modal-autostart').checked = conn.auto_start ?? true;
|
|
document.getElementById('ipsec-modal-autostart').checked = conn.auto_start ?? true;
|
|
|
document.getElementById('ipsec-modal-disabled').checked = !!conn.disabled;
|
|
document.getElementById('ipsec-modal-disabled').checked = !!conn.disabled;
|
|
|
|
|
|
|
|
|
|
+ // Populate dynamic subnets
|
|
|
|
|
+ const localContainer = document.getElementById('ipsec-modal-local-subnets-container');
|
|
|
|
|
+ const remoteContainer = document.getElementById('ipsec-modal-remote-subnets-container');
|
|
|
|
|
+
|
|
|
|
|
+ if (localContainer) {
|
|
|
|
|
+ localContainer.innerHTML = '';
|
|
|
|
|
+ const locals = (conn.local_subnets && conn.local_subnets.length > 0) ? conn.local_subnets : (conn.local_subnet ? [conn.local_subnet] : ['192.168.10.0/24']);
|
|
|
|
|
+ locals.forEach(s => addIpsecLocalSubnet(s));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (remoteContainer) {
|
|
|
|
|
+ remoteContainer.innerHTML = '';
|
|
|
|
|
+ const remotes = (conn.remote_subnets && conn.remote_subnets.length > 0) ? conn.remote_subnets : (conn.remote_subnet ? [conn.remote_subnet] : ['192.168.20.0/24']);
|
|
|
|
|
+ remotes.forEach(s => addIpsecRemoteSubnet(s));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ switchIpsecModalTab('p1');
|
|
|
document.getElementById('ipsec-modal').classList.remove('hidden');
|
|
document.getElementById('ipsec-modal').classList.remove('hidden');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1860,37 +2041,70 @@ function closeAddIPSecModal() {
|
|
|
async function submitSaveIPSec(e) {
|
|
async function submitSaveIPSec(e) {
|
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
|
const name = document.getElementById('ipsec-modal-name').value.trim();
|
|
const name = document.getElementById('ipsec-modal-name').value.trim();
|
|
|
- const localts = document.getElementById('ipsec-modal-localts').value.trim();
|
|
|
|
|
- const remotets = document.getElementById('ipsec-modal-remotets').value.trim();
|
|
|
|
|
|
|
+ const ikeVersion = document.getElementById('ipsec-modal-ikeversion').value;
|
|
|
const remotegw = document.getElementById('ipsec-modal-remotegw').value.trim();
|
|
const remotegw = document.getElementById('ipsec-modal-remotegw').value.trim();
|
|
|
const psk = document.getElementById('ipsec-modal-psk').value;
|
|
const psk = document.getElementById('ipsec-modal-psk').value;
|
|
|
- const ike = document.getElementById('ipsec-modal-ikeprop').value.trim();
|
|
|
|
|
- const esp = document.getElementById('ipsec-modal-espprop').value.trim();
|
|
|
|
|
|
|
+ const ikeProposals = document.getElementById('ipsec-modal-ikeprop').value.trim();
|
|
|
|
|
+ const ikeKeylife = parseInt(document.getElementById('ipsec-modal-ikekeylife').value, 10) || 86400;
|
|
|
|
|
+ const localId = document.getElementById('ipsec-modal-localid').value.trim();
|
|
|
|
|
+ const remoteId = document.getElementById('ipsec-modal-remoteid').value.trim();
|
|
|
|
|
+ const dpd = document.getElementById('ipsec-modal-dpd').value;
|
|
|
|
|
+
|
|
|
|
|
+ const phase2Name = document.getElementById('ipsec-modal-p2name').value.trim() || `${name}_p2`;
|
|
|
|
|
+ const espProposals = document.getElementById('ipsec-modal-espprop').value.trim();
|
|
|
|
|
+ const pfsGroup = document.getElementById('ipsec-modal-pfsgroup').value;
|
|
|
const autostart = document.getElementById('ipsec-modal-autostart').checked;
|
|
const autostart = document.getElementById('ipsec-modal-autostart').checked;
|
|
|
const disabled = document.getElementById('ipsec-modal-disabled').checked;
|
|
const disabled = document.getElementById('ipsec-modal-disabled').checked;
|
|
|
|
|
|
|
|
|
|
+ // Scrape dynamic local and remote subnets
|
|
|
|
|
+ const localInputs = document.querySelectorAll('#ipsec-modal-local-subnets-container input');
|
|
|
|
|
+ const localSubnets = [];
|
|
|
|
|
+ localInputs.forEach(inp => {
|
|
|
|
|
+ const v = inp.value.trim();
|
|
|
|
|
+ if (v) localSubnets.push(v);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const remoteInputs = document.querySelectorAll('#ipsec-modal-remote-subnets-container input');
|
|
|
|
|
+ const remoteSubnets = [];
|
|
|
|
|
+ remoteInputs.forEach(inp => {
|
|
|
|
|
+ const v = inp.value.trim();
|
|
|
|
|
+ if (v) remoteSubnets.push(v);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
const res = await fetch(`${API_BASE}/vpn/ipsec/tunnels`, {
|
|
const res = await fetch(`${API_BASE}/vpn/ipsec/tunnels`, {
|
|
|
method: 'POST',
|
|
method: 'POST',
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
body: JSON.stringify({
|
|
body: JSON.stringify({
|
|
|
name,
|
|
name,
|
|
|
|
|
+ ike_version: ikeVersion,
|
|
|
local_addrs: '%any',
|
|
local_addrs: '%any',
|
|
|
remote_addrs: remotegw,
|
|
remote_addrs: remotegw,
|
|
|
- local_subnet: localts,
|
|
|
|
|
- remote_subnet: remotets,
|
|
|
|
|
preshared_key: psk,
|
|
preshared_key: psk,
|
|
|
- ike_proposals: ike,
|
|
|
|
|
- esp_proposals: esp,
|
|
|
|
|
|
|
+ ike_proposals: ikeProposals,
|
|
|
|
|
+ ike_keylife: ikeKeylife,
|
|
|
|
|
+ local_id: localId,
|
|
|
|
|
+ remote_id: remoteId,
|
|
|
|
|
+ dpd: dpd,
|
|
|
|
|
+ phase2_name: phase2Name,
|
|
|
|
|
+ esp_proposals: espProposals,
|
|
|
|
|
+ pfs_group: pfsGroup,
|
|
|
|
|
+ pfs: pfsGroup !== 'none',
|
|
|
|
|
+ local_subnets: localSubnets,
|
|
|
|
|
+ remote_subnets: remoteSubnets,
|
|
|
|
|
+ local_subnet: localSubnets[0] || '0.0.0.0/0',
|
|
|
|
|
+ remote_subnet: remoteSubnets[0] || '0.0.0.0/0',
|
|
|
auto_start: autostart,
|
|
auto_start: autostart,
|
|
|
disabled
|
|
disabled
|
|
|
})
|
|
})
|
|
|
});
|
|
});
|
|
|
if (res.ok) {
|
|
if (res.ok) {
|
|
|
- showToast('IPSec Saved', `Tunnel ${name} configured`, 'success');
|
|
|
|
|
|
|
+ showToast('IPSec Saved', `FortiGate Tunnel ${name} configured`, 'success');
|
|
|
closeAddIPSecModal();
|
|
closeAddIPSecModal();
|
|
|
loadIPSec(false);
|
|
loadIPSec(false);
|
|
|
- fetchData(false);
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const err = await res.json();
|
|
|
|
|
+ showToast('Error', err.error || 'Failed to save IPSec tunnel', 'error');
|
|
|
}
|
|
}
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
showToast('Error', err.message, 'error');
|
|
showToast('Error', err.message, 'error');
|
|
@@ -7684,20 +7898,61 @@ function openAddBgpPeerModal() {
|
|
|
document.getElementById('modal-bgp-peer-id').value = '';
|
|
document.getElementById('modal-bgp-peer-id').value = '';
|
|
|
document.getElementById('bgp-peer-modal-title').innerText = 'New...';
|
|
document.getElementById('bgp-peer-modal-title').innerText = 'New...';
|
|
|
|
|
|
|
|
|
|
+ // General Tab
|
|
|
document.getElementById('modal-bgp-peer-enabled').checked = true;
|
|
document.getElementById('modal-bgp-peer-enabled').checked = true;
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-comment').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-name').value = '';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-instance')) document.getElementById('modal-bgp-peer-instance').value = 'bgp-instance-1';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-template')) document.getElementById('modal-bgp-peer-template').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-local-as').value = '';
|
|
|
document.getElementById('modal-bgp-peer-afi-ip').checked = true;
|
|
document.getElementById('modal-bgp-peer-afi-ip').checked = true;
|
|
|
document.getElementById('modal-bgp-peer-afi-ipv6').checked = false;
|
|
document.getElementById('modal-bgp-peer-afi-ipv6').checked = false;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-afi-l2vpn')) document.getElementById('modal-bgp-peer-afi-l2vpn').checked = false;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-afi-vpnv4')) document.getElementById('modal-bgp-peer-afi-vpnv4').checked = false;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-afi-l2vpn-cisco')) document.getElementById('modal-bgp-peer-afi-l2vpn-cisco').checked = false;
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-router-id').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-remote-addr').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-remote-port').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-remote-as').value = '';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-remote-allow-as')) document.getElementById('modal-bgp-peer-remote-allow-as').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-local-addr').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-local-port').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-local-role').value = 'ebgp';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-password').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-multihop').checked = false;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-tx-ttl')) document.getElementById('modal-bgp-peer-tx-ttl').value = '';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-rx-min-ttl')) document.getElementById('modal-bgp-peer-rx-min-ttl').value = '';
|
|
|
document.getElementById('modal-bgp-peer-connect').checked = true;
|
|
document.getElementById('modal-bgp-peer-connect').checked = true;
|
|
|
document.getElementById('modal-bgp-peer-listen').checked = true;
|
|
document.getElementById('modal-bgp-peer-listen').checked = true;
|
|
|
- document.getElementById('modal-bgp-peer-holdtime').value = '00:03:00';
|
|
|
|
|
- document.getElementById('modal-bgp-peer-keepalive').value = '00:01:00';
|
|
|
|
|
- document.getElementById('modal-bgp-peer-nexthop-choice').value = 'force-self';
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Extra Tab
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-holdtime').value = '00:00:30';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-keepalive').value = '00:00:10';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-use-bfd')) document.getElementById('modal-bgp-peer-use-bfd').checked = false;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-vrf')) document.getElementById('modal-bgp-peer-vrf').value = 'main';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-no-client-reflect')) document.getElementById('modal-bgp-peer-no-client-reflect').checked = true;
|
|
|
document.getElementById('modal-bgp-peer-redist-conn').checked = false;
|
|
document.getElementById('modal-bgp-peer-redist-conn').checked = false;
|
|
|
document.getElementById('modal-bgp-peer-redist-static').checked = true;
|
|
document.getElementById('modal-bgp-peer-redist-static').checked = true;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-redist-rip')) document.getElementById('modal-bgp-peer-redist-rip').checked = false;
|
|
|
document.getElementById('modal-bgp-peer-redist-ospf').checked = false;
|
|
document.getElementById('modal-bgp-peer-redist-ospf').checked = false;
|
|
|
document.getElementById('modal-bgp-peer-redist-bgp').checked = false;
|
|
document.getElementById('modal-bgp-peer-redist-bgp').checked = false;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-redist-vpn')) document.getElementById('modal-bgp-peer-redist-vpn').checked = false;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-redist-dhcp')) document.getElementById('modal-bgp-peer-redist-dhcp').checked = false;
|
|
|
document.getElementById('modal-bgp-peer-default-orig').checked = false;
|
|
document.getElementById('modal-bgp-peer-default-orig').checked = false;
|
|
|
|
|
|
|
|
|
|
+ // Attributes Tab
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-nexthop-choice').value = 'force-self';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-default-prepend').value = 0;
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-allow-as-in').value = 0;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-ignore-as-path-len')) document.getElementById('modal-bgp-peer-ignore-as-path-len').checked = false;
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-remove-priv-as').checked = false;
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-as-override').checked = false;
|
|
|
|
|
+
|
|
|
|
|
+ // Filter Tab
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-in-filter').value = '';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-out-filter').value = '';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-out-network-name')) document.getElementById('modal-bgp-peer-out-network-name').value = '';
|
|
|
|
|
+
|
|
|
populateBgpRoutingTables();
|
|
populateBgpRoutingTables();
|
|
|
|
|
|
|
|
const container = document.getElementById('modal-bgp-output-networks-container');
|
|
const container = document.getElementById('modal-bgp-output-networks-container');
|
|
@@ -7726,6 +7981,8 @@ function openEditBgpPeerModal(id) {
|
|
|
document.getElementById('modal-bgp-peer-enabled').checked = p.enabled !== false && !p.disabled;
|
|
document.getElementById('modal-bgp-peer-enabled').checked = p.enabled !== false && !p.disabled;
|
|
|
document.getElementById('modal-bgp-peer-comment').value = p.comment || '';
|
|
document.getElementById('modal-bgp-peer-comment').value = p.comment || '';
|
|
|
document.getElementById('modal-bgp-peer-name').value = p.name || '';
|
|
document.getElementById('modal-bgp-peer-name').value = p.name || '';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-instance')) document.getElementById('modal-bgp-peer-instance').value = p.instance || 'bgp-instance-1';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-template')) document.getElementById('modal-bgp-peer-template').value = p.template || '';
|
|
|
document.getElementById('modal-bgp-peer-local-as').value = p.local_as || '';
|
|
document.getElementById('modal-bgp-peer-local-as').value = p.local_as || '';
|
|
|
document.getElementById('modal-bgp-peer-router-id').value = p.router_id || '';
|
|
document.getElementById('modal-bgp-peer-router-id').value = p.router_id || '';
|
|
|
document.getElementById('modal-bgp-peer-afi-ip').checked = true;
|
|
document.getElementById('modal-bgp-peer-afi-ip').checked = true;
|
|
@@ -7733,34 +7990,45 @@ function openEditBgpPeerModal(id) {
|
|
|
document.getElementById('modal-bgp-peer-remote-addr').value = p.remote_address || '';
|
|
document.getElementById('modal-bgp-peer-remote-addr').value = p.remote_address || '';
|
|
|
document.getElementById('modal-bgp-peer-remote-port').value = p.remote_port || '';
|
|
document.getElementById('modal-bgp-peer-remote-port').value = p.remote_port || '';
|
|
|
document.getElementById('modal-bgp-peer-remote-as').value = p.remote_as || '';
|
|
document.getElementById('modal-bgp-peer-remote-as').value = p.remote_as || '';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-remote-allow-as')) document.getElementById('modal-bgp-peer-remote-allow-as').value = p.remote_allow_as || '';
|
|
|
document.getElementById('modal-bgp-peer-local-addr').value = p.local_address || '';
|
|
document.getElementById('modal-bgp-peer-local-addr').value = p.local_address || '';
|
|
|
document.getElementById('modal-bgp-peer-local-port').value = p.local_port || '';
|
|
document.getElementById('modal-bgp-peer-local-port').value = p.local_port || '';
|
|
|
document.getElementById('modal-bgp-peer-local-role').value = p.local_role || 'ebgp';
|
|
document.getElementById('modal-bgp-peer-local-role').value = p.local_role || 'ebgp';
|
|
|
document.getElementById('modal-bgp-peer-password').value = p.password || '';
|
|
document.getElementById('modal-bgp-peer-password').value = p.password || '';
|
|
|
document.getElementById('modal-bgp-peer-multihop').checked = !!p.multihop;
|
|
document.getElementById('modal-bgp-peer-multihop').checked = !!p.multihop;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-tx-ttl')) document.getElementById('modal-bgp-peer-tx-ttl').value = p.tx_ttl || '';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-rx-min-ttl')) document.getElementById('modal-bgp-peer-rx-min-ttl').value = p.rx_min_ttl || '';
|
|
|
document.getElementById('modal-bgp-peer-connect').checked = p.connect !== false;
|
|
document.getElementById('modal-bgp-peer-connect').checked = p.connect !== false;
|
|
|
document.getElementById('modal-bgp-peer-listen').checked = p.listen !== false;
|
|
document.getElementById('modal-bgp-peer-listen').checked = p.listen !== false;
|
|
|
|
|
|
|
|
// Extra Tab
|
|
// Extra Tab
|
|
|
- document.getElementById('modal-bgp-peer-holdtime').value = p.hold_time ? formatBgpTime(p.hold_time) : '00:03:00';
|
|
|
|
|
- document.getElementById('modal-bgp-peer-keepalive').value = p.keepalive_time ? formatBgpTime(p.keepalive_time) : '00:01:00';
|
|
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-holdtime').value = p.hold_time ? formatBgpTime(p.hold_time) : '00:00:30';
|
|
|
|
|
+ document.getElementById('modal-bgp-peer-keepalive').value = p.keepalive_time ? formatBgpTime(p.keepalive_time) : '00:00:10';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-use-bfd')) document.getElementById('modal-bgp-peer-use-bfd').checked = !!p.use_bfd;
|
|
|
document.getElementById('modal-bgp-peer-routing-table').value = p.routing_table || 'main';
|
|
document.getElementById('modal-bgp-peer-routing-table').value = p.routing_table || 'main';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-vrf')) document.getElementById('modal-bgp-peer-vrf').value = p.vrf || 'main';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-no-client-reflect')) document.getElementById('modal-bgp-peer-no-client-reflect').checked = p.no_client_reflect !== false;
|
|
|
document.getElementById('modal-bgp-peer-redist-conn').checked = !!p.redist_connected;
|
|
document.getElementById('modal-bgp-peer-redist-conn').checked = !!p.redist_connected;
|
|
|
document.getElementById('modal-bgp-peer-redist-static').checked = p.redist_static !== false;
|
|
document.getElementById('modal-bgp-peer-redist-static').checked = p.redist_static !== false;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-redist-rip')) document.getElementById('modal-bgp-peer-redist-rip').checked = !!p.redist_rip;
|
|
|
document.getElementById('modal-bgp-peer-redist-ospf').checked = !!p.redist_ospf;
|
|
document.getElementById('modal-bgp-peer-redist-ospf').checked = !!p.redist_ospf;
|
|
|
document.getElementById('modal-bgp-peer-redist-bgp').checked = !!p.redist_bgp;
|
|
document.getElementById('modal-bgp-peer-redist-bgp').checked = !!p.redist_bgp;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-redist-vpn')) document.getElementById('modal-bgp-peer-redist-vpn').checked = !!p.redist_vpn;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-redist-dhcp')) document.getElementById('modal-bgp-peer-redist-dhcp').checked = !!p.redist_dhcp;
|
|
|
document.getElementById('modal-bgp-peer-default-orig').checked = !!p.default_originate;
|
|
document.getElementById('modal-bgp-peer-default-orig').checked = !!p.default_originate;
|
|
|
|
|
|
|
|
// Attributes Tab
|
|
// Attributes Tab
|
|
|
document.getElementById('modal-bgp-peer-nexthop-choice').value = p.nexthop_choice || (p.nexthop_self ? 'force-self' : 'default');
|
|
document.getElementById('modal-bgp-peer-nexthop-choice').value = p.nexthop_choice || (p.nexthop_self ? 'force-self' : 'default');
|
|
|
document.getElementById('modal-bgp-peer-default-prepend').value = p.default_prepend || 0;
|
|
document.getElementById('modal-bgp-peer-default-prepend').value = p.default_prepend || 0;
|
|
|
document.getElementById('modal-bgp-peer-allow-as-in').value = p.allow_as_in || 0;
|
|
document.getElementById('modal-bgp-peer-allow-as-in').value = p.allow_as_in || 0;
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-ignore-as-path-len')) document.getElementById('modal-bgp-peer-ignore-as-path-len').checked = !!p.ignore_as_path_len;
|
|
|
document.getElementById('modal-bgp-peer-remove-priv-as').checked = !!p.remove_private_as;
|
|
document.getElementById('modal-bgp-peer-remove-priv-as').checked = !!p.remove_private_as;
|
|
|
document.getElementById('modal-bgp-peer-as-override').checked = !!p.as_override;
|
|
document.getElementById('modal-bgp-peer-as-override').checked = !!p.as_override;
|
|
|
|
|
|
|
|
// Filter Tab
|
|
// Filter Tab
|
|
|
document.getElementById('modal-bgp-peer-in-filter').value = p.in_filter || '';
|
|
document.getElementById('modal-bgp-peer-in-filter').value = p.in_filter || '';
|
|
|
document.getElementById('modal-bgp-peer-out-filter').value = p.out_filter || '';
|
|
document.getElementById('modal-bgp-peer-out-filter').value = p.out_filter || '';
|
|
|
|
|
+ if (document.getElementById('modal-bgp-peer-out-network-name')) document.getElementById('modal-bgp-peer-out-network-name').value = p.output_network || '';
|
|
|
|
|
|
|
|
// Output Networks
|
|
// Output Networks
|
|
|
const container = document.getElementById('modal-bgp-output-networks-container');
|
|
const container = document.getElementById('modal-bgp-output-networks-container');
|
|
@@ -7817,35 +8085,48 @@ function getBgpPeerFormData() {
|
|
|
enabled: enabled,
|
|
enabled: enabled,
|
|
|
disabled: !enabled,
|
|
disabled: !enabled,
|
|
|
comment: document.getElementById('modal-bgp-peer-comment').value.trim(),
|
|
comment: document.getElementById('modal-bgp-peer-comment').value.trim(),
|
|
|
|
|
+ instance: document.getElementById('modal-bgp-peer-instance')?.value.trim() || 'bgp-instance-1',
|
|
|
|
|
+ template: document.getElementById('modal-bgp-peer-template')?.value.trim() || '',
|
|
|
local_as: parseInt(document.getElementById('modal-bgp-peer-local-as')?.value, 10) || 0,
|
|
local_as: parseInt(document.getElementById('modal-bgp-peer-local-as')?.value, 10) || 0,
|
|
|
router_id: document.getElementById('modal-bgp-peer-router-id').value.trim(),
|
|
router_id: document.getElementById('modal-bgp-peer-router-id').value.trim(),
|
|
|
afi: document.getElementById('modal-bgp-peer-afi-ipv6').checked ? 'ipv6' : 'ip',
|
|
afi: document.getElementById('modal-bgp-peer-afi-ipv6').checked ? 'ipv6' : 'ip',
|
|
|
remote_address: document.getElementById('modal-bgp-peer-remote-addr').value.trim(),
|
|
remote_address: document.getElementById('modal-bgp-peer-remote-addr').value.trim(),
|
|
|
remote_port: parseInt(document.getElementById('modal-bgp-peer-remote-port').value, 10) || 0,
|
|
remote_port: parseInt(document.getElementById('modal-bgp-peer-remote-port').value, 10) || 0,
|
|
|
remote_as: parseInt(document.getElementById('modal-bgp-peer-remote-as').value, 10) || 0,
|
|
remote_as: parseInt(document.getElementById('modal-bgp-peer-remote-as').value, 10) || 0,
|
|
|
|
|
+ remote_allow_as: document.getElementById('modal-bgp-peer-remote-allow-as')?.value.trim() || '',
|
|
|
local_address: document.getElementById('modal-bgp-peer-local-addr').value.trim(),
|
|
local_address: document.getElementById('modal-bgp-peer-local-addr').value.trim(),
|
|
|
local_port: parseInt(document.getElementById('modal-bgp-peer-local-port').value, 10) || 0,
|
|
local_port: parseInt(document.getElementById('modal-bgp-peer-local-port').value, 10) || 0,
|
|
|
local_role: document.getElementById('modal-bgp-peer-local-role').value,
|
|
local_role: document.getElementById('modal-bgp-peer-local-role').value,
|
|
|
password: document.getElementById('modal-bgp-peer-password').value,
|
|
password: document.getElementById('modal-bgp-peer-password').value,
|
|
|
multihop: document.getElementById('modal-bgp-peer-multihop').checked,
|
|
multihop: document.getElementById('modal-bgp-peer-multihop').checked,
|
|
|
|
|
+ tx_ttl: parseInt(document.getElementById('modal-bgp-peer-tx-ttl')?.value, 10) || 0,
|
|
|
|
|
+ rx_min_ttl: parseInt(document.getElementById('modal-bgp-peer-rx-min-ttl')?.value, 10) || 0,
|
|
|
connect: document.getElementById('modal-bgp-peer-connect').checked,
|
|
connect: document.getElementById('modal-bgp-peer-connect').checked,
|
|
|
listen: document.getElementById('modal-bgp-peer-listen').checked,
|
|
listen: document.getElementById('modal-bgp-peer-listen').checked,
|
|
|
hold_time: parseBgpTime(document.getElementById('modal-bgp-peer-holdtime').value),
|
|
hold_time: parseBgpTime(document.getElementById('modal-bgp-peer-holdtime').value),
|
|
|
keepalive_time: parseBgpTime(document.getElementById('modal-bgp-peer-keepalive').value),
|
|
keepalive_time: parseBgpTime(document.getElementById('modal-bgp-peer-keepalive').value),
|
|
|
|
|
+ use_bfd: document.getElementById('modal-bgp-peer-use-bfd')?.checked || false,
|
|
|
routing_table: document.getElementById('modal-bgp-peer-routing-table').value,
|
|
routing_table: document.getElementById('modal-bgp-peer-routing-table').value,
|
|
|
|
|
+ vrf: document.getElementById('modal-bgp-peer-vrf')?.value.trim() || 'main',
|
|
|
|
|
+ no_client_reflect: document.getElementById('modal-bgp-peer-no-client-reflect')?.checked || false,
|
|
|
redist_connected: document.getElementById('modal-bgp-peer-redist-conn').checked,
|
|
redist_connected: document.getElementById('modal-bgp-peer-redist-conn').checked,
|
|
|
redist_static: document.getElementById('modal-bgp-peer-redist-static').checked,
|
|
redist_static: document.getElementById('modal-bgp-peer-redist-static').checked,
|
|
|
|
|
+ redist_rip: document.getElementById('modal-bgp-peer-redist-rip')?.checked || false,
|
|
|
redist_ospf: document.getElementById('modal-bgp-peer-redist-ospf').checked,
|
|
redist_ospf: document.getElementById('modal-bgp-peer-redist-ospf').checked,
|
|
|
redist_bgp: document.getElementById('modal-bgp-peer-redist-bgp').checked,
|
|
redist_bgp: document.getElementById('modal-bgp-peer-redist-bgp').checked,
|
|
|
|
|
+ redist_vpn: document.getElementById('modal-bgp-peer-redist-vpn')?.checked || false,
|
|
|
|
|
+ redist_dhcp: document.getElementById('modal-bgp-peer-redist-dhcp')?.checked || false,
|
|
|
default_originate: document.getElementById('modal-bgp-peer-default-orig').checked,
|
|
default_originate: document.getElementById('modal-bgp-peer-default-orig').checked,
|
|
|
nexthop_choice: document.getElementById('modal-bgp-peer-nexthop-choice').value,
|
|
nexthop_choice: document.getElementById('modal-bgp-peer-nexthop-choice').value,
|
|
|
nexthop_self: document.getElementById('modal-bgp-peer-nexthop-choice').value === 'force-self',
|
|
nexthop_self: document.getElementById('modal-bgp-peer-nexthop-choice').value === 'force-self',
|
|
|
default_prepend: parseInt(document.getElementById('modal-bgp-peer-default-prepend').value, 10) || 0,
|
|
default_prepend: parseInt(document.getElementById('modal-bgp-peer-default-prepend').value, 10) || 0,
|
|
|
allow_as_in: parseInt(document.getElementById('modal-bgp-peer-allow-as-in').value, 10) || 0,
|
|
allow_as_in: parseInt(document.getElementById('modal-bgp-peer-allow-as-in').value, 10) || 0,
|
|
|
|
|
+ ignore_as_path_len: document.getElementById('modal-bgp-peer-ignore-as-path-len')?.checked || false,
|
|
|
remove_private_as: document.getElementById('modal-bgp-peer-remove-priv-as').checked,
|
|
remove_private_as: document.getElementById('modal-bgp-peer-remove-priv-as').checked,
|
|
|
as_override: document.getElementById('modal-bgp-peer-as-override').checked,
|
|
as_override: document.getElementById('modal-bgp-peer-as-override').checked,
|
|
|
in_filter: (document.getElementById('modal-bgp-peer-in-filter')?.value || '').trim(),
|
|
in_filter: (document.getElementById('modal-bgp-peer-in-filter')?.value || '').trim(),
|
|
|
out_filter: (document.getElementById('modal-bgp-peer-out-filter')?.value || '').trim(),
|
|
out_filter: (document.getElementById('modal-bgp-peer-out-filter')?.value || '').trim(),
|
|
|
|
|
+ output_network: (document.getElementById('modal-bgp-peer-out-network-name')?.value || '').trim(),
|
|
|
output_networks: outputNetworks
|
|
output_networks: outputNetworks
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|