Explorar el Código

feat(routing): replace FRR with BIRD 2 engine supporting multi-instance BGP and OSPFv2

Proxmox Router hace 1 semana
padre
commit
8e83e8bd19

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 498 - 381
internal/dynamicrouting/manager.go


+ 1 - 0
internal/dynamicrouting/types.go

@@ -20,6 +20,7 @@ type BGPPeer struct {
 	RemoteAddress  string `json:"remote_address"`
 	RemoteAS       uint32 `json:"remote_as"`
 	LocalAddress   string `json:"local_address,omitempty"`
+	LocalAS        uint32 `json:"local_as,omitempty"` // Multi-Instance Local AS (if 0, uses global AS)
 	Multihop       bool   `json:"multihop"`
 	NexthopSelf    bool   `json:"nexthop_self"`
 	Passive        bool   `json:"passive"`

+ 12 - 4
internal/web/static/app.js

@@ -107,10 +107,10 @@ function navigate(tabName) {
     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' },
     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' },
-    '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' },
     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' },
@@ -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 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 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 text-slate-400">${escapeHtml(p.uptime || '-')}</td>
         <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('bgp-peer-modal-title').innerText = 'Add BGP Peer Connection';
   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');
   if (inFilterEl) inFilterEl.value = '';
   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-remote-addr').value = p.remote_address || '';
   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-password').value = p.password || '';
   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(),
     remote_address: document.getElementById('modal-bgp-peer-remote-addr').value.trim(),
     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(),
     password: document.getElementById('modal-bgp-peer-password').value,
     multihop: document.getElementById('modal-bgp-peer-multihop').checked,

+ 8 - 4
internal/web/static/index.html

@@ -1994,7 +1994,7 @@
                 <h2 class="text-base font-bold text-white">BGP Dynamic Routing</h2>
                 <span id="bgp-live-status-pill" class="text-[10px] px-2 py-0.5 rounded font-mono bg-slate-800 text-slate-400 border border-slate-700">Checking...</span>
               </div>
-              <p class="text-xs text-slate-400">Enterprise FRRouting BGP stack: Autonomous System peering sessions, prefix announcements, and BGP routing table (RIB).</p>
+              <p class="text-xs text-slate-400">High-Performance BIRD 2 BGP Engine: Multi-Instance / Multi-AS peering sessions, programmable route filters, prefix announcements, and BGP routing table (RIB).</p>
             </div>
 
             <div class="flex items-center space-x-2 flex-wrap gap-y-2">
@@ -2161,7 +2161,7 @@
                 <h2 class="text-base font-bold text-white">OSPF Dynamic Routing</h2>
                 <span id="ospf-live-status-pill" class="text-[10px] px-2 py-0.5 rounded font-mono bg-slate-800 text-slate-400 border border-slate-700">Checking...</span>
               </div>
-              <p class="text-xs text-slate-400">Enterprise FRRouting OSPFv2 stack: Link-state interior gateway routing, multi-area topologies, and neighbor adjacencies.</p>
+              <p class="text-xs text-slate-400">High-Performance BIRD 2 OSPFv2 Engine: Link-state interior gateway routing, multi-area topologies, and neighbor adjacencies.</p>
             </div>
 
             <div class="flex items-center space-x-2 flex-wrap gap-y-2">
@@ -6948,7 +6948,7 @@
         <div class="flex items-center justify-between p-3 rounded-xl bg-slate-800/60 border border-slate-700/60">
           <div>
             <div class="font-semibold text-white">Enable BGP Routing</div>
-            <div class="text-[11px] text-slate-400">Run FRRouting bgpd service for dynamic exterior gateway routing</div>
+            <div class="text-[11px] text-slate-400">Run BIRD 2 daemon for dynamic exterior gateway routing & multi-instance AS peering</div>
           </div>
           <input type="checkbox" id="modal-bgp-enabled" class="w-4 h-4 rounded text-purple-600 focus:ring-purple-500 bg-slate-800 border-slate-600">
         </div>
@@ -7027,6 +7027,10 @@
             <label class="block font-semibold text-slate-300 mb-1.5">Remote AS *</label>
             <input type="number" id="modal-bgp-peer-remote-as" required min="1" max="4294967295" placeholder="65000" class="w-full bg-slate-800 border border-slate-700 rounded-lg px-3 py-2 text-white font-mono">
           </div>
+          <div>
+            <label class="block font-semibold text-slate-300 mb-1.5">Local AS (Multi-Instance)</label>
+            <input type="number" id="modal-bgp-peer-local-as" min="1" max="4294967295" placeholder="Optional (uses global AS if blank)" class="w-full bg-slate-800 border border-slate-700 rounded-lg px-3 py-2 text-white font-mono">
+          </div>
         </div>
 
         <div class="grid grid-cols-2 gap-4">
@@ -7128,7 +7132,7 @@
         <div class="flex items-center justify-between p-3 rounded-xl bg-slate-800/60 border border-slate-700/60">
           <div>
             <div class="font-semibold text-white">Enable OSPF Routing</div>
-            <div class="text-[11px] text-slate-400">Run FRRouting ospfd service for dynamic interior gateway routing</div>
+            <div class="text-[11px] text-slate-400">Run BIRD 2 daemon for dynamic interior gateway routing & link-state topology</div>
           </div>
           <input type="checkbox" id="modal-ospf-enabled" class="w-4 h-4 rounded text-indigo-600 focus:ring-indigo-500 bg-slate-800 border-slate-600">
         </div>

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio