# =============================================================================
# newhope — IPv6 apply script (ROS 7.21.4, BGP-only / no OSPFv3)
# =============================================================================
#
# Newhope is a relay tower. P2Ps:
#   * core (north)   — ether2-380, v6 P2P 2606:1c80:0:13::/64 (newhope .2)
#   * lowry (south)  — ether6-lowrycrossing, v6 P2P 2606:1c80:0:18::/64 (newhope .1)
# Default upstream toward core via :13::1.
# Lowry's loopback :10::109 is reachable through the :18::/64 link (lowry
# is dual-homed only via newhope today).
#
# Loopback: 2606:1c80:0:10::108/128
# /44 customer aggregate: 2606:1c80:1800::/44
# Mgmt LAN: 2606:1c80:1800::1/64 — assumes a `mgmt` bridge (verify with
# /interface/print before applying).
# PPPoE profile assumed `pppoe`. Customer interface-list assumed `customer`.
# =============================================================================

# -----------------------------------------------------------------------------
# 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 (afi~"ipv6" or address-families~"ipv6")]

# -----------------------------------------------------------------------------
# APPLY — BGP instance
# -----------------------------------------------------------------------------
/routing bgp template set [find name=default] disabled=no

/routing bgp instance
add name=bgp-instance-1 as=393837 router-id=10.254.254.108

# -----------------------------------------------------------------------------
# APPLY — addresses
# -----------------------------------------------------------------------------
/ipv6 settings set forward=yes accept-router-advertisements=no

/ipv6 address
add address=2606:1c80:0:10::108/128 interface=lo                       advertise=no  comment="loopback"
add address=2606:1c80:0:13::2/64    interface=ether2-380               advertise=no  comment="P2P newhope<->core"
add address=2606:1c80:0:18::1/64    interface=ether6-lowrycrossing     advertise=no  comment="P2P newhope<->lowry"
add address=2606:1c80:1800::1/64    interface=bridge_cpe_mgmt                     advertise=yes comment="newhope mgmt LAN"

# -----------------------------------------------------------------------------
# APPLY — static routes
# -----------------------------------------------------------------------------
/ipv6 route
add dst-address=::/0                    gateway=2606:1c80:0:13::1 distance=1   comment="default via core"
add dst-address=2606:1c80:0:10::253/128 gateway=2606:1c80:0:13::1 distance=1   comment="core loopback (iBGP bootstrap)"
add dst-address=2606:1c80:0:10::254/128 gateway=2606:1c80:0:13::1 distance=1   comment="edge loopback via core"

# Lowry sits one hop further out via the newhope<->lowry P2P. newhope is
# the only neighbour that can deliver to lowry's loopback, so we hold a
# static for it; without this, traffic for :10::109 from core/edge loops
# at newhope until iBGP fully converges.
add dst-address=2606:1c80:0:10::109/128 gateway=2606:1c80:0:18::2 distance=1   comment="lowry loopback via P2P"

add dst-address=2606:1c80:1800::/44 blackhole distance=200 comment="newhope /44 aggregate (iBGP origin)"

# -----------------------------------------------------------------------------
# APPLY — neighbour discovery on the mgmt LAN
# -----------------------------------------------------------------------------
/ipv6 nd
add interface=bridge_cpe_mgmt ra-interval=3m20s-10m managed-address-configuration=no other-configuration=yes advertise-dns=yes

/ipv6 nd prefix
add interface=bridge_cpe_mgmt prefix=2606:1c80:1800::/64 autonomous=yes on-link=yes

/ipv6 dhcp-server
add interface=bridge_cpe_mgmt name=newhope-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 PPPoE profile
# -----------------------------------------------------------------------------
/ipv6 pool
add name=newhope-cust-pd-1 prefix=2606:1c80:1801::/48 prefix-length=56

/ppp profile
set [find name=newhope] remote-ipv6-prefix-pool=newhope-cust-pd-1 dhcpv6-pd-pool=newhope-cust-pd-1

# -----------------------------------------------------------------------------
# APPLY — firewall
# -----------------------------------------------------------------------------
/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 src-address=2606:1c80:1800::/44                   comment="v6 outbound from newhope customers"
add chain=forward action=accept src-address=2606:1c80:1900::/44                   comment="v6 outbound from lowry customers (transit)"
add chain=forward action=drop                                                     comment="default deny"

# -----------------------------------------------------------------------------
# APPLY — iBGP to core (v6 RR)
# -----------------------------------------------------------------------------
/routing filter rule
add chain=v6-ibgp-out disabled=no rule="if (dst==2606:1c80:1800::/44 || dst==2606:1c80:0:10::108/128 || (dst-len==64 && (dst==2606:1c80:0:13::/64 || dst==2606:1c80:0:18::/64))) { accept; } else { reject; }"

/routing bgp connection
add name=ibgp-rr-core instance=bgp-instance-1 templates=default \
    afi=ip,ipv6 local.role=ibgp local.address=2606:1c80:0:10::108 \
    remote.address=2606:1c80:0:10::253 remote.as=393837 multihop=yes \
    nexthop-choice=force-self output.filter-chain=v6-ibgp-out \
    output.redistribute=connected,static \
    comment="iBGP to core (v6 RR), v6 transport"

# -----------------------------------------------------------------------------
# VERIFY
# -----------------------------------------------------------------------------
# /ipv6 address print
# /ipv6 route print where active
# /routing bgp session print
# /ping 2606:1c80:0:10::253 count=3  ;; core
# /ping 2606:1c80:0:10::109 count=3  ;; lowry (after lowry applies)
