Proses Keputusan BGP Step-Through Debugger

function runDebugger() { const get = id => document.getElementById(id); const a = { weight: parseInt(get('aWeight').value), lp: parseInt(get('aLp').value), local: parseInt(get('aLocal').value), asp: parseInt(get('aAsp').value), origin: parseInt(get('aOrigin').value), med: parseInt(get('aMed').value), type: get('aType').value, igp: parseInt(get('aIgp').value), rid: get('aRid').value, }; const b = { weight: parseInt(get('bWeight').value), lp: parseInt(get('bLp').value), local: parseInt(get('bLocal').value), asp: parseInt(get('bAsp').value), origin: parseInt(get('bOrigin').value), med: parseInt(get('bMed').value), type: get('bType').value, igp: parseInt(get('bIgp').value), rid: get('bRid').value, }; const aRidNum = ipToNum(a.rid); const bRidNum = ipToNum(b.rid); const resultsSection = document.getElementById('resultsSection'); resultsSection.style.display = 'block'; const originName = v => ['IGP (i)','EGP (e)','Incomplete (?)'][v]; const criteria = [ { name: 'Weight (Cisco)', higher: true, aVal: a.weight, bVal: b.weight, aLabel: a.weight, bLabel: b.weight, note: 'Higher weight wins. Cisco proprietary, not sent to peers.', }, { name: 'Local Preference', higher: true, aVal: a.lp, bVal: b.lp, aLabel: a.lp, bLabel: b.lp, note: 'Higher local-pref wins. iBGP-propagated, AS-wide policy knob.', }, { name: 'Locally Originated', higher: true, aVal: a.local, bVal: b.local, aLabel: a.local ? 'Yes' : 'No', bLabel: b.local ? 'Yes' : 'No', note: 'Locally originated (network/aggregate) preferred over learned routes.', }, { name: 'AS-Path Length', higher: false, aVal: a.asp, bVal: b.asp, aLabel: `${a.asp} hops`, bLabel: `${b.asp} hops`, note: 'Shorter AS-Path wins.', }, { name: 'Origin Code', higher: false, aVal: a.origin, bVal: b.origin, aLabel: originName(a.origin), bLabel: originName(b.origin), note: 'IGP (i) < EGP (e) < Incomplete (?). Lower numeric value wins.', }, { name: 'MED', higher: false, aVal: a.med, bVal: b.med, aLabel: a.med, bLabel: b.med, note: 'Lower MED wins. Only compared between paths from same neighboring AS (RFC 4271).', }, { name: 'eBGP over iBGP', aVal: a.type === 'e' ? 0 : 1, bVal: b.type === 'e' ? 0 : 1, higher: false, aLabel: a.type === 'e' ? 'eBGP' : 'iBGP', bLabel: b.type === 'e' ? 'eBGP' : 'iBGP', note: 'eBGP paths preferred over iBGP paths.', }, { name: 'IGP Metric to Next-Hop', higher: false, aVal: a.igp, bVal: b.igp, aLabel: a.igp, bLabel: b.igp, note: 'Lower IGP cost to BGP next-hop wins.', }, { name: 'BGP Router-ID', higher: false, aVal: aRidNum !== null ? aRidNum : 0, bVal: bRidNum !== null ? bRidNum : 0, aLabel: a.rid, bLabel: b.rid, note: 'Lower router-ID wins (final deterministic tie-breaker).', }, ]; let winner = null; const steps = criteria.map((c, i) => { let verdict, cls; if (winner) { // Already decided return `
  • ${i+1}
    ${c.name}
    A: ${c.aLabel} | B: ${c.bLabel}
    — Skipped (winner already determined) —
  • `; } if (c.higher) { if (c.aVal > c.bVal) { verdict = 'Path A wins'; cls = 'a'; winner = 'A'; } else if (c.bVal > c.aVal) { verdict = 'Path B wins'; cls = 'b'; winner = 'B'; } else { verdict = 'Tie — proceed to next criterion'; cls = 'tie'; } } else { if (c.aVal < c.bVal) { verdict = 'Path A wins'; cls = 'a'; winner = 'A'; } else if (c.bVal < c.aVal) { verdict = 'Path B wins'; cls = 'b'; winner = 'B'; } else { verdict = 'Tie — proceed to next criterion'; cls = 'tie'; } } return `
  • ${i+1}
    ${c.name}
    A: ${c.aLabel} | B: ${c.bLabel}
    ${c.note}
    ${verdict}
  • `; }); const winnerBox = winner ? `
    Best Path: Path ${winner}
    ` : `
    Complete tie after all 9 criteria — implementation-specific tiebreaker
    `; document.getElementById('stepList').innerHTML = steps.join(''); document.getElementById('winnerBox').innerHTML = winnerBox; }