# ============================================================================= # core (380) — IPv6 apply script (ROS 7.21.4, BGP-only / no OSPFv3) # ============================================================================= # # Core sits between edge and the towers. Two paths to edge mirror v4: # 1. PRIMARY: sfp-sfpplus1-edge-preseem, /127 :1002::2 — edge cost 10 # 2. BACKUP: ether3-edge-direct, /127 :11::2 — OSPFv2 cost 100 on both # ends; v6 mirrors via static distance. # # Tower-facing P2Ps (per ipv6.md): # ether5-climax :12::/64 (core .1, climax .2) # ether4-newhope :13::/64 (core .1, newhope .2) # ether1-982-60ghz :14::/64 (core .1, 982 .2) # ether6-culleoka-11ghz :15::/64 (core .1, culleoka .2) # # Mgmt LAN: vlan10_combo1 (vlan 10 on combo1-380), v6 = 2606:1c80:1400::1/64 # PPPoE customers: profile name `380`, customer pool 2606:1c80:1401::/48 → /56 # # Two pre-apply fixes required on core: # (a) /routing/bgp/instance bgp-instance-1 currently has as=65530 — must # be 393837 to peer iBGP with edge. We update it in place. # (b) BFD is currently on for ether5-climax (AF24), ether4-newhope, and # ether6-culleoka-11ghz (AF11). Per fleet policy (no BFD on # wireless), we set use-bfd=no on those three OSPFv2 templates. # Wired backbone (sfp-sfpplus1-edge-preseem, ether3-edge-direct) # keeps BFD as-is. # ============================================================================= # ----------------------------------------------------------------------------- # WIPE — drop OSPFv3 + stale internal v6 # ----------------------------------------------------------------------------- /ppp profile set [find] remote-ipv6-prefix-pool="" dhcpv6-pd-pool="" /ipv6 dhcp-server remove [find] /ipv6 dhcp-server option remove [find] /ipv6 dhcp-client remove [find] /ipv6 nd prefix remove [find] /ipv6 nd remove [find default=no] /ipv6 pool remove [find] /ipv6 route remove [find dynamic=no] /ipv6 firewall filter remove [find] /ipv6 firewall mangle remove [find] /ipv6 firewall raw remove [find] /ipv6 address remove [find dynamic=no] /routing ospf interface-template remove [find area=backbone-v3] /routing ospf area remove [find name=backbone-v3] /routing ospf instance remove [find name=default-v3] /routing bgp connection remove [find name~"ibgp" and address-families~"ipv6"] # also remove the disabled placeholder climax connection (will be replaced # by the future climax tower's own iBGP-to-edge session). /routing bgp connection remove [find name=climax and disabled=yes] # ----------------------------------------------------------------------------- # APPLY — fix BGP instance AS (65530 → 393837 to match the fleet) # ----------------------------------------------------------------------------- /routing bgp instance set [find name=bgp-instance-1] as=393837 # ----------------------------------------------------------------------------- # APPLY — turn off BFD on wireless backbone OSPFv2 templates # ----------------------------------------------------------------------------- /routing ospf interface-template set [find interfaces=ether5-climax] use-bfd=no /routing ospf interface-template set [find interfaces=ether4-newhope] use-bfd=no /routing ospf interface-template set [find interfaces=ether6-culleoka-11ghz] use-bfd=no # ----------------------------------------------------------------------------- # APPLY — addresses # ----------------------------------------------------------------------------- /ipv6 settings set forward=yes accept-router-advertisements=no /ipv6 address add address=2606:1c80:0:10::253/128 interface=lo advertise=no comment="loopback" add address=2606:1c80:0:11::2/64 interface=ether3-edge-direct advertise=no comment="P2P core<->edge direct (backup)" add address=2606:1c80:0:1002::2/64 interface=sfp-sfpplus1-edge-preseem advertise=no comment="P2P core<->edge via preseem (primary)" add address=2606:1c80:0:12::1/64 interface=ether5-climax advertise=no comment="P2P core<->climax" add address=2606:1c80:0:13::1/64 interface=ether4-newhope advertise=no comment="P2P core<->newhope" add address=2606:1c80:0:14::1/64 interface=ether1-982-60ghz advertise=no comment="P2P core<->982 60GHz" add address=2606:1c80:0:15::1/64 interface=ether6-culleoka-11ghz advertise=no comment="P2P core<->culleoka" add address=2606:1c80:1400::1/64 interface=vlan10_combo1 advertise=yes comment="380 mgmt LAN" # ----------------------------------------------------------------------------- # APPLY — static routes (replace what an IGP would have learned) # ----------------------------------------------------------------------------- /ipv6 route # v6 default toward edge — preseem primary, direct backup (mirrors v4 cost relationship). add dst-address=::/0 gateway=2606:1c80:0:1002::1 distance=1 comment="default via preseem (primary)" add dst-address=::/0 gateway=2606:1c80:0:11::1 distance=2 comment="default via direct (backup)" # Edge loopback static fallback (so iBGP TCP control plane can reach edge # even before BGP populates anything beyond defaults). add dst-address=2606:1c80:0:10::254/128 gateway=2606:1c80:0:1002::1 distance=1 comment="edge loopback via preseem" add dst-address=2606:1c80:0:10::254/128 gateway=2606:1c80:0:11::1 distance=2 comment="edge loopback via direct" # Per-tower /128 bootstrap statics. Every iBGP RR client needs core to be # able to reach its loopback BEFORE the iBGP session is up — chicken/egg # otherwise. distance=1 wins until BGP comes up; once it does, the session # itself reflects the same /128 with the same forwarding outcome, so these # statics stay harmlessly more-specific. Towers reached *through* climax # (494) or *through* newhope (lowry) take the long way; directly-attached # towers (982, culleoka, newhope) use the matching P2P. add dst-address=2606:1c80:0:10::101/128 gateway=2606:1c80:0:12::2 distance=1 comment="verona loopback (via climax)" add dst-address=2606:1c80:0:10::102/128 gateway=2606:1c80:0:12::2 distance=1 comment="climax loopback" add dst-address=2606:1c80:0:10::104/128 gateway=2606:1c80:0:15::2 distance=1 comment="culleoka loopback" add dst-address=2606:1c80:0:10::108/128 gateway=2606:1c80:0:13::2 distance=1 comment="newhope loopback" add dst-address=2606:1c80:0:10::109/128 gateway=2606:1c80:0:13::2 distance=1 comment="lowry loopback (via newhope)" add dst-address=2606:1c80:0:10::110/128 gateway=2606:1c80:0:14::2 distance=1 comment="982 loopback" add dst-address=2606:1c80:0:10::111/128 gateway=2606:1c80:0:12::2 distance=1 comment="494 loopback (via climax)" # Blackhole core's /44 aggregate so iBGP has the prefix to advertise upward. add dst-address=2606:1c80:1400::/44 blackhole distance=200 comment="core /44 aggregate (iBGP origin)" # ----------------------------------------------------------------------------- # APPLY — neighbour discovery on the 380 mgmt LAN (SLAAC + RDNSS) # ----------------------------------------------------------------------------- /ipv6 nd add interface=vlan10_combo1 ra-interval=3m20s-10m managed-address-configuration=no other-configuration=yes advertise-dns=yes /ipv6 nd prefix add interface=vlan10_combo1 prefix=2606:1c80:1400::/64 autonomous=yes on-link=yes /ipv6 dhcp-server add interface=vlan10_combo1 name=core-mgmt-stateless address-pool=static-only /ipv6 dhcp-server option add name=v6-dns code=23 value="'2606:4700:4700::1111''2606:4700:4700::1001'" # ----------------------------------------------------------------------------- # APPLY — customer PD pool + bind to the 380 PPPoE profile # ----------------------------------------------------------------------------- /ipv6 pool add name=core-cust-pd-1 prefix=2606:1c80:1401::/48 prefix-length=56 /ppp profile set [find name=380] remote-ipv6-prefix-pool=core-cust-pd-1 dhcpv6-pd-pool=core-cust-pd-1 # ----------------------------------------------------------------------------- # APPLY — firewall (mirrors v4 hygiene; deny by default) # ----------------------------------------------------------------------------- /ipv6 firewall filter add chain=input action=accept connection-state=established,related comment="established" add chain=input action=drop connection-state=invalid comment="invalid" add chain=input action=accept protocol=icmpv6 comment="icmpv6" add chain=input action=accept src-address=fe80::/10 comment="link-local" add chain=input action=accept src-address=2606:1c80::/32 comment="internal" add chain=input action=drop comment="default deny" add chain=forward action=accept connection-state=established,related comment="established" add chain=forward action=drop connection-state=invalid comment="invalid" add chain=forward action=accept protocol=icmpv6 hop-limit=equal:1 comment="PMTUD" add chain=forward action=accept protocol=icmpv6 comment="icmpv6" add chain=forward action=accept src-address=2606:1c80::/32 dst-address=2606:1c80::/32 comment="internal-to-internal" add chain=forward action=accept in-interface-list=customer comment="v6 outbound from customers" add chain=forward action=drop comment="default deny" # ----------------------------------------------------------------------------- # APPLY — iBGP route reflector (core is RR; edge + every tower are RR clients) # ----------------------------------------------------------------------------- # Why core (not edge) is the RR: ROS 6.49 on edge does not properly reflect v6 # NLRI even with all RR settings (cluster-id, route-reflect, multihop, correct # in/out filters). ROS7 on core does. So core takes the RR role and edge is # just another iBGP client — it learns tower /44s + /128 loopbacks reflected # from core, and supplies the v6 default that core reflects back to towers. # # cluster-id on the bgp-instance turns this router into a route reflector. # It must be set BEFORE adding the client connections. /routing bgp instance set [find name=bgp-instance-1] cluster-id=10.254.254.253 # Filter for RR-reflected traffic (in & out): allow ::/0, any /44 (customer # aggregates), any /64 (P2P backbone links + per-tower customer LANs), any # /128 (router loopbacks). Reject everything else (defense in depth — keeps # random connected /80 etc. from leaking). # NOTE on syntax: ROS 7.21 routing-filter language doesn't accept range # matchers like `dst-in ` or `dst > ` — only `dst==` # and length comparisons. So we match by length-class, not by sub-range. # The /48 covering customer-vs-infra distinction is enforced by the # ORIGINATING router's own narrower filter (v6-ibgp-out below). /routing filter rule add chain=v6-rr-out disabled=no rule="if (dst==::/0 || dst-len==44 || dst-len==64 || dst-len==128) { accept; } else { reject; }" add chain=v6-rr-in disabled=no rule="if (dst==::/0 || dst-len==44 || dst-len==64 || dst-len==128) { accept; } else { reject; }" # Filter for advertising CORE'S OWN connected/static routes outbound (this # filter runs on each connection's output.filter-chain — what core ORIGINATES # rather than what it REFLECTS). Narrow by exact prefix so only core's /44 # customer aggregate, /128 loopback, and /64 P2P links toward each neighbour # escape into iBGP. add chain=v6-ibgp-out disabled=no rule="if (dst==2606:1c80:1400::/44 || dst==2606:1c80:0:10::253/128 || (dst-len==64 && (dst==2606:1c80:0:11::/64 || dst==2606:1c80:0:12::/64 || dst==2606:1c80:0:13::/64 || dst==2606:1c80:0:14::/64 || dst==2606:1c80:0:15::/64 || dst==2606:1c80:0:1002::/64))) { accept; } else { reject; }" # All client connections share these settings: # templates=default inherits keepalive/holdtime/timers # afi=ip,ipv6 carry both v4 and v6 NLRI (v4 unused on these but harmless) # local.role=ibgp same-AS = iBGP # multihop=yes loopback-to-loopback (more than one hop) # nexthop-choice=force-self pin next-hop to core's v6 loopback # cluster=yes marks the peer as an RR client # input.filter=v6-rr-in limit what we accept # output.filter-chain=v6-rr-out limit what we send (covers reflected + originated) # output.redistribute=connected,static pick up our own /44 + /128 /routing bgp connection add name=ibgp-rr-edge instance=bgp-instance-1 templates=default afi=ip,ipv6 local.role=ibgp local.address=2606:1c80:0:10::253 remote.address=2606:1c80:0:10::254 remote.as=393837 multihop=yes nexthop-choice=force-self cluster=yes input.filter=v6-rr-in output.filter-chain=v6-rr-out output.redistribute=connected,static comment="RR client: edge" add name=ibgp-rr-verona instance=bgp-instance-1 templates=default afi=ip,ipv6 local.role=ibgp local.address=2606:1c80:0:10::253 remote.address=2606:1c80:0:10::101 remote.as=393837 multihop=yes nexthop-choice=force-self cluster=yes input.filter=v6-rr-in output.filter-chain=v6-rr-out output.redistribute=connected,static comment="RR client: verona" add name=ibgp-rr-climax instance=bgp-instance-1 templates=default afi=ip,ipv6 local.role=ibgp local.address=2606:1c80:0:10::253 remote.address=2606:1c80:0:10::102 remote.as=393837 multihop=yes nexthop-choice=force-self cluster=yes input.filter=v6-rr-in output.filter-chain=v6-rr-out output.redistribute=connected,static comment="RR client: climax" add name=ibgp-rr-culleoka instance=bgp-instance-1 templates=default afi=ip,ipv6 local.role=ibgp local.address=2606:1c80:0:10::253 remote.address=2606:1c80:0:10::104 remote.as=393837 multihop=yes nexthop-choice=force-self cluster=yes input.filter=v6-rr-in output.filter-chain=v6-rr-out output.redistribute=connected,static comment="RR client: culleoka" add name=ibgp-rr-newhope instance=bgp-instance-1 templates=default afi=ip,ipv6 local.role=ibgp local.address=2606:1c80:0:10::253 remote.address=2606:1c80:0:10::108 remote.as=393837 multihop=yes nexthop-choice=force-self cluster=yes input.filter=v6-rr-in output.filter-chain=v6-rr-out output.redistribute=connected,static comment="RR client: newhope" add name=ibgp-rr-lowry instance=bgp-instance-1 templates=default afi=ip,ipv6 local.role=ibgp local.address=2606:1c80:0:10::253 remote.address=2606:1c80:0:10::109 remote.as=393837 multihop=yes nexthop-choice=force-self cluster=yes input.filter=v6-rr-in output.filter-chain=v6-rr-out output.redistribute=connected,static comment="RR client: lowry" add name=ibgp-rr-982 instance=bgp-instance-1 templates=default afi=ip,ipv6 local.role=ibgp local.address=2606:1c80:0:10::253 remote.address=2606:1c80:0:10::110 remote.as=393837 multihop=yes nexthop-choice=force-self cluster=yes input.filter=v6-rr-in output.filter-chain=v6-rr-out output.redistribute=connected,static comment="RR client: 982" add name=ibgp-rr-494 instance=bgp-instance-1 templates=default afi=ip,ipv6 local.role=ibgp local.address=2606:1c80:0:10::253 remote.address=2606:1c80:0:10::111 remote.as=393837 multihop=yes nexthop-choice=force-self cluster=yes input.filter=v6-rr-in output.filter-chain=v6-rr-out output.redistribute=connected,static comment="RR client: 494" # ----------------------------------------------------------------------------- # VERIFY (paste after apply) # ----------------------------------------------------------------------------- # /ipv6 address print # /ipv6 route print where active # /routing ospf neighbor print # /routing ospf interface-template print where use-bfd=yes ;; should be wired-only # /routing bgp instance print # /routing bgp connection print # /routing bgp session print # # After edge has applied: # /ping 2606:1c80:0:1002::1 count=3 ;; edge preseem-side # /ping 2606:1c80:0:11::1 count=3 ;; edge direct-side # /ping 2606:1c80:0:10::254 count=3 ;; edge loopback # /ping 2606:4700:4700::1111 count=3 ;; cloudflare end-to-end # /routing bgp session print ;; ibgp-edge-v6 should be Established