# ============================================================================= # edge — IPv6 apply script (ROS 6.49.18, BGP-only / no OSPFv3) # ============================================================================= # # Edge is the iBGP hub: it terminates the TWC v6 eBGP peering and the v4 # transport iBGP sessions to every tower. v6 NLRI rides v4 transport (so the # existing v4 OSPF reachability between loopbacks is reused; no v6 IGP is # needed). This matches the verona-v6-apply.rsc design choice. # # Two paths edge<->core: # 1. PRIMARY: sfp-sfpplus11-preseem via the Preseem shaper (transparent # L2). OSPFv2 cost on edge is the default 10. v6 P2P: # 2606:1c80:0:1002::/64 (edge .1, core .2) # 2. BACKUP: sfp-sfpplus7-core-direct direct fiber. OSPFv2 cost on edge # is 100 (same on core's side). v6 P2P: # 2606:1c80:0:11::/64 (edge .1, core .2) # NOTE: P2P prefix is /64 not /127 — picking ::1/127 + ::2/127 puts the # two ends in *different* /127 networks (verified live 2026-05-09). /64 # matches the per-link allocation in ipv6.md. # Static v6 routes for the infra /48 mirror that cost relationship by # distance (lower = preferred): preseem at distance=1, direct at # distance=2. # # What this script DOES NOT touch (USER CONSTRAINT 2026-05-09): # * TWC v6 eBGP peer `twc-v6` (remote 2605:6000:0:8::f:372, AS11427) — # name doesn't match the ^ibgp- wipe pattern, so it survives. # * The 2606:1c80::/32 BGP network announcement upstream. # * The TWC P2P address 2605:6000:0:8::f:373/127 on sfp-sfpplus12-spectrum # — enabled, so it survives the [find disabled=yes] wipe. # * The existing server LAN address 2606:1c80::1 on vlan9_sfpplus8 — # enabled, so it survives. We only ADD a per-interface ND override # to suppress RA there; the IP and prefix are unmodified. # * v4 OSPFv2 / RIP / firewall rules — v4 control plane is unchanged. # # Apply order: review -> paste in winbox/SSH on edge -> verify with checks # at the bottom -> only then run the matching `core-v6-apply.rsc` so the # preseem and direct /127 endpoints come up symmetrically. # ============================================================================= # ----------------------------------------------------------------------------- # WIPE — only the stale internal-only v6 state on edge. Leaves TWC peering, # the upstream /32 announcement, the server LAN address, and v4 alone. # ----------------------------------------------------------------------------- # Drop any disabled placeholder v6 internal addresses (none on edge today, # but harmless if present). /ipv6 address remove [find disabled=yes] # Drop any leftover OSPFv3 interface entries (we are committing to BGP-only # for v6; any v3 instances on edge have been minimal/stub). /routing ospf-v3 interface remove [find] # Drop only internal iBGP v6 peers if any exist; never touch twc-v6. /routing bgp peer remove [find name~"^ibgp-" and address-families~"ipv6"] # ----------------------------------------------------------------------------- # APPLY — addresses # ----------------------------------------------------------------------------- /ipv6 settings set forward=yes accept-router-advertisements=no /ipv6 address add address=2606:1c80:0:10::254/128 interface=loopback advertise=no comment="edge loopback" add address=2606:1c80:0:11::1/64 interface=sfp-sfpplus7-core-direct advertise=no comment="P2P edge<->core direct (backup)" add address=2606:1c80:0:1002::1/64 interface=sfp-sfpplus11-preseem advertise=no comment="P2P edge<->core via preseem (primary)" # NOTE: the server LAN address 2606:1c80::1 on vlan9_sfpplus8 is left # untouched per user constraint. The ND override below makes it RA-free # without modifying the address itself. # ----------------------------------------------------------------------------- # APPLY — neighbour discovery: SUPPRESS RA on the server LAN # ----------------------------------------------------------------------------- # Server LAN is static-only per the IPv6 plan — disable RA + DHCPv6 hints. # A per-interface entry overrides the global default. /ipv6 nd add interface=vlan9_sfpplus8 disabled=no advertise=no managed-address-configuration=no other-configuration=no comment="server LAN: static only, no SLAAC" # ----------------------------------------------------------------------------- # APPLY — static routes (replace what an IGP would have learned) # ----------------------------------------------------------------------------- # Infra /48 covers all router loopbacks (2606:1c80:0:10::/64), all P2P # /64s, and any future infra slots. Two entries with different distances # pin preseem as primary and direct as backup. The connected /64 server # LAN at 2606:1c80::/64 wins by longest-prefix-match, so this /48 doesn't # steal local server traffic. /ipv6 route add dst-address=2606:1c80::/48 gateway=2606:1c80:0:1002::2 distance=1 comment="infra: via preseem (primary)" add dst-address=2606:1c80::/48 gateway=2606:1c80:0:11::2 distance=2 comment="infra: via direct (backup)" # Tower /44s are learned via iBGP from each tower (next-hop = tower's v6 # loopback inside :10::/64, recursively resolved through the /48 above). # No static needed for them. # ----------------------------------------------------------------------------- # APPLY — firewall (extend the existing minimal v6 ruleset) # ----------------------------------------------------------------------------- # The existing v6 firewall already accepts BGP (179) and established. Add # the rules required for internal-network forwarding + ICMPv6 / link-local. /ipv6 firewall filter add chain=input action=accept protocol=icmpv6 comment="icmpv6 input" add chain=input action=accept src-address=fe80::/10 comment="link-local input" add chain=input action=accept src-address=2606:1c80::/32 comment="internal input" add chain=forward action=accept protocol=icmpv6 hop-limit=equal:1 comment="PMTUD forward" add chain=forward action=accept protocol=icmpv6 comment="icmpv6 forward" add chain=forward action=accept src-address=2606:1c80::/32 dst-address=2606:1c80::/32 comment="internal<->internal" # (we do not add a default-deny; edge has long-running customer transit # paths and a sudden v6 default-deny would break them. existing rules at # the bottom of /ipv6 firewall filter remain authoritative.) # ----------------------------------------------------------------------------- # APPLY — iBGP route filters (v6) # ----------------------------------------------------------------------------- # Edge has ONE iBGP v6 peer: core, which is the v6 RR for the fleet. Edge is # an RR client of core (no `route-reflect=yes` — that flag would mark the # OTHER side as a client, but edge has no clients). Edge sends ::/0 to core # (which reflects it to towers) and learns tower /44s + /128 loopbacks from # core (reflected from each tower). # # in-filter: accept any infra/customer prefix that core (v6 RR) reflects to # us. Length 44 = customer aggregates, 64 = backbone P2Ps + per-tower LAN /64s, # 128 = router loopbacks. Anything else within 2606:1c80::/32 is rejected # (defense in depth — keeps random connected /80 etc. from leaking). /routing filter add chain=ibgp-rr-in prefix=2606:1c80::/32 prefix-length=44-128 action=accept comment="any reflected infra/customer prefix" add chain=ibgp-rr-in action=discard comment="default deny" # out-filter: edge sends only the v6 default to core (which the RR fans # out to every tower). Anything else stays inside edge. add chain=ibgp-rr-out prefix=::/0 prefix-length=0 action=accept comment="default route" add chain=ibgp-rr-out action=discard comment="default deny" # ----------------------------------------------------------------------------- # APPLY — iBGP peer to core (v6 transport, carrying v6 NLRI) # ----------------------------------------------------------------------------- # v6 transport (loopback-to-loopback over 2606:1c80:0:10::254 ↔ ::253) avoids # the v4-mapped-next-hop bug we hit with v4 transport carrying v6 NLRI. Core # (ROS7) is the route reflector — edge is an RR client and, importantly, NOT # a reflector itself (ROS 6.49 does not properly reflect v6 NLRI even with # all RR settings; that's the entire reason core has the role). # update-source=loopback sources the TCP session from edge's loopback iface # (which holds both 10.254.254.254 and 2606:1c80:0:10::254). # nexthop-choice=force-self pins the next-hop edge advertises (::/0) to # edge's own v6 loopback so towers can resolve it via the RR-reflected # /128 path. /routing bgp peer add name=ibgp-rr-core remote-address=2606:1c80:0:10::253 remote-as=393837 update-source=loopback address-families=ipv6 nexthop-choice=force-self ttl=255 in-filter=ibgp-rr-in out-filter=ibgp-rr-out default-originate=always comment="iBGP to core (v6 RR), v6 transport" # ----------------------------------------------------------------------------- # VERIFY (paste after apply) # ----------------------------------------------------------------------------- # /ipv6 address print # /ipv6 route print where active # /ipv6 nd print # /routing bgp peer print where name~"v6" # /routing bgp advertisements print peer=ibgp-verona-v6 # # Expected immediately: # * /ipv6 address print shows 2606:1c80:0:10::254/128 (loopback), # :11::1/127 (direct), :1002::1/127 (preseem), :1::/64 server LAN # * /ipv6 nd print shows the vlan9_sfpplus8 entry with advertise=no # * the new /48 routes show as inactive (gateway unreachable until core # applies), which is fine # * ibgp-verona-v6 is in `connecting` state until verona reaches edge's # v6 loopback (which needs core configured) — for the bare TCP # session, v4 loopback reachability is enough so the session SHOULD # come up immediately. confirm with /routing bgp peer print. # # Once core has its matching v6 apply: # /ping 2606:1c80:0:1002::2 count=3 ;; core preseem-side # /ping 2606:1c80:0:11::2 count=3 ;; core direct-side # /ping 2606:1c80:0:10::253 count=3 ;; core loopback (via preseem) # /ip route check dst=2606:1c80:0:10::101 ;; verona loopback path