<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Networking on NateBent.com</title>
    <link>https://natebent.com/tags/networking/</link>
    <description>Recent content in Networking on NateBent.com</description>
    <generator>Hugo</generator>
    <language>en</language>
    <managingEditor> (Nathan Bent)</managingEditor>
    <atom:link href="https://natebent.com/tags/networking/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>IPv6 at Home: Prefix Delegation with Cox, FortiGate, and an Aging Brocade Core</title>
      <link>https://natebent.com/posts/ipv6-at-home-prefix-delegation-with-cox-fortigate-and-an-aging-brocade-core/</link>
      <pubDate>Sun, 15 Dec 2024 01:00:00 +0000</pubDate><author>Nathan Bent</author>
      <guid>https://natebent.com/posts/ipv6-at-home-prefix-delegation-with-cox-fortigate-and-an-aging-brocade-core/</guid>
      <description>&lt;p&gt;Cox gets a lot of criticism, and most of it&amp;rsquo;s earned. But there&amp;rsquo;s one thing they do right that a lot of ISPs still don&amp;rsquo;t: they hand out a full /56 IPv6 prefix via DHCPv6 Prefix Delegation (DHCPv6-PD). That&amp;rsquo;s 256 individual /64 subnets, which is more than enough for a homelab, however sprawling it gets. This post walks through how I&amp;rsquo;m using that /56 today, why part of my network still requires manual intervention, and what I want to fix down the road.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve never worked with IPv6 prefix delegation before, this should also work as a decent introduction to the concept.&lt;/p&gt;
&lt;h2 id=&#34;a-quick-ipv6-primer&#34;&gt;A quick IPv6 primer&lt;/h2&gt;
&lt;blockquote class=&#34;callout callout-note&#34;&gt;
    &lt;p class=&#34;callout-title&#34;&gt;
      &lt;span class=&#34;callout-icon&#34;&gt;&lt;svg viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&gt;&lt;path d=&#34;M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z&#34;/&gt;&lt;/svg&gt;&lt;/span&gt;
      &lt;span class=&#34;callout-label&#34;&gt;Note&lt;/span&gt;&lt;/p&gt;
    &lt;p&gt;Skip ahead to &lt;a href=&#34;https://natebent.com/posts/ipv6-at-home-prefix-delegation-with-cox-fortigate-and-an-aging-brocade-core/#the-quick-version-of-dhcpv6-pd&#34;&gt;The quick version of DHCPv6-PD&lt;/a&gt; if you already live and breathe this stuff.&lt;/p&gt;
  &lt;/blockquote&gt;&lt;p&gt;IPv4 gives us roughly 4.3 billion addresses, a number that felt inexhaustible in 1981 and turned out to be laughably small once every phone, laptop, doorbell, and light bulb wanted one. We&amp;rsquo;ve spent the last two decades patching around that shortage with NAT, which lets thousands of devices share a single public IP by having a router quietly rewrite packet headers as traffic passes through. It works, but it broke the original end-to-end model of the internet. Anything that needs true bidirectional connectivity (VoIP, peer-to-peer apps, some VPN configurations) ends up needing workarounds like STUN, TURN, or port forwarding just to punch through.&lt;/p&gt;
