|
@@ -107,10 +107,10 @@ function navigate(tabName) {
|
|
|
vlans: { title: 'VLAN Virtual Networks', sub: 'IEEE 802.1Q sub-interface segmentation and routing' },
|
|
vlans: { title: 'VLAN Virtual Networks', sub: 'IEEE 802.1Q sub-interface segmentation and routing' },
|
|
|
firewall: { title: 'Network Firewall', sub: 'Stateful packet inspection, NAT, traffic mangle, address lists & connection tracking' },
|
|
firewall: { title: 'Network Firewall', sub: 'Stateful packet inspection, NAT, traffic mangle, address lists & connection tracking' },
|
|
|
routes: { title: 'Routing & Policy', sub: 'Routing tables, static routes (DAS/DAC), and policy routing rules' },
|
|
routes: { title: 'Routing & Policy', sub: 'Routing tables, static routes (DAS/DAC), and policy routing rules' },
|
|
|
- bgp: { title: 'BGP Routing (/routing bgp)', sub: 'FRRouting BGP peering sessions, advertised networks, and BGP routing table (RIB)' },
|
|
|
|
|
- ospf: { title: 'OSPF Routing (/routing ospf)', sub: 'FRRouting OSPFv2 link-state routing, dynamic neighbor adjacencies, and multi-area topology' },
|
|
|
|
|
|
|
+ bgp: { title: 'BGP Routing (/routing bgp)', sub: 'BIRD 2 BGP Multi-Instance peering sessions, advertised networks, and BGP routing table (RIB)' },
|
|
|
|
|
+ ospf: { title: 'OSPF Routing (/routing ospf)', sub: 'BIRD 2 OSPFv2 link-state routing, dynamic neighbor adjacencies, and multi-area topology' },
|
|
|
'routing-filters': { title: 'Routing Filters (/routing filter)', sub: 'Route filter chains, prefix matching, BGP community maps & policy-based path control' },
|
|
'routing-filters': { title: 'Routing Filters (/routing filter)', sub: 'Route filter chains, prefix matching, BGP community maps & policy-based path control' },
|
|
|
- 'dynamic-routing': { title: 'BGP Routing (/routing bgp)', sub: 'FRRouting dynamic routing' },
|
|
|
|
|
|
|
+ 'dynamic-routing': { title: 'BGP Routing (/routing bgp)', sub: 'BIRD 2 dynamic routing engine' },
|
|
|
ppp: { title: 'PPP Servers & Secrets', sub: 'Subscriber authentication, dynamic IP pools and VPN access concentrators' },
|
|
ppp: { title: 'PPP Servers & Secrets', sub: 'Subscriber authentication, dynamic IP pools and VPN access concentrators' },
|
|
|
eoip: { title: 'EoIP Tunnels', sub: 'Ethernet over IP (EoIP / GRETAP) Layer 2 encapsulation & transparent network bridging' },
|
|
eoip: { title: 'EoIP Tunnels', sub: 'Ethernet over IP (EoIP / GRETAP) Layer 2 encapsulation & transparent network bridging' },
|
|
|
pppoe: { title: 'PPPoE Client WAN', sub: 'Point-to-Point Protocol over Ethernet WAN access' },
|
|
pppoe: { title: 'PPPoE Client WAN', sub: 'Point-to-Point Protocol over Ethernet WAN access' },
|
|
@@ -7022,7 +7022,10 @@ function renderBgpPeers() {
|
|
|
<td class="py-2.5 px-3 text-center tracking-wider">${flagA}${flagE}${flagX}</td>
|
|
<td class="py-2.5 px-3 text-center tracking-wider">${flagA}${flagE}${flagX}</td>
|
|
|
<td class="py-2.5 px-3 font-semibold text-white">${escapeHtml(p.name)}</td>
|
|
<td class="py-2.5 px-3 font-semibold text-white">${escapeHtml(p.name)}</td>
|
|
|
<td class="py-2.5 px-3 text-purple-300 font-bold">${escapeHtml(p.remote_address)}</td>
|
|
<td class="py-2.5 px-3 text-purple-300 font-bold">${escapeHtml(p.remote_address)}</td>
|
|
|
- <td class="py-2.5 px-3 font-bold text-slate-200">AS ${p.remote_as}</td>
|
|
|
|
|
|
|
+ <td class="py-2.5 px-3">
|
|
|
|
|
+ <div class="font-bold text-slate-200">AS ${p.remote_as}</div>
|
|
|
|
|
+ ${p.local_as ? `<div class="text-[10px] text-purple-400 font-mono font-semibold" title="Custom Multi-Instance AS">Local: AS ${p.local_as}</div>` : `<div class="text-[10px] text-slate-500 font-mono">Global AS</div>`}
|
|
|
|
|
+ </td>
|
|
|
<td class="py-2.5 px-3">${stateBadge}</td>
|
|
<td class="py-2.5 px-3">${stateBadge}</td>
|
|
|
<td class="py-2.5 px-3 text-slate-400">${escapeHtml(p.uptime || '-')}</td>
|
|
<td class="py-2.5 px-3 text-slate-400">${escapeHtml(p.uptime || '-')}</td>
|
|
|
<td class="py-2.5 px-3 text-slate-300">
|
|
<td class="py-2.5 px-3 text-slate-300">
|
|
@@ -7331,6 +7334,8 @@ function openAddBgpPeerModal() {
|
|
|
document.getElementById('modal-bgp-peer-id').value = '';
|
|
document.getElementById('modal-bgp-peer-id').value = '';
|
|
|
document.getElementById('bgp-peer-modal-title').innerText = 'Add BGP Peer Connection';
|
|
document.getElementById('bgp-peer-modal-title').innerText = 'Add BGP Peer Connection';
|
|
|
document.getElementById('modal-bgp-peer-nexthop-self').checked = true;
|
|
document.getElementById('modal-bgp-peer-nexthop-self').checked = true;
|
|
|
|
|
+ const localAsEl = document.getElementById('modal-bgp-peer-local-as');
|
|
|
|
|
+ if (localAsEl) localAsEl.value = '';
|
|
|
const inFilterEl = document.getElementById('modal-bgp-peer-in-filter');
|
|
const inFilterEl = document.getElementById('modal-bgp-peer-in-filter');
|
|
|
if (inFilterEl) inFilterEl.value = '';
|
|
if (inFilterEl) inFilterEl.value = '';
|
|
|
const outFilterEl = document.getElementById('modal-bgp-peer-out-filter');
|
|
const outFilterEl = document.getElementById('modal-bgp-peer-out-filter');
|
|
@@ -7345,6 +7350,8 @@ function openEditBgpPeerModal(id) {
|
|
|
document.getElementById('modal-bgp-peer-name').value = p.name || '';
|
|
document.getElementById('modal-bgp-peer-name').value = p.name || '';
|
|
|
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-as').value = p.remote_as || '';
|
|
document.getElementById('modal-bgp-peer-remote-as').value = p.remote_as || '';
|
|
|
|
|
+ const localAsEl = document.getElementById('modal-bgp-peer-local-as');
|
|
|
|
|
+ if (localAsEl) localAsEl.value = p.local_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-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;
|
|
@@ -7371,6 +7378,7 @@ async function submitBgpPeer(e) {
|
|
|
name: document.getElementById('modal-bgp-peer-name').value.trim(),
|
|
name: document.getElementById('modal-bgp-peer-name').value.trim(),
|
|
|
remote_address: document.getElementById('modal-bgp-peer-remote-addr').value.trim(),
|
|
remote_address: document.getElementById('modal-bgp-peer-remote-addr').value.trim(),
|
|
|
remote_as: parseInt(document.getElementById('modal-bgp-peer-remote-as').value, 10),
|
|
remote_as: parseInt(document.getElementById('modal-bgp-peer-remote-as').value, 10),
|
|
|
|
|
+ local_as: parseInt(document.getElementById('modal-bgp-peer-local-as')?.value, 10) || 0,
|
|
|
local_address: document.getElementById('modal-bgp-peer-local-addr').value.trim(),
|
|
local_address: document.getElementById('modal-bgp-peer-local-addr').value.trim(),
|
|
|
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,
|