&lt;p&gt;IPv6 was designed to make that shortage, and the NAT workaround, unnecessary. Instead of 32-bit addresses, IPv6 uses 128 bits: roughly 340 undecillion addresses, or enough to assign a unique address to every grain of sand on Earth several times over. The practical effect is that NAT stops being a requirement. Every device on your network can have its own globally routable address.&lt;/p&gt;
&lt;p&gt;That single change ripples into how IPv6 networks are actually built. Rather than your ISP handing you one address to share, they hand you a prefix, a block of addresses you subnet yourself. Cox delegates a /56 to my FortiGate, which is 256 individual /64 networks to divide up however I like. This happens through DHCPv6-PD: your router requests a prefix and the ISP&amp;rsquo;s infrastructure hands one back, the same way DHCP hands out a single IPv4 lease, just at a much larger scale.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what that actually looks like inside one of my addresses:&lt;/p&gt;
&lt;figure&gt;
      &lt;img src=&#34;https://natebent.com/posts/ipv6-at-home-prefix-delegation-with-cox-fortigate-and-an-aging-brocade-core/images/ipv6-address-anatomy.svg&#34; alt=&#34;Anatomy of an IPv6 address from my /56, showing the 56-bit Cox prefix, 8-bit subnet ID, and 64-bit interface ID&#34;
           data-full=&#34;/posts/ipv6-at-home-prefix-delegation-with-cox-fortigate-and-an-aging-brocade-core/images/ipv6-address-anatomy.svg&#34;
           loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;figcaption&gt;Anatomy of an IPv6 address from my /56, showing the 56-bit Cox prefix, 8-bit subnet ID, and 64-bit interface ID&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Address configuration also works differently day to day. IPv4 devices almost universally get their address via DHCP. IPv6 supports that too, but it also supports SLAAC (Stateless Address Autoconfiguration), where a device constructs its own address by listening to router advertisements and combining the announced prefix with its own interface identifier, no DHCP server required. Two flags in the router advertisement control the division of labor: the Managed flag tells hosts to get full configuration from DHCPv6, and the Other flag tells hosts to keep using SLAAC for addressing but pull other details (like DNS servers) from DHCPv6. Networks often run both simultaneously.&lt;/p&gt;
&lt;p&gt;The /64 boundary is another convention worth internalizing. In IPv4 you might run a /29 for a point-to-point link or a /22 for a large user segment, sizing subnets tightly around host count. IPv6 throws that scarcity mindset out entirely: /64 is the standard subnet size almost everywhere, because SLAAC&amp;rsquo;s addressing math is built around a 64-bit network portion and a 64-bit host portion. A single /64 contains more addresses than the entire IPv4 internet, so there&amp;rsquo;s no meaningful reason to subnet tighter.&lt;/p&gt;
&lt;p&gt;Plenty carries over from IPv4, though. OSPF still works the same way conceptually, just with an IPv6-specific version (OSPFv3) running alongside the IPv4 one. VLANs, trunking, and switch fundamentals don&amp;rsquo;t change at all. The real shift is philosophical: IPv4 design is an exercise in conserving a scarce resource, while IPv6 design assumes abundance and focuses on keeping addressing logically organized.&lt;/p&gt;
&lt;h2 id=&#34;the-quick-version-of-dhcpv6-pd&#34;&gt;The quick version of DHCPv6-PD&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re coming from an IPv4 mindset, prefix delegation feels backwards at first. With IPv4, your router gets one address from your ISP and NATs everything behind it. With IPv6, there&amp;rsquo;s no NAT in the intended design, so your ISP hands you a block of addresses to subnet however you like.&lt;/p&gt;
&lt;p&gt;A DHCPv6-PD exchange has a few pieces worth knowing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PD client: the device that requests a prefix from upstream. My FortiGate is the client toward Cox.&lt;/li&gt;
&lt;li&gt;PD server: the device delegating prefixes to something downstream. My FortiGate also acts as a PD server internally, though only in a limited sense (more below).&lt;/li&gt;
&lt;li&gt;IAID (Identity Association ID): an identifier tied to a specific delegation request. If you have multiple WAN interfaces or want multiple independent delegations, the IAID is how the client and server keep them straight.&lt;/li&gt;
&lt;li&gt;Prefix hint: the client can ask for a specific size, like &lt;code&gt;::/56&lt;/code&gt;. The server isn&amp;rsquo;t obligated to honor it, but Cox does.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Put together, the whole delegation chain in my network looks like this, including the part where it stops being automatic:&lt;/p&gt;
&lt;figure&gt;
      &lt;img src=&#34;https://natebent.com/posts/ipv6-at-home-prefix-delegation-with-cox-fortigate-and-an-aging-brocade-core/images/dhcpv6-pd-flow.svg&#34; alt=&#34;The DHCPv6-PD delegation chain from Cox to the FortiGate, the /56 carved into /64 subnets, and the Brocade where addresses are configured by hand&#34;
           data-full=&#34;/posts/ipv6-at-home-prefix-delegation-with-cox-fortigate-and-an-aging-brocade-core/images/dhcpv6-pd-flow.svg&#34;
           loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;figcaption&gt;The DHCPv6-PD delegation chain from Cox to the FortiGate, the /56 carved into /64 subnets, and the Brocade where addresses are configured by hand&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&#34;my-setup&#34;&gt;My setup&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;WAN side (Cox-facing):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;config system interface
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    edit &amp;#34;WAN-LACP&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set mode dhcp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set type aggregate
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set member &amp;#34;wan2&amp;#34; &amp;#34;wan1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set role wan
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        config ipv6
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set ip6-mode dhcp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set dhcp6-prefix-delegation enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            config dhcp6-iapd-list
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                edit 46
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                edit 1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    set prefix-hint ::/56
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The FortiGate&amp;rsquo;s WAN is a 2-member LACP aggregate (&lt;code&gt;wan1&lt;/code&gt;, &lt;code&gt;wan2&lt;/code&gt;) sitting on Cox&amp;rsquo;s DOCSIS handoff. &lt;code&gt;dhcp6-prefix-delegation enable&lt;/code&gt; turns on the PD client behavior, and the &lt;code&gt;prefix-hint ::/56&lt;/code&gt; tells Cox&amp;rsquo;s DHCPv6 server what size I&amp;rsquo;d like. Cox honors it every time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LAN side (internal transit toward the Brocade):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;config system interface
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    edit &amp;#34;LAN-LACP&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set ip 192.168.255.254 255.255.255.252
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set type aggregate
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set member &amp;#34;internal1&amp;#34; &amp;#34;internal2&amp;#34; &amp;#34;internal3&amp;#34; &amp;#34;internal4&amp;#34; &amp;#34;internal5&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        config ipv6
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set ip6-mode delegated
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set ip6-send-adv enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set ip6-manage-flag enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set ip6-other-flag enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set ip6-delegated-prefix-iaid 1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set ip6-upstream-interface &amp;#34;WAN-LACP&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set ip6-subnet ::1/64
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is the interesting part. &lt;code&gt;ip6-mode delegated&lt;/code&gt; means this interface doesn&amp;rsquo;t get a static IPv6 address. Instead it carves an address out of whatever prefix was delegated on &lt;code&gt;WAN-LACP&lt;/code&gt; (referenced by &lt;code&gt;ip6-delegated-prefix-iaid 1&lt;/code&gt;, matching the IAID from the WAN config). &lt;code&gt;ip6-subnet ::1/64&lt;/code&gt; says &amp;ldquo;take the first /64 out of my delegation and use &lt;code&gt;::1&lt;/code&gt; as this interface&amp;rsquo;s address within it.&amp;rdquo; That resolves to something like &lt;code&gt;2001:db8:1234:b200::1/64&lt;/code&gt; given my current /56.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ip6-manage-flag&lt;/code&gt; and &lt;code&gt;ip6-other-flag&lt;/code&gt; settings control SLAAC behavior on this segment. They tell downstream devices &amp;ldquo;don&amp;rsquo;t just self-assign an address, go ask a DHCPv6 server for configuration too.&amp;rdquo; This matters less than usual here, because this interface isn&amp;rsquo;t really serving end hosts. It&amp;rsquo;s my routing transit link to the Brocade core.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Routing glue (OSPFv3):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;config router ospf6
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    set default-information-originate always
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config area
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        edit 0.0.0.0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config ospf6-interface
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        edit &amp;#34;LAN-LACP&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set interface &amp;#34;LAN-LACP&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set priority 255
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config redistribute &amp;#34;connected&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set status enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;default-information-originate always&lt;/code&gt; means the FortiGate injects an IPv6 default route into OSPFv3 regardless of whether it technically has one of its own, which is useful since I want to guarantee every internal router has a path out, even during a rekey. &lt;code&gt;redistribute connected&lt;/code&gt; pushes locally attached subnets (including any DMZ IPv6 segments living directly on the FortiGate) into OSPF as well.&lt;/p&gt;
&lt;p&gt;One IPv6-specific thing worth noting if you go to verify any of this: OSPFv3 forms adjacencies and installs next-hops using link-local addresses (&lt;code&gt;fe80::/10&lt;/code&gt;), not the global addresses you configured. The first time you look at an IPv6 routing table and see a pile of &lt;code&gt;fe80::&lt;/code&gt; next-hops, that&amp;rsquo;s normal, not broken.&lt;/p&gt;
&lt;h2 id=&#34;where-bgp-fits-in&#34;&gt;Where BGP fits in&lt;/h2&gt;
&lt;p&gt;The FortiGate also runs iBGP (AS 65412) to the Brocade, to a lab peer, and to my three Proxmox hosts via a dynamic neighbor range, mostly to carry the EVPN control plane for Proxmox SDN. Here&amp;rsquo;s the relevant skeleton (trimmed, secrets redacted):&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;config router bgp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    set as 65412
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    set router-id 192.168.255.254
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    set ebgp-multipath enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    set ibgp-multipath enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config neighbor
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        edit &amp;#34;10.169.169.1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set remote-as 65412
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        edit &amp;#34;192.168.255.253&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set remote-as 65412
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config neighbor-group
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        edit &amp;#34;pve-hosts&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set next-hop-self enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set next-hop-self-vpnv4 enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set soft-reconfiguration enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set soft-reconfiguration-evpn enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set remote-as 65412
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config neighbor-range
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        edit 1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set prefix 10.16.230.0 255.255.255.0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            set neighbor-group &amp;#34;pve-hosts&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        next
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config redistribute &amp;#34;connected&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set status enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set route-map &amp;#34;NGBHL_HQ-BGP_Routes&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config redistribute &amp;#34;ospf&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set status enable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        set route-map &amp;#34;NGBHL_HQ-BGP_Routes&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config redistribute6 &amp;#34;connected&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    config redistribute6 &amp;#34;ospf&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    end
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Every one of those sessions negotiates the IPv6 Unicast and VPNv6 address families. FortiOS advertises them by default when the capability is there, and &lt;code&gt;get router info6 bgp neighbors&lt;/code&gt; confirms it on each peer:&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Neighbor capabilities:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Address family IPv6 Unicast: advertised
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Address family VPNv6 Unicast: advertised
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Address family L2VPN EVPN: advertised and received
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; For address family: IPv6 Unicast
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  0 accepted prefixes, 0 prefixes in rib
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  0 announced prefixes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;So the multiprotocol plumbing is up (these are MP-BGP sessions over IPv4 transport), but as of today zero IPv6 routes actually flow through BGP. Notice the &lt;code&gt;redistribute6&lt;/code&gt; blocks in the config above: present, empty, disabled. All IPv6 routing is OSPFv3&amp;rsquo;s job.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s partly deliberate. Turning on &lt;code&gt;redistribute6&lt;/code&gt; is one line, but doing it properly means building an IPv6 route-map and prefix-list mirroring my IPv4 policy, and any &lt;code&gt;prefix-list6&lt;/code&gt; entry that references my delegated space goes stale the moment Cox hands me a new /56. OSPFv3 with &lt;code&gt;default-information-originate always&lt;/code&gt; and &lt;code&gt;redistribute connected&lt;/code&gt; sidesteps that entirely, since neither references a specific prefix. Until I solve the renumbering problem for real, keeping IPv6 out of BGP policy is one less thing to break.&lt;/p&gt;
&lt;h2 id=&#34;the-brocade-where-the-automation-stops&#34;&gt;The Brocade: where the automation stops&lt;/h2&gt;
&lt;p&gt;My core switch is a Brocade ICX 6610. Old, but stacked with 10/40GbE that I&amp;rsquo;m still using nearly all of. It runs OSPFv3 just fine and happily learns routes and the default route from the FortiGate. What it can&amp;rsquo;t do is act as a DHCPv6-PD client. There&amp;rsquo;s no mechanism for it to say &amp;ldquo;hey FortiGate, delegate me a sub-block and I&amp;rsquo;ll configure my own interfaces from it.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;That means every VLAN interface (&lt;code&gt;ve X&lt;/code&gt;) that needs a real IPv6 address has one manually assigned, like this:&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;interface ve 665
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ipv6 address 2001:db8:1234:b200::2/64
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ipv6 ospf area 0.0.0.0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ipv6 ospf active
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;interface ve 2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ipv6 address 2001:db8:1234:b202::1/64
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;interface ve 20
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ipv6 address 2001:db8:1234:b214::1/64
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Each of these was carved out of the /56 using an &lt;a href=&#34;https://www.site24x7.com/tools/ipv6-subnetcalculator.html&#34;&gt;IPv6 subnet calculator&lt;/a&gt;, keeping the last hex digits of the third block roughly aligned with the equivalent IPv4 VLAN ID for my own sanity (VLAN 2 becomes &lt;code&gt;...b202&lt;/code&gt;, VLAN 20 becomes &lt;code&gt;...b214&lt;/code&gt;, and so on). It&amp;rsquo;s a little goofy, but it means I can eyeball a &lt;code&gt;ve&lt;/code&gt; interface&amp;rsquo;s IPv6 address and immediately know which VLAN it belongs to.&lt;/p&gt;
&lt;p&gt;The problem: I don&amp;rsquo;t get a static /56 from Cox. Every time I swap FortiGates, which happens periodically since I source them from decommissioned units at work, I get a brand new one. IPv4 doesn&amp;rsquo;t care; DHCP just hands out a new address and life goes on. IPv6 means going back into the Brocade and manually updating every single &lt;code&gt;ve&lt;/code&gt; interface with the new prefix.&lt;/p&gt;
&lt;blockquote class=&#34;callout callout-caution&#34;&gt;
    &lt;p class=&#34;callout-title&#34;&gt;
      &lt;span class=&#34;callout-icon&#34;&gt;&lt;svg viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&gt;&lt;path d=&#34;M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.141.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z&#34;/&gt;&lt;/svg&gt;&lt;/span&gt;
      &lt;span class=&#34;callout-label&#34;&gt;Caution&lt;/span&gt;&lt;/p&gt;
    &lt;p&gt;Nothing warns you when this happens. The old prefix just stops routing, and every statically configured interface on the Brocade keeps advertising addresses out of space I no longer hold. Dual-stack hosts still prefer IPv6 when it looks available, so the symptom isn&amp;rsquo;t &amp;ldquo;IPv6 is down,&amp;rdquo; it&amp;rsquo;s &amp;ldquo;random things are slow or broken until they fall back to IPv4.&amp;rdquo;&lt;/p&gt;
  &lt;/blockquote&gt;&lt;h2 id=&#34;why-the-prefix-changes-on-every-swap&#34;&gt;Why the prefix changes on every swap&lt;/h2&gt;
&lt;p&gt;For a while I filed this under &amp;ldquo;Cox being Cox,&amp;rdquo; but the mechanism is more specific than that, and it&amp;rsquo;s worth understanding. DHCPv6 doesn&amp;rsquo;t identify clients by MAC address the way DHCPv4 effectively does. It uses a DUID (DHCP Unique Identifier), and the ISP&amp;rsquo;s delegation binding follows that DUID. FortiOS generates a DUID-LLT, which is built from a hardware address plus a generation timestamp, and there&amp;rsquo;s no supported knob I&amp;rsquo;ve found to carry a DUID from one FortiGate to its replacement.&lt;/p&gt;
&lt;blockquote class=&#34;callout callout-insight&#34;&gt;
    &lt;p class=&#34;callout-title&#34;&gt;
      &lt;span class=&#34;callout-icon&#34;&gt;&lt;svg viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&gt;&lt;path d=&#34;M8 0 L9.6 6.4 L16 8 L9.6 9.6 L8 16 L6.4 9.6 L0 8 L6.4 6.4 Z&#34;/&gt;&lt;/svg&gt;&lt;/span&gt;
      &lt;span class=&#34;callout-label&#34;&gt;Interesting!&lt;/span&gt;&lt;/p&gt;
    &lt;p&gt;Your delegated prefix isn&amp;rsquo;t tied to your account or your modem. It follows your router&amp;rsquo;s DHCPv6 identity, the DUID. New hardware means a new DUID, and a new DUID means Cox treats you as a brand new client and hands you a brand new /56.&lt;/p&gt;
  &lt;/blockquote&gt;&lt;p&gt;People running routers where the DUID can be pinned (EdgeOS, pfSense, plain Linux with systemd-networkd) report reasonably sticky prefixes from Cox once they do so, though never guaranteed sticky. On the FortiGate side I get to treat the prefix as rented by the box, not by me, and engineer around it.&lt;/p&gt;
&lt;h2 id=&#34;what-ive-done-about-it-so-far&#34;&gt;What I&amp;rsquo;ve done about it (so far)&lt;/h2&gt;
&lt;p&gt;Since the subnetting logic is fixed, same offsets, same structure, every time, I wrote a small Python script that takes my new first /64 (which becomes subnet #1 by convention) and calculates any subnet index from there, the same way the site24x7 calculator does, but scriptable and instant. It turns a &amp;ldquo;go re-derive eight subnets by hand&amp;rdquo; task into a few seconds of copy-paste. It doesn&amp;rsquo;t touch the Brocade directly yet, but it removes the annoying part of the manual process.&lt;/p&gt;
&lt;h2 id=&#34;what-i-actually-want-full-automation&#34;&gt;What I actually want: full automation&lt;/h2&gt;
&lt;p&gt;The real fix is a script that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pulls the current delegated /56 from the FortiGate (via its REST API, &lt;code&gt;GET /api/v2/monitor/system/interface&lt;/code&gt; or similar, filtered for &lt;code&gt;LAN-LACP&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Recalculates every &lt;code&gt;ve&lt;/code&gt; interface&amp;rsquo;s expected IPv6 address using the same fixed offsets I already use&lt;/li&gt;
&lt;li&gt;Diffs that against the Brocade&amp;rsquo;s current running config&lt;/li&gt;
&lt;li&gt;Pushes the delta via SSH (Paramiko and a scripted CLI session, since the ICX doesn&amp;rsquo;t have a modern API)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is entirely doable. The FortiGate API is well documented and the Brocade will accept scripted SSH config changes without complaint. It&amp;rsquo;s just a project I haven&amp;rsquo;t sat down and built yet.&lt;/p&gt;
&lt;h2 id=&#34;the-longer-term-fix&#34;&gt;The longer-term fix&lt;/h2&gt;
&lt;p&gt;The actual root cause is that the Brocade 6610, however capable it still is for raw switching throughput, is old enough that it predates widespread DHCPv6-PD client support on this class of hardware. Modern L3 switches and routers support acting as a PD client, which would let this whole process happen automatically end to end: Cox delegates to the FortiGate, the FortiGate re-delegates downstream, and the core reconfigures itself.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s a &amp;ldquo;someday&amp;rdquo; project. Replacing a switch with this much 10/40GbE density in active use isn&amp;rsquo;t a small undertaking, and the 6610 has been rock solid otherwise. For now, scripting the delta is the pragmatic path.&lt;/p&gt;
&lt;h2 id=&#34;a-few-things-worth-knowing-before-you-turn-this-on&#34;&gt;A few things worth knowing before you turn this on&lt;/h2&gt;
&lt;p&gt;Some things that aren&amp;rsquo;t specific to my gear but bit me or nearly did:&lt;/p&gt;
&lt;p&gt;The moment you enable IPv6 on a segment, dual-stack hosts start preferring it. There&amp;rsquo;s no gradual rollout; a working router advertisement changes traffic paths immediately. Make sure your IPv6 firewall policy exists before the RA does, because on the FortiGate, IPv6 policies are a separate policy set from IPv4. The default is deny, which is safe, but &amp;ldquo;safe&amp;rdquo; here means &amp;ldquo;IPv6 silently doesn&amp;rsquo;t pass traffic,&amp;rdquo; which is its own fun debugging session.&lt;/p&gt;
&lt;p&gt;If you need addresses that survive a re-delegation, ULA space (&lt;code&gt;fd00::/8&lt;/code&gt; from RFC 4193) is the standard answer for stable internal addressing alongside the global prefix. I&amp;rsquo;ve avoided it so far because running two prefixes per segment brings its own source-address-selection headaches, but it&amp;rsquo;s the escape hatch if the renumbering pain ever outgrows the scripting.&lt;/p&gt;
&lt;h2 id=&#34;useful-debug-commands&#34;&gt;Useful debug commands&lt;/h2&gt;
&lt;p&gt;A few commands I lean on when troubleshooting this setup.&lt;/p&gt;
&lt;h3 id=&#34;state-and-routing-tables&#34;&gt;State and routing tables&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;FortiGate:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;diagnose ipv6 address list
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;get router info6 ospf neighbor
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;get router info6 routing-table ospf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;get router info6 bgp neighbors
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;diagnose debug application dhcp6c -1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;diagnose debug enable&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Brocade ICX:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;show ipv6 interface brief
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;show ipv6 route
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;show ipv6 ospf neighbor
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;show ipv6 ospf database&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&#34;ping-the-ipv6-way&#34;&gt;Ping, the IPv6 way&lt;/h3&gt;
&lt;p&gt;Ping is still the fastest sanity check, but IPv6 adds a wrinkle worth knowing on both platforms: a plain ping only proves the path from the router&amp;rsquo;s default source address. After a renumber, the failure you&amp;rsquo;re hunting is usually a &lt;em&gt;return&lt;/em&gt; path for one specific segment, and for that you need to control the source.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FortiGate.&lt;/strong&gt; The IPv6 ping is &lt;code&gt;execute ping6&lt;/code&gt;, and its behavior is shaped by a persistent set of options under &lt;code&gt;execute ping6-options&lt;/code&gt; (they stick for the session, so &lt;code&gt;reset&lt;/code&gt; when you&amp;rsquo;re done):&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# basic reachability to the Brocade&amp;#39;s side of the transit link
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;execute ping6 2001:db8:1234:b200::2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# prove a specific VLAN&amp;#39;s prefix routes end to end:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# source from that segment&amp;#39;s gateway and ping something external
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;execute ping6-options source6 2001:db8:1234:b214::1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;execute ping6-options repeat-count 5
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;execute ping6 2001:4860:4860::8888
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# check what you&amp;#39;ve left set, then put it back
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;execute ping6-options view-settings
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;execute ping6-options reset&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If that sourced ping works, the whole chain is healthy for that VLAN: the prefix is current, the FortiGate is routing it, and Cox is accepting traffic sourced from it. One caveat from Fortinet&amp;rsquo;s own troubleshooting guidance: don&amp;rsquo;t source a ping from one of the FortiGate&amp;rsquo;s interface addresses to another of its own interface addresses. That fails by design and tells you nothing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Brocade ICX.&lt;/strong&gt; FastIron&amp;rsquo;s version is &lt;code&gt;ping ipv6&lt;/code&gt;, with &lt;code&gt;source&lt;/code&gt; and &lt;code&gt;outgoing-interface&lt;/code&gt; as the useful knobs:&lt;/p&gt;
&lt;div class=&#34;code-wrap&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;! basic reachability to the FortiGate&amp;#39;s side of the transit link
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ping ipv6 2001:db8:1234:b200::1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;! same end-to-end test from the switch&amp;#39;s side:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;! source from a VLAN gateway and ping something external
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ping ipv6 2001:4860:4860::8888 source 2001:db8:1234:b214::1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;! ping a link-local neighbor (needs the interface, since
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;! fe80:: addresses are ambiguous without one)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ping ipv6 fe80::xxxx:xxxx:xxxx:xxxx outgoing-interface ve 665&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;That last one is the IPv6-specific habit to build. Link-local addresses exist on every interface simultaneously, so the switch has no idea which segment you mean unless you tell it. It&amp;rsquo;s also the ping that keeps working when your global prefix is stale, which makes it the cleanest way to separate &amp;ldquo;the transit link is down&amp;rdquo; from &amp;ldquo;my addressing is out of date.&amp;rdquo; If the link-local ping to the FortiGate succeeds but the global one fails, you already know which problem you have.&lt;/p&gt;
&lt;blockquote class=&#34;callout callout-tip&#34;&gt;
    &lt;p class=&#34;callout-title&#34;&gt;
      &lt;span class=&#34;callout-icon&#34;&gt;&lt;svg viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&gt;&lt;path d=&#34;M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z&#34;/&gt;&lt;/svg&gt;&lt;/span&gt;
      &lt;span class=&#34;callout-label&#34;&gt;Tip&lt;/span&gt;&lt;/p&gt;
    &lt;p&gt;Run the &lt;code&gt;dhcp6c&lt;/code&gt; debug immediately after a FortiGate swap. It shows the actual PD exchange with Cox in real time, including the prefix that comes back, which saves you from guessing whether the delay is DHCPv6-PD related or an OSPF adjacency problem further downstream.&lt;/p&gt;
  &lt;/blockquote&gt;&lt;h2 id=&#34;closing-thoughts&#34;&gt;Closing thoughts&lt;/h2&gt;
&lt;p&gt;None of this is exotic. DHCPv6-PD is a mature, well-supported standard, and the FortiGate side of my setup handles it without any fuss. The friction is entirely a hardware-generation problem on the Brocade side, compounded by a prefix that follows a DUID I can&amp;rsquo;t keep. If you&amp;rsquo;re building something similar and shopping for core switching gear, &amp;ldquo;DHCPv6-PD client support&amp;rdquo; is worth putting on your checklist early, because retrofitting automation around a switch that can&amp;rsquo;t do it is a lot more work than just picking one that can.&lt;/p&gt;
&lt;h2 id=&#34;references-and-further-reading&#34;&gt;References and further reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.fortinet.com/document/fortigate/7.6.4/administration-guide/37673/ipv6-prefix-delegation&#34;&gt;IPv6 prefix delegation, FortiOS Administration Guide&lt;/a&gt; - Fortinet&amp;rsquo;s worked example of the upstream/downstream PD configuration used here.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc9915&#34;&gt;RFC 9915: Dynamic Host Configuration Protocol for IPv6 (DHCPv6)&lt;/a&gt; - the current DHCPv6 spec, including prefix delegation. It recently replaced RFC 8415, which itself absorbed the original PD spec (RFC 3633).&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community.fortinet.com/t5/Support-Forum/Getting-DHCPv6-IAID-and-DHCPv6-Client-DUID-on-an-interface/td-p/267387&#34;&gt;Getting DHCPv6 IAID and DHCPv6 Client DUID on an interface, Fortinet Community&lt;/a&gt; - confirms FortiOS uses DUID-LLT as its DHCPv6 client identity, and how to see it in debug output.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://weberblog.net/dhcpv6-prefix-delegation-on-a-fortigate-firewall/&#34;&gt;DHCPv6 Prefix Delegation on a FortiGate Firewall, Weberblog&lt;/a&gt; - a thorough hands-on walkthrough of the same FortiOS PD machinery, including the gotchas around &lt;code&gt;ip6-subnet&lt;/code&gt; defaults.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community.fortinet.com/t5/FortiGate/Troubleshooting-Tip-Using-PING-options-from-the-FortiGate-CLI/ta-p/190774&#34;&gt;Using PING options from the FortiGate CLI, Fortinet Community&lt;/a&gt; - the full &lt;code&gt;ping6-options&lt;/code&gt; reference, including the local-interface-to-local-interface caveat.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.ruckuswireless.com/fastiron/08.0.40/fastiron-08040a-l3guide/GUID-30897B48-C10B-4CE5-8994-0B5A1D4E6CE5.html&#34;&gt;Pinging an IPv6 address, FastIron Layer 3 Routing Configuration Guide&lt;/a&gt; - the &lt;code&gt;ping ipv6&lt;/code&gt; syntax on the ICX, with the &lt;code&gt;source&lt;/code&gt; and &lt;code&gt;outgoing-interface&lt;/code&gt; parameters.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
  </channel>
</rss>
