<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-martin-deploying-ipv6-data-center-03" category="info" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true">

<front>
<title abbrev="deploying-ipv6-data-center">Deploying IPv6 in Data Centers</title><seriesInfo value="draft-martin-deploying-ipv6-data-center-03" status="informational" name="Internet-Draft"></seriesInfo>
<author initials="F." surname="Martin" fullname="Franck Martin"><organization>Peachymango.org</organization><address><postal><street></street>
</postal><email>franck@peachymango.org</email>
</address></author><author initials="P.S." surname="Tiesel" fullname="Philipp S. Tiesel"><organization>SAP SE</organization><address><postal><street></street>
</postal><email>philipp@tiesel.net</email>
<email>philipp.tiesel@sap.com</email>
</address></author><date year="2026" month="September" day="24"></date>
<area>ops</area>
<workgroup>IPv6 Operations</workgroup>
<keyword>IPv6</keyword>
<keyword>data center</keyword>
<keyword>SRE</keyword>
<keyword>software</keyword>
<keyword>operations</keyword>
<keyword>deployment</keyword>

<abstract>
<t>Data center operators are moving toward IPv6-only operation to simplify
addressing, restore end-to-end connectivity, and meet operator and
government timelines. Much published IPv6 guidance targets network engineers;
this document instead addresses <strong>Site Reliability Engineers (SREs)</strong> and
<strong>Software Engineers (SWEs)</strong> who deploy, operate, and debug services in
<strong>operator-owned data centers</strong>. It is organized in four parts --- migration
strategies, building the data center, tools and best practices, and pitfalls ---
with IPv6 fundamentals as an appendix. It documents common software and
infrastructure gaps and offers practical deployment patterns aligned with the
IPv6 Operations (v6ops) working group charter.</t>
</abstract>

<note><name>About This Document</name>
<t>This note is to be removed before publishing as an RFC.</t>
<t>The latest revision of this draft can be found at
<eref target="https://github.com/franckhlmartin/ietf-draft-deploying-ipv6-data-center/">https://github.com/franckhlmartin/ietf-draft-deploying-ipv6-data-center/</eref>.
An HTML editor's copy is at
<eref target="https://franckhlmartin.github.io/ietf-draft-deploying-ipv6-data-center/draft-martin-deploying-ipv6-data-center.html">https://franckhlmartin.github.io/ietf-draft-deploying-ipv6-data-center/draft-martin-deploying-ipv6-data-center.html</eref>.
Status information for this document may be found at
<eref target="https://datatracker.ietf.org/doc/draft-martin-deploying-ipv6-data-center/">https://datatracker.ietf.org/doc/draft-martin-deploying-ipv6-data-center/</eref>.</t>
<t>Discussion of this document takes place on the v6ops Working Group
mailing list (<eref target="mailto:v6ops@ietf.org">mailto:v6ops@ietf.org</eref>), which is archived at
<eref target="https://mailarchive.ietf.org/arch/browse/v6ops/">https://mailarchive.ietf.org/arch/browse/v6ops/</eref>. Subscribe at
<eref target="https://www.ietf.org/mailman/listinfo/v6ops/">https://www.ietf.org/mailman/listinfo/v6ops/</eref>.</t>
<t>Source for this draft and an issue tracker can be found at
<eref target="https://github.com/franckhlmartin/ietf-draft-deploying-ipv6-data-center">https://github.com/franckhlmartin/ietf-draft-deploying-ipv6-data-center</eref>.</t>
</note>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>

<section anchor="audience-and-purpose"><name>Audience and Purpose</name>
<t>This document is written for <strong>Site Reliability Engineers (SREs) and Software
Engineers (SWEs)</strong> who run services in data
centers --- not primarily for network engineers designing routing policy.
Network teams still own prefixes, routing, and firewalls, but IPv6
deployment succeeds or fails in application code, configuration management,
monitoring pipelines, and the long tail of enterprise software that assumes
IPv4. It also fails when the work is <strong>unscheduled</strong> against competing
priorities, or when security and network teams meet the design only at cutover
(see <xref target="programme-sponsorship"></xref>).</t>
<t><strong>Scope:</strong> The primary audience runs services on infrastructure the organization
<strong>owns or directly controls</strong> --- operator-managed networks, prefixes, routing,
firewalls, and bare-metal or virtualized hosts in <strong>physical or private data
centers</strong>. This document does <strong>not</strong> prescribe how to deploy IPv6 <strong>natively
inside third-party Infrastructure-as-a-Service (IaaS)</strong> platforms (public cloud
VPCs, provider-managed Kubernetes, and similar). Each cloud provider imposes its
own addressing models, quotas, APIs, and processes; the deployer is <strong>constrained</strong>
by those platform choices in ways this draft cannot generalize. Operators with
hybrid estates <bcp14>SHOULD</bcp14> still understand cloud IPv6 gaps and connectivity
limits (see <xref target="hybrid-cloud"></xref>) because those constraints often determine whether
an on-premise IPv6-only program can succeed.</t>
</section>

<section anchor="related-guides"><name>Related Guides</name>
<t>This document focuses on data center SRE and software engineering practice.
Operators and developers may also find these <strong>informative guides</strong> useful
alongside this draft:</t>

<ul spacing="compact">
<li><xref target="RFC7381"></xref> --- enterprise IPv6 deployment framework (v6ops)</li>
<li><xref target="RFC4038"></xref> --- application aspects of IPv6 transition</li>
<li><xref target="I-D.ietf-v6ops-ipv6-app-testing"></xref> --- testing applications' IPv6 support across
IPv4-only, dual-stack, IPv6-only with NAT64, and IPv6-only-strict scenarios (v6ops);
the testing companion to the deployment guidance in this document</li>
<li><xref target="I-D.ietf-v6ops-ipv6-only"></xref> --- IPv6-only and IPv6-Mostly terminology definitions (v6ops)</li>
<li><xref target="I-D.ietf-6man-rfc6724-update"></xref> --- RFC 6724 policy-table update: known-local
ULA preference over IPv4 and over GUA for local use (6man; RFC Editor queue)</li>
<li><xref target="I-D.martin-ipv6-addr-selection-updates"></xref> --- proposed further destination-
selection updates; includes an attempt to preserve DNS order where Rule 9
would otherwise collapse it. Until that is implemented on hosts, clients
still handle load spreading (see <xref target="address-selection"></xref>)</li>
<li><xref target="ARCEP-IPV6-GUIDE"></xref> --- enterprise IPv6 rollout guidance from ARCEP (France)</li>
<li><xref target="ARIN-APPS-V6"></xref> --- application and software developer guidance from ARIN</li>
</ul>
<t>They overlap partially with sections here (applications, addressing, operations)
but cover broader enterprise and regional context.</t>
</section>

<section anchor="document-structure"><name>Document Structure</name>
<t>This document is organized by audience job --- <strong>strategy</strong>, then <strong>build</strong>, then
<strong>tools</strong>, then <strong>pitfalls</strong> --- rather than by protocol layer or a single
linear migration playbook. Overlapping themes (for example internal vs external
scope in <xref target="internal-external"></xref> and <xref target="provision-not-transform"></xref>) appear where each
audience needs them; sections cross-link rather than repeat editorially. IPv6
fundamentals for software engineers (<xref target="ipv6-fundamentals"></xref>) sit as an <strong>appendix</strong>
at the end for shared vocabulary; they are not the linear starting chapter.</t>
<t><strong>Part I --- Migration Strategies</strong> (<xref target="transition"></xref>): scoping IPv6-only programs,
programme sponsorship and early procurement (<xref target="programme-sponsorship"></xref>,
<xref target="procurement"></xref>), inventory and metrics (<xref target="observability"></xref>), hybrid on-premise and
cloud (<xref target="hybrid-cloud"></xref>), and noticeable IPv4 friction (<xref target="ipv4-friction"></xref>) ---
define policy and measurement before bulk technical change.</t>
<t><strong>Part II --- Building the IPv6 Data Center:</strong> addressing and host/container
provisioning (<xref target="internet-addressing"></xref> and related subsections), plus progress
metrics that show dual-stack or IPv6-only adoption in the fabric.</t>
<t><strong>Part III --- Tools &amp; Best Practices:</strong> developer and pre-production
environments (<xref target="dev-environments"></xref>), IPv6-only jump hosts
(<xref target="ipv6-only-jump-hosts"></xref>), network diagnostics (<xref target="network-diagnostics"></xref>), and
tracking application readiness (<xref target="application-readiness"></xref>).</t>
<t><strong>Part IV --- Pitfalls:</strong> out-of-band management (<xref target="oob-management"></xref>), DNS
registration (<xref target="dns-registration"></xref>), ICMPv6 and PMTUD (<xref target="icmpv6-pmtud"></xref>), and
application-layer traps --- localhost (<xref target="localhost-pitfalls"></xref>), name resolution
(<xref target="name-resolution"></xref>), client-side load balancing (<xref target="client-load-balancing"></xref>),
address storage, and language runtimes.</t>
<t><strong>Reading paths by role:</strong></t>

<ul spacing="compact">
<li><em>Program lead / engineering manager:</em> Part I first (including
<xref target="programme-sponsorship"></xref>, <xref target="procurement"></xref>, and <xref target="ipv4-only-exceptions"></xref>), then
skim Parts II and III as overview.</li>
<li><em>Business sponsor / security lead:</em> <xref target="programme-sponsorship"></xref>,
<xref target="ipv4-only-exceptions"></xref>, <xref target="icmpv6-pmtud"></xref>, then Security Considerations.</li>
<li><em>Network / DC infrastructure engineer:</em> Part II addressing, then Part IV on
OOB, DNS registration, and ICMPv6/PMTUD; consult <xref target="ipv6-fundamentals"></xref> when
vocabulary is needed.</li>
<li><em>SRE/SWE engineer:</em> Part I <xref target="observability"></xref>, Part III tools and
readiness tracking, then Part IV application pitfalls; consult
<xref target="ipv6-fundamentals"></xref> when vocabulary is needed.</li>
<li><em>Full migration owner:</em> linear --- Parts I through IV, then Security
Considerations, with <xref target="ipv6-fundamentals"></xref> as reference.</li>
</ul>
</section>

<section anchor="requirements-language"><name>Requirements Language</name>
<t>The key words &quot;<bcp14>MUST</bcp14>&quot;, &quot;<bcp14>MUST NOT</bcp14>&quot;, &quot;<bcp14>REQUIRED</bcp14>&quot;, &quot;<bcp14>SHALL</bcp14>&quot;,
&quot;<bcp14>SHALL NOT</bcp14>&quot;, &quot;<bcp14>SHOULD</bcp14>&quot;, &quot;<bcp14>SHOULD NOT</bcp14>&quot;, &quot;<bcp14>RECOMMENDED</bcp14>&quot;,
&quot;<bcp14>NOT RECOMMENDED</bcp14>&quot;, &quot;<bcp14>MAY</bcp14>&quot;, and &quot;<bcp14>OPTIONAL</bcp14>&quot; in this document are to
be interpreted as described in BCP 14 <xref target="RFC2119"></xref> <xref target="RFC8174"></xref> when, and only
when, they appear in all capitals, as shown here.</t>
</section>
</section>

<section anchor="transition"><name>Part I: Migration Strategies</name>
<t>This section underlines one uncomfortable truth: The hardest challenges
on the way to IPv6 (only) are organizational issues and incentivization.
Thus, it provides guidance how to pick and slice candidates for
a migration to IPv6 only and how to structure such a migration effort.</t>
<t>While it makes sense to roll out dual stack and IPv6 mostly in breadth
for access networks, a clear scope is essential for the success of
IPv6 only project. Depending on the organizational structure and
experience with IPv6, the scope should be limited to a manageable
size like a application landscape, platform instance or data center.</t>

<section anchor="reasons-to-start-ipv6-only-programs"><name>Reasons to start IPv6 only Programs</name>
<t>In most commercial environments, IPv6 only projects over the size of a
proof of concept are hard to justify from a business perspective.
Therefore, the migration towards IPv6 only should be planned around
other activities including, but not limited to:</t>

<ul spacing="compact">
<li>Major hardware replacements,</li>
<li>Data center builds or expansions,</li>
<li>Re-platforming of applications or infrastructures,</li>
<li>Move from on-premise to the cloud (or the other way around),</li>
<li>Integration of AI workloads,</li>
<li>Introduction of zero trust networking, and</li>
<li>Containerization.</li>
</ul>
<t>While the aforementioned projects justify to start the project,
realizing them with an IPv6 only architecture provides cost savings,
can improve scalability, provide growth opportunities and may
benefit overall security management by reducing overall complexity,
and allowing end-to-end audition of data flows.
Especially if such activities require costly IPv4 numbering re-architecture
or acquisition of IPv4 address space, a cost benefit analysis will
likely be in favour of an IPv6-only architecture.</t>
</section>

<section anchor="provision-not-transform"><name>Easier to Provision Than to Transform</name>
<t><strong>It is easier to provision IPv6 correctly than to transform a running service.</strong>
Enabling dual-stack on a server, container, or service that was deployed
IPv4-only is already a substantial change --- addresses, ACLs, DNS, health
checks, and often application configuration --- then <strong>restarting in place</strong>
and hoping nothing was missed. Going <strong>IPv6-only</strong> is a further step: it
removes the IPv4 safety net and usually requires more of the dependency and
operations stack to be ready. Both benefit from greenfield timing; they are
not the same difficulty. Provisioning time already runs those checks, supports
canary or phased ramp-up, and catches failures before the service takes
production traffic.</t>
<t>Teams <bcp14>SHOULD</bcp14> treat every <strong>new service</strong>, <strong>new software version</strong>, and
<strong>rewrite of an existing application</strong> as an opportunity to ship <strong>IPv6-only on
internal interfaces</strong> from the start (see <xref target="internal-external"></xref>), with <strong>dual-stack
only where external reachability requires it</strong>, rather than cloning an IPv4-only
template and scheduling conversion later. Brownfield conversion remains necessary
for legacy estates, but the default for greenfield work <bcp14>SHOULD NOT</bcp14> be
&quot;IPv4 now, IPv6 someday.&quot;</t>
</section>

<section anchor="programme-sponsorship"><name>Programme Sponsorship and Stakeholders</name>
<t><xref target="RFC7381"></xref> covers enterprise IPv6 deployment more broadly. This subsection is
the SRE-facing minimum: who must prioritize the work and who must be in the room
before the addressing plan is frozen.</t>
<t><strong>Sponsorship schedules the work; escalation only unblocks it.</strong> A named
<strong>business sponsor</strong> ranks IPv6 against competing quarterly work so teams can
staff the migration. The same person <bcp14>MAY</bcp14> also approve IPv4-only exceptions
or escalate blocked teams, but those are different decisions: sponsorship puts
the programme on the plan; exception approval bounds a waiver
<xref target="ipv4-only-exceptions"></xref>; escalation clears obstruction after the work is
already scheduled. Without sponsorship the programme never gets scheduled in
the first place.</t>
<t>Treat <strong>security and the business as primary stakeholders from kickoff</strong>, not as
late approval gates. Bring into the room early:</t>

<ul spacing="compact">
<li><strong>Security</strong> --- threat models and security policies <strong>before</strong> perimeter
rule changes (see <xref target="icmpv6-pmtud"></xref> and Security Considerations).</li>
<li><strong>Network</strong> --- prefix policy and allocation lead time (see
<xref target="prefix-allocation"></xref>).</li>
<li><strong>Platform / SRE</strong> --- inventory, observability, and jump-host readiness.</li>
<li><strong>Owners of tier-1 services</strong> --- consent before a service flips to dual-stack
or IPv6-only.</li>
</ul>
<t>An IPv4-only exception process governs one artefact well; it does not replace
sponsorship or early stakeholder consent.</t>

<section anchor="procurement"><name>Procurement and Long-Lead Hardware</name>
<t>Update <strong>purchase requirements, RFPs, and vendor questionnaires</strong> at program
kickoff --- ideally <strong>before</strong> any production dual-stack or IPv6-only cutover
--- so new acquisitions cannot quietly extend the IPv4-only lifetime of the
fleet. Infrastructure and facility gear often have 10+ refresh
cycles and little or no field-upgradable network stack; buying IPv4-only
today can block IPv4 decommissioning long after application code is ready
(see <xref target="oob-management"></xref>).</t>
<t>Operators <bcp14>SHOULD</bcp14>:</t>

<ul spacing="compact">
<li><strong>Require IPv6-only and dual-stack support</strong> for new purchases that attach to
data center or management networks --- compute BMCs, switches, consoles,
PDUs, environmental monitors, <strong>network time appliances</strong> (NTP or PTP,
including GPS-synced stratum servers), <strong>storage appliances</strong>, and similar
long-lived devices --- not only for application software.</li>
<li>Distinguish <strong>systems the organization owns or controls</strong> (and can mandate
in contracts) from <strong>systems it does not</strong> (public cloud SKUs, SaaS, leased
facility gear) so inventory and exception tracking cover both classes early
(see <xref target="observability"></xref> and <xref target="hybrid-cloud"></xref>).</li>
<li>Treat written vendor claims as necessary but insufficient: qualify candidates
in a <strong>lab or acceptance network</strong>, including an <strong>IPv6-only</strong> path where
practical (see <xref target="ipv6-only-jump-hosts"></xref> for IPv6-only guest or demo Wi-Fi),
before production purchase or racking.</li>
</ul>
<t>Procurement language is the contractual backup; lab &quot;show me&quot; testing catches
products that claim IPv6 readiness and fail under operational load.</t>
</section>
</section>

<section anchor="observability"><name>Inventory and Metrics</name>
<t>IPv6 migration needs <strong>inventory plus measurement</strong>: a service list with IPv6
readiness labels, automated discovery of what is missing from that list, and
time-series metrics that show progress toward dual-stack or IPv6-only targets.</t>
<t>The inventory in <xref target="application-readiness"></xref> <bcp14>MUST</bcp14> list every application and
platform component with a readiness state (for example: IPv6-only ready,
dual-stack, IPv4-only, unknown). Inventory alone is not enough --- operators
<bcp14>SHOULD</bcp14> run periodic <strong>discovery</strong> that compares running processes, container
images, load balancer pools, and DNS names against the catalog and <strong>flags
unregistered services</strong>. Shadow deployments and shared hosts routinely run
software that no team has classified.</t>
</section>

<section anchor="ipv4-only-exceptions"><name>IPv4-Only Exceptions and Remediation Plans</name>
<t>The business will sometimes <strong>require an IPv4-only product, service, or
technology</strong> --- a vendor constraint, acquisition, regulated workload, or
time-to-market trade-off. Business goals matter, but <strong>IPv4-only dependency
SHOULD NOT be discovered only after full production adoption</strong>, when rollback is
expensive and the migration program has already assumed dual-stack or IPv6-only
readiness.</t>
<t><strong>Default to hard failure on missing IPv6 early</strong> in inventory, CI, dependency
gates, and synthetic checks (see <xref target="observability"></xref> and <xref target="application-readiness"></xref>)
so non-compliant software surfaces before it reaches tier-1 paths. Where IPv4-only
is genuinely required, use a <strong>formal exception process</strong> --- the same discipline
security teams apply to policy waivers:</t>

<ul spacing="compact">
<li><strong>Record the business reason</strong> for IPv4-only adoption and who approved it.</li>
<li><strong>Require a remediation plan</strong> --- path to dual-stack, IPv6 support, or
replacement --- with <strong>milestones and a target date</strong>.</li>
<li><strong>Track progress</strong> in the same service catalog and dashboards used for migration
metrics; exceptions <bcp14>SHOULD</bcp14> expire or be renewed on review, not roll forever.</li>
<li><strong>Flag dependents</strong> so downstream teams know they are building on a known
exception.</li>
</ul>
<t>An approved exception <bcp14>MAY</bcp14> permit production use of IPv4-only software for a
bounded period; it <bcp14>MUST NOT</bcp14> be an informal verbal waiver. Review open
exceptions in change advisory or migration governance the same way security
reviews open risk acceptances --- stale plans become blockers again when dates
slip without an updated timeline.</t>
</section>

<section anchor="hybrid-cloud"><name>Hybrid On-Premise and Cloud Environments</name>
<t>This section is <strong>in scope</strong> for operator-owned data centers that <strong>connect to</strong>
public cloud; it is <strong>not</strong> a guide to replacing the data center with IaaS or to
running production workloads <strong>inside</strong> provider-controlled virtual networks.
Native IPv6 deployment on public cloud providers like AWS, Azure, GCP,
or other IaaS platforms belongs in provider documentation or a separate document.
Managed services, and control-plane IPv6 support differ by vendor, region, and
SKU in ways no single recommendation can capture. The material below <strong>does</strong>
matter for on-premise migration: cloud dependencies, private connectivity, and
provider IPv6 gaps routinely block or reshape IPv6-only programs on
operator-managed fabric even when compute stays in the physical data center.</t>
<t>Most enterprises are not pure on-premise: data centers connect to <strong>public
cloud</strong> providers for burst capacity, managed
services, disaster recovery, and SaaS integration.
At the time of writing, <strong>IPv6 support across cloud control planes and
managed services is incomplete</strong> --- capabilities differ
by provider, region, SKU, and release.</t>
<t>Hybrid gap analysis belongs in <strong>Part I inventory and early program planning</strong>,
not a discovery phase after the on-premise fabric is already IPv6-only,
as subtile limitations can dramatically effect feasibility of architectural
pattern and prevent reaching project goals on some public cloud providers.</t>

<section anchor="connectivity-models"><name>Connectivity Models</name>
<t>Migration design <strong>depends on how on-premise reaches cloud</strong>:</t>

<ul spacing="compact">
<li><strong>Centralized gateway or cloud edge</strong> --- on-premise workloads reach cloud APIs
and resources through a <strong>narrow path</strong>: site-to-site VPN, Direct Connect,
ExpressRoute, Cloud Interconnect, transit gateway, or operator translation at
the border (see <xref target="internet-egress"></xref>). IPv6 may terminate at that gateway; an
internal v6-only host might reach cloud only via a dual-stack hub or
translation. Prefix plans, ACLs, DNS views, and observability probes must
anchor on that <strong>choke point</strong>.</li>
<li><strong>Direct or flat hybrid routing</strong> --- on-premise and cloud workloads share
<strong>routable reachability</strong> (extended L3, cloud CIDRs advertised into the DC,
cross-site service mesh). <strong>Any host may connect to any cloud instance</strong> on
the allowed paths; IPv4 and IPv6 <strong>must both be validated end-to-end</strong>, including
cloud VPC/VNet IPv6 CIDRs, security groups, network ACLs, private endpoints,
and on-premise firewall policy.</li>
</ul>
<t>Document which model each environment uses <strong>before</strong> declaring internal
IPv6-only. A data center that is v6-only on the fabric but cloud-connected only
through an <strong>IPv4-only VPN or private link</strong> still depends on translation or
exceptions at the edge --- a common hidden blocker.</t>
</section>

<section anchor="cloud-provider-gap-analysis"><name>Cloud Provider Gap Analysis</name>
<t>Cloud portfolios change frequently. Operators <bcp14>SHOULD</bcp14> maintain a
<strong>provider-specific IPv6 matrix</strong> for every service in use --- compute, load
balancing, databases, object storage, key management, logging, identity, managed
Kubernetes control planes, firewalls, WAF, PrivateLink-style endpoints, and
inter-region peering --- with readiness labels and notes on <strong>region, tier, and
verification date</strong>.</t>
<t>Label by the <strong>default client path</strong> used in production (the hostname and options
the running SDK, CLI, or library uses with <strong>no extra configuration</strong>), not by a
provider capability page or an alternate dual-stack endpoint that applications do
not call unless reconfigured:</t>

<ul spacing="compact">
<li><strong>supported</strong> --- the default client path resolves and works on IPv6.</li>
<li><strong>supported-not-default</strong> --- IPv6 exists only behind an alternate hostname,
opt-in flag, or non-default region or SKU; production without that change stays
on IPv4.</li>
<li><strong>partial</strong> --- incomplete feature coverage (some APIs, regions, or SKUs),
distinct from &quot;complete but opt-in.&quot;</li>
<li><strong>unsupported</strong> / <strong>unknown</strong> --- no usable IPv6 path, or not yet verified.</li>
</ul>
<t>Defaults move over time; re-check on the verification-date column rather than
assuming a past &quot;supported&quot; label still matches what clients dial today.</t>
<t>Where clients can use <strong>operator-controlled DNS</strong> (private zones, service
discovery, or aliases under a stable convention), prefer names <strong>independent of
the provider's hostname taxonomy</strong> (see <xref target="name-resolution"></xref>). Publish A and AAAA
(or point aliases) under that convention so application configuration does not
inherit provider path quirks --- for example when one provider hostname has AAAA
and a sibling default does not. Operator names are a mitigation when the client
stack allows them; the matrix still records whether the <strong>provider default</strong> path
is IPv6-ready.</t>
<t><strong>Identify blockers early:</strong> review architecture diagrams and infrastructure-as-code
for implicit IPv4 assumptions (RFC 1918-only security groups, IPv4 health checks,
managed endpoints without AAAA on the default path, IPv4-only egress appliances).
Open <strong>provider support cases and feature requests</strong> as soon as a required service
lacks IPv6 --- enterprise cutover dates cannot wait for roadmap surprises
discovered in production. Where IPv6 exists only as <strong>supported-not-default</strong> or
only in select regions or SKUs, record that constraint in the inventory and use
<xref target="ipv4-only-exceptions"></xref> when the business must stay on IPv4-only cloud paths
temporarily.</t>
</section>

<section anchor="cloud-as-platform-software"><name>Cloud as Platform Software</name>
<t>From the data center team's perspective, <strong>cloud is platform software the business
cannot fully control</strong> --- APIs, quotas, and feature availability change on the
provider's schedule. Apply the same discipline as <xref target="application-readiness"></xref>: list
each cloud dependency in the fleet inventory, assign IPv6 readiness labels, and
<strong>raise gaps before platform adoption</strong>, not after teams have built on IPv4-only
managed services.</t>
<t>Hybrid programs <bcp14>SHOULD</bcp14> include <strong>cloud account and landing-zone reviews</strong> in
the same governance cadence as on-premise migration metrics (see <xref target="observability"></xref>).
A service marked &quot;IPv6-ready on-premise&quot; that calls an <strong>IPv4-only cloud API</strong>,
depends on a <strong>supported-not-default</strong> cloud path without the required client
change, or runs on an <strong>IPv4-only managed control plane</strong> is not ready for
internal v6-only operation. Treat cloud like any other long-lead vendor:
inventory, support tickets, and exception tracking <bcp14>SHOULD</bcp14> start at program
kickoff.</t>
</section>
</section>

<section anchor="ipv4-friction"><name>Adding Noticeable IPv4 Friction</name>
<t>This technique belongs in a <strong>working dual-stack</strong> environment where <strong>IPv6 is
already preferred</strong> --- not during the initial dual-stack rollout, when IPv4 is
still the expected path. IPv4 fallback is silent by default: Happy Eyeballs
<xref target="name-resolution"></xref> and most clients succeed on IPv4 when IPv6 is slow or
broken, so a deploy can undo IPv6 preference without paging anyone. Prefer
<strong>observability split by address family</strong> (see <xref target="observability"></xref>) and correct
client Happy Eyeballs behavior first.</t>
<t>Two related uses:</t>

<ul spacing="compact">
<li><strong>Culture and training (humans):</strong> on dual-stack <strong>jump hosts</strong> and similar
admin paths, make IPv4 sessions <strong>obvious</strong> (for example a login banner ---
see <xref target="ipv6-only-jump-hosts"></xref>) so SREs and SWEs internalize that <strong>IPv6 is now
preferred</strong> before the first sev-1 forces the lesson.</li>
<li><strong>Silent regression (machines):</strong> on inter-application RPC and HTTP paths,
operators <bcp14>MAY</bcp14> apply a <strong>modest delay or traffic shaping</strong> to IPv4 --- for
example a few milliseconds via host or fabric QoS, or Linux <tt>tc</tt> delay on
IPv4 classifiers --- so unintended IPv4 preference shows up as <strong>higher
latency or lower QPS</strong>, metrics most SRE teams already watch. That is a
<strong>soft failure</strong> while the estate is still dual-stack; after <strong>IPv6-only</strong>,
the same breakage becomes a <strong>hard failure</strong>.</li>
</ul>
<t><strong>Hard blocks</strong> on IPv4 remain a last resort while production still needs IPv4
for emergencies. Treat intentional path degradation with care: it can interact
poorly with client Happy Eyeballs implementations and feels like an eternity
under incident pressure. On break-glass admin paths, prefer a <strong>visible
signal</strong> (banner, metric regression) over multi-second delays.</t>
<t>The penalty <bcp14>MUST</bcp14> remain small enough that break-glass and degraded
operation still succeed. Detection, not outage. This operator-applied path
delay is distinct from the Happy Eyeballs <strong>IPv4 connection-attempt delay</strong> in
<xref target="name-resolution"></xref>, which races families at the client rather than making IPv4
worse on the wire.</t>
</section>
</section>

<section anchor="part-ii-building-the-ipv6-data-center"><name>Part II: Building the IPv6 Data Center</name>

<section anchor="internet-addressing"><name>Internet and Data Center Addressing</name>
<t>Network teams assign prefixes; SREs consume them in orchestration templates,
container runtimes, and firewall tickets. This section covers patterns that
reduce outages during rollout.</t>
</section>

<section anchor="prefix-length-and-the-64-convention"><name>Prefix Length and the /64 Convention</name>
<t>On most LANs and data center segments, the <strong>network/host split is at the
64th bit</strong> --- a <tt>/64</tt> prefix on the wire <xref target="RFC4291"></xref>. Roughly speaking, a
<tt>/64</tt> is the IPv6 analogue of an IPv4 <tt>/24</tt> in terms of &quot;one subnet per
broadcast domain,&quot; though the address space is vastly larger.</t>
<t>Operators <bcp14>SHOULD</bcp14> document their own numbering policy and
growth plan (see <xref target="prefix-allocation"></xref>).
Based on hardware or infrastructure provider capabilities,
this can manifest in different data center templates.</t>
<t>For example, such a template may assign a <strong><tt>/56</tt> per host</strong> so each container can receive
its own <strong><tt>/64</tt></strong>, highlighting the <tt>/64</tt> per virtual link on the host.
Another variant, assigning a <strong><tt>/64</tt> per VLAN/link between hosts</strong> so each host can receive
a fraction of it, e.g., a <tt>/80</tt> sill leaving addressing space for further subnet division on a per container basis.</t>

<section anchor="prefix-allocation"><name>Prefix Allocation for Hosts and Containers</name>
<t>The important software lesson is an <strong>explicit prefix plan per role</strong>, sized for
growth --- what receives a prefix (host, VM, container, pod, service, rack, or
other role), at what length, and how those roles nest --- rather than assuming
&quot;one address per host&quot; as in legacy IPv4 NAT designs. Operators <bcp14>SHOULD</bcp14> write
that numbering policy down, then <strong>size for current inventory and plausible 10+ years
growth</strong> (hosts, clusters, and sites). Request the next allocation <strong>before</strong>
the last usable prefix is assigned; discovering a ceiling mid-migration turns a
sizing choice into an allocation request with its own justification and lead
time (the same early-case discipline as <xref target="hybrid-cloud"></xref>). The exact mapping
depends on orchestrator and CNI design; the templates below are examples, not a
single mandatory layout.</t>
<t>One <strong>template</strong> for counting <tt>/64</tt>s --- not a recommendation every estate must
follow --- assigns a <strong><tt>/56</tt> to each physical host</strong> (or rack entity), providing
<strong>256 <tt>/64</tt> subnets</strong> --- one <tt>/64</tt> for the host itself and up to <strong>255 <tt>/64</tt>
prefixes</strong> for containers, virtual machines, or pods. Under that template each
container <bcp14>MAY</bcp14> receive a full <strong><tt>/64</tt></strong>, with routing between <tt>/64</tt> islands
instead of NAT for east-west traffic. Arithmetic follows the policy: a <tt>/56</tt> per
host exhausts a <tt>/48</tt> at <strong>256 hosts</strong>; larger estates need a shorter site prefix
or a different per-entity size. Assigning only a <strong><tt>/64</tt> per host</strong> without
further delegation is <strong>often insufficient</strong> when containers need SLAAC for address assignment.</t>
<t>Orchestrators such as <strong>Kubernetes</strong> often need <strong>several ranges</strong> (for example
node, pod, and service). Whether this can be combined with a single per-host delegation
depends on the orchestrators and its CNI.
Common layouts either gives each node a <tt>/64</tt> from a pod range or
carve out longer-than-<tt>/64</tt> subnets from one host prefix.</t>
<t>In a <strong>closed data center</strong>
with explicit routing and no SLAAC on container segments, some designs assign one
<strong><tt>/64</tt> (or longer) per physical host</strong> and carve <strong><tt>/72</tt> (or longer) subnets</strong> from that host
prefix for containers. That <tt>/72</tt> pattern is <strong>not</strong> suitable hosts expect standard <tt>/64</tt> semantics;
use it only with operator-wide agreement and tested CNI or orchestrator support --- do not read it
as advising against ordinary orchestrator node <tt>/64</tt>s.</t>
<t>These patterns assume an <strong>operator-controlled</strong> data center fabric where the
network team can delegate prefixes freely. In <strong>hybrid</strong> environments that
connect on-premise fabric to public cloud (see <xref target="hybrid-cloud"></xref>), operators
<bcp14>MAY</bcp14> choose different prefix plans so numbering stays consistent across
sites. Cloud providers impose subnet sizes, delegation limits, and aggregation
rules that cannot be changed from the data center alone; mirroring (or mapping
cleanly to) those conventions on bare metal <bcp14>MAY</bcp14> simplify IPAM, ACLs, and
runbooks even when a <tt>/56</tt>-per-host template would otherwise be preferred
locally. The right trade-off depends on connectivity model, orchestrator, and
how much of the estate shares addressing with cloud virtual networks. This
document does not enumerate cloud or IaaS offerings; it focuses on networks
the operator controls directly.</t>
<t>Kubernetes clusters often use eBPF-based service NAT on the node. Traditional
Linux tools (<tt>ss</tt>, <tt>/proc/net/tcp</tt>) may show node-level sockets, not pod-level
flows, when NAT is involved. IPv6 routing reduces NAT use --- which also
<strong>reduces the complexity inherent in NAT when tracing connections</strong> --- but
<strong>does not remove the need for observability hooks</strong> at the CNI layer.</t>
</section>
</section>

<section anchor="link-local-gateways"><name>Link-Local Gateways</name>
<t>A good practice is to place the default gateway at <strong><tt>fe80::1</tt></strong> on each
link. That choice avoids consuming a global address for the router and matches
common vendor examples. Servers <bcp14>MUST</bcp14> specify the outgoing interface when
using link-local next hops (for example, <tt>ip -6 route add default via fe80::1
dev eth0</tt>). The router platform <bcp14>MUST</bcp14> actually configure <tt>fe80::1</tt> on the
expected interface.</t>

<section anchor="static-addressing-router-advertisements-and-ipam"><name>Static Addressing, Router Advertisements, and IPAM</name>
<t>Enterprise data centers usually prefer <strong>static addresses</strong> from an IP Address
Management (IPAM) system over SLAAC-derived random interface identifiers.
Disable <strong>Router Advertisements (RA)</strong> on server-facing <strong>switch ports</strong> (for
example by clearing the <strong>Managed</strong> and <strong>Other</strong> flags) <strong>and</strong> disable
<strong>SLAAC</strong> on <strong>servers and other endpoints</strong> when static addressing is required.
Applying both controls --- at the <strong>network edge and on the host</strong> --- provides
<strong>two layers of protection</strong> so hosts do not acquire unexpected addresses
alongside provisioned ones. That double safeguard also limits surprise growth
in the number of addresses the fabric and security devices must track (see
<xref target="address-types"></xref> on multiple addresses per host).</t>
<t>Gateway at <strong><tt>fe80::1</tt></strong>, global addresses from IPAM, and DNS names registered
in forward and reverse zones should be one coordinated change set.</t>
</section>

<section anchor="semantic-prefixes"><name>Semantic Prefixes for Internal Traffic</name>
<t>On IPv4, operators quickly tell <strong>internal from Internet</strong> traffic: RFC 1918
space such as <tt>10.0.0.0/8</tt> and <tt>192.168.0.0/16</tt> signals &quot;inside the
organization&quot; in logs, captures, and mental models <xref target="RFC1918"></xref>. On IPv6, most
data center addresses are <strong>global unicast</strong> --- there is no automatic &quot;private
vs public&quot; heuristic. Debugging and ACL writing become harder unless the site
<strong>designates a small set of well-known aggregates</strong> in IPAM and teaches SREs to
use them.</t>
<t>A practical pattern is to carve <strong>one prefix for each operational class</strong>, for
example:</t>

<ul spacing="compact">
<li><strong>Everything in the data center</strong> --- one aggregated prefix (the exact length
depends on fleet size; a <tt>/26</tt> under the site GUA is an example when the
block is purely semantic and routing summarizes wider internally)</li>
<li><strong>Everything employees</strong> --- corporate VPN, office wired/wireless for staff</li>
<li><strong>Everything guest Wi-Fi</strong> --- captive portal and untrusted clients</li>
</ul>
<t>Where operators must read or type addresses by hand, aligning those class
boundaries on a <strong>nibble boundary</strong> (a multiple of four bits) keeps the hex
form easier to scan than an arbitrary bit split.</t>
<t>SREs then remember <strong>three networks</strong>, not hundreds of <tt>/64</tt>s, when filtering
pcaps, writing runbooks, or explaining an incident. Document these prefixes in
the same place as <xref target="prefix-allocation"></xref> and <xref target="acl-propagation"></xref> rules so logs,
firewall objects, and monitoring use consistent names (<tt>dc-internal</tt>,
<tt>corp-employee</tt>, <tt>guest-wifi</tt>).</t>
<t><strong>Internal data center prefixes SHOULD NOT be announced or routed to the
Internet.</strong> When addresses are global unicast, <strong>routing policy</strong>
at the edge <bcp14>SHOULD</bcp14> filter site-internal aggregates so they remain reachable
only inside the operator network. Operators <bcp14>MAY</bcp14> suppress these GUA prefixes
from BGP advertisements if permitted by the relevant RIR and if such exclusion
does not cause unnecessary prefix de-aggregation. That routing boundary adds
<strong>defense in depth</strong> on top of firewalls: a misconfigured ACL or leaked route
is less likely to expose internal infrastructure to the public Internet.</t>
<t>Monitoring, security analytics, and log UIs <bcp14>SHOULD</bcp14> let operators <strong>assign
visible colors or tags to semantic prefix ranges</strong> --- for example, external
(Internet-facing) addresses in one color, data center internal prefixes in
another, and corporate or employee VPN ranges in a third. The exact palette is
operator choice; the goal is instant recognition in dashboards, alerts, and
pcap summaries without parsing every <tt>/64</tt>.</t>
</section>
</section>

<section anchor="internet-egress"><name>Internet Egress and Edge Gateways</name>
<t>On IPv4 it is often convenient to give a data center host Internet access via
<strong>NAT44</strong> (or operator CGNAT) on a central device. That pattern <strong>SHOULD NOT
be copied onto IPv6 hosts</strong> --- do not deploy ad hoc <strong>NAT66</strong> or per-server
masquerading so internal servers &quot;hide&quot; behind random IPv6 ports. Internal
hosts <bcp14>SHOULD</bcp14> reach the Internet through a <strong>gateway at the edge</strong> (border
router, firewall, or dedicated translation cluster) with explicit policy and
logging.</t>
<t>That edge model still helps when an <strong>IPv6-only server</strong> must reach an
<strong>IPv4-only Internet service</strong>: the server sends IPv6 to the edge; the gateway
performs <strong>NAT64</strong> or protocol translation <xref target="RFC6146"></xref> (and DNS64 where
needed) on the way out. Translation is <strong>centralized, observable, and
rate-limited</strong> --- not duplicated on every app host.</t>
</section>

<section anchor="internal-external"><name>Internal vs External: Where IPv6-Only Applies</name>
<t>A practical <strong>IPv6-only data center</strong> usually means <strong>IPv6-only on internal
interfaces and east-west paths</strong>, not on every interface facing the outside
world. The <strong>Internet is not yet ready for an IPv6-only-only edge</strong>: clients,
transit, partners, and operator tooling still expect <strong>dual-stack</strong> (or IPv4
fallback) on <strong>external</strong> interfaces --- load balancers, border routers, VPN
concentrators, and customer-facing anycast fronts.</t>
<t>This document uses &quot;IPv6-only,&quot; &quot;dual-stack,&quot; and related terms informally for
deployment context. For precise, testable definitions of the connectivity
scenarios --- <strong>IPv4-only</strong>, <strong>dual-stack</strong>, <strong>IPv6-only with NAT64</strong>, and
<strong>IPv6-only-strict</strong> (no IPv4 connectivity, encapsulated or translated) ---
see <xref target="I-D.ietf-v6ops-ipv6-app-testing"></xref> and the terminology in
<xref target="I-D.ietf-v6ops-ipv6-only"></xref>. Aligning verification with those scenarios keeps
this deployment guidance consistent with application-side IPv6 testing.</t>
<t>Plan accordingly:</t>

<ul spacing="compact">
<li><strong>Inside the data center:</strong> servers, containers, and service-to-service traffic
<bcp14>SHOULD</bcp14> move to <strong>IPv6-only</strong> (or IPv6-primary) on internal VLANs and
<tt>/64</tt> islands as readiness allows.</li>
<li><strong>At the edge:</strong> <strong>external interfaces SHOULD remain dual-stack</strong> until IPv4
dependency is gone for your user base and upstream paths. The edge gateway
performs translation when an internal IPv6-only host must reach IPv4-only
destinations (see above).</li>
</ul>
<t><strong>Dual-home servers on the edge</strong> --- one <strong>internal</strong> interface (IPv6-only or
IPv6-primary) and one <strong>external</strong> interface (dual-stack) --- simplify
<strong>administration and break-glass access</strong>: operators and automation can reach
management paths on the internal v6 network while the service still serves
dual-stack Internet clients. Document which interface is which in IPAM and
host naming; do not collapse &quot;internal v6-only&quot; and &quot;external dual-stack&quot; into
a single ambiguous address on production boxes. During migration, the internal
interface may remain <strong>IPv4-only</strong> for a time; see
<xref target="dual-homed-transitional-routing"></xref> for routing and DNS pitfalls on those hosts.</t>

<section anchor="dual-homed-transitional-routing"><name>Dual-Homed Hosts During Internal IPv6 Rollout</name>
<t>Edge servers often have <strong>two interfaces</strong>: an <strong>external</strong> interface toward the
Internet (dual-stack, <strong>default route</strong>) and an <strong>internal</strong> interface toward the
data center (today <strong>IPv4-only</strong>, with <strong>more-specific routes</strong> for internal
prefixes). That layout is common during brownfield migration before the internal
VLAN gains IPv6 on every host.</t>
<t>When internal services begin publishing <strong>AAAA</strong> records, a dual-homed host that
still has <strong>no IPv6 on the internal interface</strong> may resolve both A and AAAA for
an internal name but send IPv6 connection attempts out the <strong>default route</strong> on
the external interface. Those packets never reach the internal service. Symptoms
include <strong>long timeouts</strong> on dual-stack clients, flaky automation, and &quot;internal
DNS works from other hosts but not from the edge box.&quot;</t>
<t>Operators <bcp14>SHOULD</bcp14> align <strong>routing policy with DNS</strong>, not assume AAAA implies
a working IPv6 path from every interface:</t>

<ul spacing="compact">
<li><strong>Preferred long-term:</strong> enable IPv6 on the internal interface and install
<strong>scoped routes</strong> (or policy routing) so internal GUA prefixes egress the
internal interface (see <xref target="semantic-prefixes"></xref>).</li>
<li><strong>Transitional mitigation:</strong> while the internal NIC remains IPv4-only, install
an <strong><tt>unreachable</tt></strong> route for the site <strong>internal IPv6 aggregate</strong> on the host
(for example, the <tt>dc-internal</tt> prefix from <xref target="semantic-prefixes"></xref>). The kernel
then rejects connection attempts to internal AAAA addresses <strong>immediately</strong>
with a local &quot;no route to host&quot; error instead of forwarding them via the
Internet default route. Clients that iterate all resolved addresses --- or use
Happy Eyeballs <xref target="RFC8305"></xref> --- can fall back to the <strong>A</strong> record over the
internal IPv4 path (see <xref target="name-resolution"></xref>). Do <strong>not</strong> use a <strong><tt>blackhole</tt></strong>
route for this purpose: blackhole <strong>silently discards</strong> packets and recreates
the same <strong>timeout</strong> behavior the operator is trying to avoid.</li>
<li><strong>Border visibility:</strong> operators <bcp14>MAY</bcp14> also monitor or log at Internet or
site border devices any packets destined to <strong>internal-only</strong> IPv6 aggregates
that should never appear on external policy paths --- a useful signal of
mis-egress during rollout. Blocking those flows at the border can help, but
treat hard denies carefully in multihomed designs.</li>
<li><strong>Alternative:</strong> <strong>split-horizon DNS</strong> so resolvers used on edge hosts do not
return AAAA for names that are reachable only on the internal IPv4 path until
routing is fixed.</li>
</ul>
<t>This pattern is <strong>not</strong> a substitute for enabling IPv6 on internal interfaces;
it prevents <strong>misrouted IPv6</strong> during rollout. Application code that stops after
the first address (<tt>gethostbyname()</tt>, <tt>InetAddress.getByName()</tt>, and similar)
<strong>will not benefit</strong> --- fix routing <strong>and</strong> resolution behavior together.</t>
<t>Example (Linux, illustrative prefix):</t>

<artwork><![CDATA[ip -6 route add unreachable 2001:db8:dc::/48
]]></artwork>
<t>Express the same policy in configuration management on every dual-homed edge
role during the transition; remove the unreachable route when the internal
interface is dual-stack and correct scoped routes are in place.</t>
</section>
</section>

<section anchor="ipv4-only-wrappers"><name>Frontends for IPv4-Only Services</name>
<t>Legacy applications that remain <strong>IPv4-only</strong> <bcp14>SHOULD NOT</bcp14> be exposed
directly to dual-stack or IPv6-only clients. Surround them with a <strong>gateway
tier</strong> --- for example <strong>nginx</strong>, <strong>HAProxy</strong>, or a service-mesh ingress ---
that accepts <strong>IPv6 (and IPv4 if required)</strong> on the front side and speaks IPv4
only to the backend. Clients see a normal v6-capable service name; the
IPv4-only binary stays on an internal path until it is rewritten or replaced
(see <xref target="provision-not-transform"></xref>).</t>
<t>In dual-stack deployments where session persistence is required, SREs <bcp14>MUST</bcp14>
verify that the gateway tier preserves session continuity across both IPv4 and
IPv6. Implementations that maintain separate persistence state for each address
family may experience session loss when clients alternate between IPv4 and IPv6.</t>
<t>An alternative on the host is <strong>NAT64 implemented with eBPF</strong> (similar in spirit
to Kubernetes node NAT). That can unblock a single service quickly but <strong>often
does not scale</strong> as a fleet-wide strategy --- connection state, troubleshooting,
and upgrade churn multiply with every host doing translation. Prefer a <strong>small
number of shared frontends or edge translators</strong> over per-host NAT64 except in
controlled exceptions. See also <xref target="icmpv6-pmtud"></xref> for VPN and middlebox
interactions with translated traffic.</t>
</section>

<section anchor="acl-propagation"><name>Access Control List Propagation</name>
<t>When IPv6 is added to a service that already runs on IPv4, <strong>firewall and ACL
automation may lag by minutes</strong>. During that window the service can appear
<strong>healthy on IPv4 but broken on IPv6</strong>, or reachable in one direction only.
SRE runbooks <bcp14>SHOULD</bcp14> treat &quot;IPv6 enabled on the host&quot; and &quot;IPv6 permitted
end-to-end&quot; as separate checklist items. Do not announce IPv6 on a load
balancer until policy propagation completes. Application-level IP allow and
deny lists are a related deployment risk: enabling IPv6 can shift clients onto
addresses missing from the list, causing service disruption;
<xref target="I-D.ietf-v6ops-ipv6-app-testing"></xref> discusses testing for this before rollout.</t>
<t>Software teams <bcp14>SHOULD NOT</bcp14> create entirely new ACL models per address family
when the same role-based policy can express both; parallel rule sets double
drift risk. Where separate rules are unavoidable, generate them from the same
source of truth.</t>

<section anchor="ipam-based-ipv4-to-ipv6-mapping-for-acls"><name>IPAM-Based IPv4-to-IPv6 Mapping for ACLs</name>
<t>When IPAM tracks both address families, operators can <strong>derive a predictable
IPv6 address from a hostname</strong> before an AAAA record exists in DNS. That
mapping lets ACL and firewall systems publish <strong>IPv6 rules in advance</strong>, so
policy is already in place when the service starts listening on IPv6 --- there
is no window where the host is up on IPv6 but ACL automation is still catching
up.</t>
<t>This pattern <strong>requires ACL policy to be expressed by hostname (or role)</strong>, not
by scattered literal addresses maintained separately per family. Given a hostname,
a controller can resolve or derive addresses with the following <strong>pseudo-rules</strong>:</t>

<ol spacing="compact">
<li>Look up the <strong>AAAA</strong> record. If present, use that IPv6 address.</li>
<li>If no AAAA exists, look up the <strong>A</strong> record and obtain the IPv4 address.</li>
<li>In IPAM, find the <strong>IPv4 network</strong> that contains that address.</li>
<li>Find the <strong>associated IPv6 network</strong> paired with that IPv4 network in IPAM.</li>
<li><strong>Embed the IPv4 address</strong> into the IPv6 network according to the site's
translation plan (for example, a fixed nibble layout or well-known offset).
The result is the <strong>predicted IPv6 address</strong> for that hostname.</li>
</ol>
<t>The benefit is operational: <strong>ACLs for IPv6 can be built and deployed everywhere
before DNS advertises AAAA</strong>, because the IPv6 address is computable from the
same hostname and IPAM data already used for IPv4. When the service later
enables IPv6 and the AAAA is published, the pre-provisioned rules should match
without a second ACL rollout. The site translation plan in step 5 <bcp14>MUST</bcp14> be
documented and stable; ad hoc embedding layouts defeat this approach.</t>
<t>Operators <bcp14>SHOULD</bcp14> detect <strong>drift</strong> when DNS or IPAM changes: for example,
compare published A/AAAA records to the address predicted by the embedding
plan, and alert when they diverge so pre-built ACLs are not left pointing at
the wrong host.</t>
<t>The same correlation policy supports an <strong>early dual-stack step on the host</strong>
without advertising <strong>AAAA</strong> in DNS. IPAM assigns the predicted IPv6 address on
the interface; the application tier can remain <strong>IPv4-only</strong> (A record only,
IPv4 listen sockets) while <strong>outbound</strong> traffic from the host uses IPv6. That
lets platform agents --- configuration management, monitoring, log shippers,
vulnerability scanners, and other infrastructure daemons (see <xref target="host-agents"></xref>)
--- reach <strong>IPv6-only</strong> services on the fabric before application code is
ready. Inbound clients still use IPv4 until a deliberate cutover adds AAAA and
dual-stack or IPv6-only listeners; pre-provision ACLs and routing for the
predicted v6 address using the steps above.</t>
<t>If ACL systems cannot accept hostnames and expand them through this logic,
teams fall back to the lag problem described above --- IPv6 goes live while
firewall tickets are still in flight.</t>
</section>
</section>

<section anchor="progress-metrics"><name>Progress Metrics</name>
<t>Dashboards <bcp14>SHOULD</bcp14> expose fleet-level indicators, for example:</t>

<ul spacing="compact">
<li>Percentage of services <strong>IPv6-only</strong>, <strong>dual-stack</strong>, or <strong>IPv4-only</strong> (by
count and by criticality tier)</li>
<li>Trend of <strong>AAAA vs A-only</strong> DNS names for production hostnames</li>
<li>Ratio of <strong>ingress bytes or connections</strong> over IPv6 vs IPv4 at load balancers</li>
<li>Where NAT64 or similar translation is in use, a <strong>third traffic class</strong> ---
pure IPv6, pure IPv4, and <strong>transitional</strong> (IPv6 inside the site, IPv4
outside via translation) --- so operators can see when it is safe to remove
translators from a segment</li>
<li>Where available, <strong>TCP/TLS/QUIC connection-establishment</strong> counters split by address
family --- for example SYN or connection attempts versus successfully
established sessions, handshake timeouts, and SYN retransmissions --- so
path or middlebox problems that drop or stall IPv6 handshakes are not hidden
by byte or connection totals that still look healthy</li>
<li>Count of hosts or pods <strong>without any IPv6 address</strong> in IPAM or configuration
management</li>
<li><strong>Latency and QPS split by address family</strong>, or unexplained regressions
correlated with rising IPv4 share (see <xref target="ipv4-friction"></xref>)</li>
</ul>
<t>Set explicit targets (for example, &quot;90% of tier-1 APIs dual-stack by Q4&quot;) and
review the same metrics in change advisory boards.</t>

<section anchor="dual-stack-regression-and-hard-failures-on-ipv6"><name>Dual-Stack Regression and Hard Failures on IPv6</name>
<t>Dual-stack is a valuable migration step, but <strong>without monitoring it invites
regression</strong>. A service that passed dual-stack testing can <strong>stop working on IPv6</strong>
after an unrelated code push --- for example, a new dependency, a changed bind
address, or a refactored HTTP client that silently prefers IPv4. Unmonitored
dual-stack fleets often <strong>mask</strong> such regressions because IPv4 still succeeds.
Where operators apply modest IPv4 path friction <xref target="ipv4-friction"></xref>, a sudden
preference for IPv4 often appears first as <strong>increased latency or reduced
QPS</strong> on services that already export those metrics --- treat those
regressions as IPv6-preference failures, not generic capacity events, until
address-family split confirms otherwise.</t>
<t><strong>Treat IPv6 failures as hard failures as soon as policy allows</strong> --- alert on
IPv6-only health checks, IPv6 listen-socket regressions, and rising IPv4-only
connection share for tier-1 services. Where production remains dual-stack,
synthetic probes <bcp14>SHOULD</bcp14> exercise <strong>IPv6 explicitly</strong> (AAAA-only paths,
IPv6 literal targets, or IPv6-only test clients), not only dual-stack clients
that can hide breakage. When probing a load balancer or VIP <strong>by address</strong> to
separate DNS or address-selection failures from the data path, HTTP and TLS
checks <bcp14>SHOULD</bcp14> still present the production <strong>hostname</strong> (TLS SNI and HTTP
<tt>Host</tt>) so the probe exercises the same certificate and virtual-host path as
real clients; a bare IP literal may pass TCP while missing application-layer
faults. <xref target="I-D.ietf-v6ops-ipv6-app-testing"></xref> describes
client-, server-, and network-based tracing strategies that distinguish
genuine IPv6-only-strict behavior from dual-stack masking. The sooner IPv6 errors page on-call the same way IPv4
errors do, the less likely a team discovers IPv6 rot months later during an
IPv4 decommissioning drill.</t>
<t>Approved <strong>IPv4-only exceptions</strong> (see <xref target="ipv4-only-exceptions"></xref>) are the controlled
counterpart to this policy: hard failure is the default; a documented waiver
with remediation timeline is the escape hatch, not silent dual-stack masking.</t>
</section>

<section anchor="host-level-listen-socket-audit"><name>Host-Level Listen-Socket Audit</name>
<t>On each host, collect which services <strong>listen on IPv4-only</strong>, <strong>IPv6-only</strong>, or
<strong>dual-stack</strong>. On Linux, <tt>ss -tulnp</tt> (or <tt>/proc/net/tcp</tt> and <tt>tcp6</tt>) is the
usual source, but classification is <strong>non-trivial</strong>:</t>

<ul spacing="compact">
<li>Separate <tt>tcp</tt>/<tt>udp</tt> vs <tt>tcp6</tt>/<tt>udp6</tt> lines are often <strong>IPv4-only</strong> vs
<strong>IPv6-only</strong> listeners.</li>
<li>A single IPv6 socket with <tt>IPV6_V6ONLY=0</tt> may accept IPv4-mapped traffic
without a matching <tt>tcp</tt> line --- treat as <strong>dual-stack</strong> only after checking
socket options or process documentation.</li>
<li>Match rows by <strong>PID, port, and inode</strong> when correlating multiple lines for one
daemon; export a normalized label (<tt>v4-only</tt>, <tt>v6-only</tt>, <tt>dual-stack</tt>,
<tt>unknown</tt>) for metrics.</li>
</ul>
<t>Run this audit on a schedule and on every deploy; alert when a tier-1 service
regresses to IPv4-only.</t>
</section>

<section anchor="host-agents"><name>Host Agents Before Application Provisioning</name>
<t>Before any application software is installed, <strong>inventory every agent and
daemon already running on the host</strong> --- configuration management, monitoring,
log shippers, vulnerability scanners, <strong>EDR</strong>, host firewalls, and other
platform packages the fleet image includes by default. These components often
<strong>bind IPv4-only</strong>, ship IPv4-only policy from a central console, or break when
the host loses IPv4 even if the workload you plan to deploy is IPv6-ready.</t>
<t>Run this baseline check on <strong>golden images and freshly provisioned servers</strong>, not
only on production services. A host cannot safely move to dual-stack or
IPv6-only if an unknown agent still requires <strong>IPv4 loopback for listening</strong>
(that is, it binds only on <tt>127.0.0.1</tt> while IPv6-only local clients must
connect), RFC 1918 reachability, or IPv4-only reporting to its controller.
<strong>IPv4 loopback on <tt>lo</tt> itself</strong> --- including clients that dial <tt>127.0.0.1</tt> ---
is expected to remain on many platforms (for example Linux, where IPv4 cannot be
disabled in the kernel) and is not the same as routable IPv4 on application
interfaces. Export agent name, version, listen
sockets (see above), and <strong>IPv6 readiness</strong> into the same catalog as
<xref target="application-readiness"></xref>. Re-run when the image or security baseline changes.</t>
</section>

<section anchor="traffic-by-protocol-and-address-family"><name>Traffic by Protocol and Address Family</name>
<t>Switches and routers expose <strong>IPv4 and IPv6 packet counters</strong> but often <strong>do
not break out TCP and UDP by IP version</strong> (TCPv4 vs TCPv6, UDPv4 vs UDPv6).
Where the platform allows, collect <strong><tt>tcp4</tt>/<tt>udp4</tt> vs <tt>tcp6</tt>/<tt>udp6</tt></strong> (or
equivalent flow records) on hosts, hypervisors, and top-of-rack devices.
Application SREs need <strong>L4 metrics split by address family</strong> to confirm traffic
is migrating and to find stragglers still on IPv4-only or translated paths.</t>
<t>Log pipelines <bcp14>SHOULD</bcp14> record address family explicitly (<tt>AF_INET</tt> vs
<tt>AF_INET6</tt>) rather than inferring from string shape.</t>
</section>

<section anchor="http-signaling-and-planned-ipv4-drills"><name>HTTP Signaling and Planned IPv4 Drills</name>
<t>For HTTP services, implementing <eref target="https://datatracker.ietf.org/doc/draft-martin-retry-over-ipv6/">HTTP Signaling of Planned IPv4
Unavailability</eref>
(<tt>566</tt> responses, <tt>Retry-Over-IPv6</tt>, and related headers) gives <strong>measurable
signals</strong> during planned IPv4 outages: count <tt>566</tt> responses, soft vs hard
failures after IPv6 retry, and clients still hitting IPv4. That data belongs on
the same dashboards as listen-socket and byte-ratio metrics when rolling out
dual-stack or IPv6-only frontends.</t>
</section>

<section anchor="live-traffic-and-service-call-trees"><name>Live Traffic and Service Call Trees</name>
<t>Inventory and socket audits show <strong>what could</strong> run on IPv6; live traffic shows
<strong>what does</strong>. Instrument outbound and inbound connections (service mesh,
eBPF, proxy access logs, or APM) to tag each hop with <strong>address family</strong>.
Roll those tags into a <strong>call tree or dependency graph per service</strong> so teams
see, for example, &quot;API gateway is dual-stack but 80% of backend calls still use
IPv4&quot; or &quot;this batch job is IPv4-only despite an IPv6-ready binary.&quot;</t>
<t>Use call-tree family breakdown to prioritize refactors: fix the highest-volume
IPv4-only edges first. Where translation is present, tag hops as <strong>native
IPv6</strong>, <strong>native IPv4</strong>, or <strong>transitional</strong> so dashboards show when NAT64 can
be retired from a path. Reconcile call-tree findings with the inventory --- a
service marked &quot;IPv6 ready&quot; with no IPv6 traffic is not done.
<xref target="I-D.ietf-v6ops-ipv6-app-testing"></xref> describes decomposing complex, multi-service
cloud applications into per-flow test cases, matching this per-hop view.</t>
</section>
</section>
</section>

<section anchor="part-iii-tools-best-practices"><name>Part III: Tools &amp; Best Practices</name>

<section anchor="dev-environments"><name>Developer and Pre-Production Environments</name>
<t><strong>Provide dual-stack (and eventually IPv6-only) networks to developers as early
as possible</strong> --- ideally before production rollout, not after. Engineers who
code and debug only on IPv4-only laptops or lab VLANs ship software that
&quot;works in the office&quot; and fails when AAAA records appear in production.</t>
<t>It is customary to <strong>build and test new code in VMs or containers</strong> that mirror
production topology before release. Those evaluation environments <bcp14>MUST</bcp14>
include <strong>dual-stack</strong> and <strong>IPv6-only</strong> variants alongside legacy IPv4-only
images where brownfield support is still required. CI pipelines <bcp14>SHOULD</bcp14> run
integration tests against both address-family modes so a code push cannot
silently regress IPv6 without failing the build.
<xref target="I-D.ietf-v6ops-ipv6-app-testing"></xref> defines the connectivity-scenario
combinations and testing strategies these pipelines <bcp14>SHOULD</bcp14> cover, including
IPv6-only-strict and IPv6-only with NAT64.</t>
<t>Platform teams <bcp14>SHOULD</bcp14> publish standard developer network profiles (dual-stack
lab, IPv6-only sandbox, simulated edge with NAT64) and document how to attach
local IDEs, test harnesses, and AI coding agents to them.</t>
</section>

<section anchor="ipv6-only-jump-hosts"><name>IPv6-Only Jump Hosts</name>
<t>Moving to IPv6 is not only a routing change --- it requires a <strong>cultural shift</strong>
for SREs and SWEs who have spent years assuming IPv4 literals, RFC 1918 mental
models, and IPv4-first tooling. <strong>Make that shift visible before emergencies:</strong>
IPv6-only jump hosts, IPv6-first runbooks, and labeled lab networks teach the
new defaults while change windows are calm. Engineers under incident pressure
<strong>do not have time to learn IPv6 idioms</strong>; if the first time they need <tt>dig -x</tt>
on an <tt>ip6.arpa</tt> name or SSH over a global v6 management address is during a
sev-1, the organization has already failed the migration program.</t>
<t>A practical staged transition puts <strong>administrative jump hosts</strong> on an
IPv6-first path while leaving application tiers dual-stack temporarily.
&quot;IPv6-only&quot; for that host means two different things --- do not conflate them:</t>

<ul spacing="compact">
<li><strong><tt>sshd</tt> (and similar entry points) listen only on IPv6:</strong> employees and IT
must reach the bastion over IPv6. The <strong>client path</strong> can still be dual-stack
(laptop, VPN, corp Wi-Fi); the point is to force IT to <strong>provide a working
IPv6 environment to staff</strong> so people can get in at all.</li>
<li><strong>No IPv4 address on the jump host:</strong> once operators are on the box, every
management command and every call to <strong>management APIs</strong> (config management,
inventory, monitoring, cloud control planes, and similar) must succeed over
IPv6. That is a stricter proof that the <strong>operations stack</strong> is IPv6-ready,
not only that SSH answered on a AAAA.</li>
</ul>
<t>Engineers run break-glass SSH and day-to-day tooling from those hosts. Maintain
at least one <strong>dual-stack backup jump host</strong> during migration and <strong>audit who
connects and which commands run</strong> until parity is proven.</t>
<t>On that dual-stack backup, operators <bcp14>MAY</bcp14> add <strong>noticeable but non-blocking
IPv4 friction</strong> so a session that landed on IPv4 is obvious without denying
access. Prefer a <strong>login banner</strong> that states the session used IPv4 over
multi-second delays: under incident pressure, even a few seconds of ForcedCommand
countdown can feel like an outage. If a delay is used at all, keep it minimal
and temporary, and consider reducing IPv4 SSH session timeouts instead.
Emergency access still works; the signal is that IPv6 is not functional or not
preferred, so the path can be fixed while the window is calm. IPv6 sessions
<bcp14>SHOULD NOT</bcp14> receive the same penalty. The same idea applies more broadly than
SSH --- see <xref target="ipv4-friction"></xref>.</t>
<t>Corporate and guest <strong>Wi-Fi</strong> are <strong>ops- and lab-adjacent</strong> to the data center
fabric (different device churn and trust model than server VLANs). Treat them as
useful migration exercise networks, not as a substitute for jump-host discipline;
broader enterprise wireless guidance is in <xref target="RFC7381"></xref>. Provide <strong>dual-stack
Wi-Fi</strong> for everyday employee devices during migration, and at least one
<strong>IPv6-only employee Wi-Fi</strong> SSID so laptops, phones, VPN clients, and
captive-portal flows are exercised on AAAA-only paths before production depends
on them. Label SSIDs explicitly (for example, <tt>corp-dualstack</tt> and
<tt>corp-v6-only</tt>) so engineers know which network they joined.</t>
<t>Some operators <bcp14>MAY</bcp14> additionally offer <strong>IPv6-only guest Wi-Fi</strong> --- for
example in lab, conference, or vendor demo areas --- so external teams can
demonstrate that hardware and software work without IPv4 fallback during
evaluations and acceptance testing. That network <bcp14>SHOULD</bcp14> be clearly marked,
rate-limited, and isolated from internal management zones; it complements jump
hosts but does not replace them for break-glass administration.</t>
</section>

<section anchor="network-diagnostics"><name>Network Diagnostics in the Data Center</name>
<t>A data center is a <strong>closed, operator-controlled environment</strong>. Two practices
that help SREs diagnose routing, DNS, and reachability problems on <strong>both IPv4
and IPv6</strong> are often skipped because they feel optional or risky.</t>

<section anchor="reverse-dns"><name>Reverse DNS</name>
<t>Maintain <strong>forward and reverse DNS</strong> for long-lived infrastructure: servers,
load balancers, management interfaces, and other addresses that appear in logs,
firewall hits, flow records, and packet captures. Reverse zones (<strong>PTR</strong> for
IPv4, <strong>ip6.arpa</strong> for IPv6 <xref target="RFC3596"></xref>) map an address back to a hostname.
That mapping is routine on IPv4 but becomes <strong>essential on IPv6</strong>, where
prefixes are not human-scannable and incidents otherwise devolve into comparing
128-bit literals. Reverse records <bcp14>SHOULD</bcp14> be created in the same change
workflow as forward records and IPAM assignments (see <xref target="dns-registration"></xref>).
Spot-check with <tt>dig -x</tt> or equivalent on both address families before relying
on reverse lookup during an outage.</t>
</section>

<section anchor="controlled-icmp-echo-ping"><name>Controlled ICMP Echo (Ping)</name>
<t>Teams trained to drop <strong>ICMP echo request/reply</strong> (&quot;ping&quot;) on the public Internet
sometimes apply the same rule everywhere. <strong>Inside the data center</strong>, allowing
echo request/reply <strong>with limits</strong> --- rate limits, scoped ACLs, source
restrictions to management networks or jump hosts, or equivalent controls --- is
<bcp14>RECOMMENDED</bcp14> for troubleshooting. A <strong>successful</strong> ping confirms basic IP
reachability (when echo is permitted) without opening application ports. A
<strong>failed</strong> ping alone <strong>does not</strong> prove there is no route: filtering, rate
limits, host firewall policy, or a destination that does not answer echo can
produce the same symptom. Combine ping with <tt>traceroute</tt>, <tt>tracepath</tt>, or <tt>mtr</tt>,
TCP connects to a known port, or other checks before concluding &quot;no route&quot;
versus &quot;route but service down.&quot;</t>
<t>This is separate from the ICMPv6 requirements in <xref target="icmpv6-pmtud"></xref>: Neighbor
Discovery and Path MTU Discovery need specific ICMPv6 types on production paths
and <bcp14>MUST NOT</bcp14> be blocked wholesale. Controlled echo is an additional
<strong>diagnostic convenience</strong> on top of that baseline. Operators <bcp14>SHOULD NOT</bcp14>
replace protocol-required ICMP with echo-only rules, nor block echo in ways that
remove a basic reachability tool from on-call engineers. Apply the same
philosophy to <strong>ICMPv4 echo</strong> inside the fabric: constrain abuse, but preserve
a controlled way to test L3 connectivity during incidents.</t>
</section>
</section>

<section anchor="application-readiness"><name>Tracking Application and Software Readiness</name>
<t>IPv6 deployment exposes software that &quot;worked on the LAN&quot; only because the LAN
was IPv4. This section lists classes of problems seen in production data
centers and enterprise rollouts.</t>

<section anchor="enterprise-platform-inventory"><name>Enterprise Platform Inventory</name>
<t>Many enterprise platforms still assume IPv4-only access paths. Examples
reported in operator experience <strong>as of this writing</strong> include <strong>Hadoop</strong>,
certain <strong>object storage APIs</strong>, <strong>Kubernetes</strong> dependencies (especially
third-party charts and sidecars), <strong>cloud firewalls</strong> (for example,
Firewalls and third-party NGFW images on cloud platforms where IPv6 support
lagged vendor roadmaps), and <strong>security analytics</strong> pipelines that ingest
NetFlow or packet metadata on IPv4 only. Re-check product status at
publication and deployment time --- capability claims change. Hybrid and
multi-cloud estates need the same inventory discipline for managed services and
connectivity paths (see <xref target="hybrid-cloud"></xref>).</t>
<t><strong>Action for SRE teams:</strong> maintain a <strong>living inventory</strong> of software in the
deployment path (data plane, control plane, CI/CD, security, logging) with an
explicit <strong>IPv6 supported / broken / untested</strong> classification. Monitoring
pipelines <bcp14>SHOULD</bcp14> continuously <strong>discover services not yet in that inventory</strong>
(see <xref target="observability"></xref>). Security research or monitoring that runs IPv4-only
cannot validate IPv6 attack surface; teams <bcp14>SHOULD</bcp14> require IPv6 parity before
accepting &quot;no IPv6 security issues&quot; claims.</t>
</section>

<section anchor="dependency-and-platform-readiness-gates"><name>Dependency and Platform Readiness Gates</name>
<t>Many SREs and software engineers <strong>will not</strong> study address representation,
<tt>getaddrinfo()</tt> semantics, or Happy Eyeballs in depth --- and should not have
to before every deploy. Platform teams <bcp14>SHOULD</bcp14> publish <strong>monitored readiness
gates</strong>: for each shared dependency (language runtime, HTTP/RPC client, database
driver, messaging library, observability agent, base container image), document
a <strong>minimum version or image tag</strong> <em>and</em> the <strong>required configuration
profile</strong>, both validated on dual-stack and IPv6-only paths.</t>
<t>A version or image threshold is a <strong>prerequisite</strong>, not proof that the
deployed service is IPv6-ready. The same binary can still run IPv4-only
because a feature flag, environment variable, listen address, or
endpoint-selection setting is wrong. Software version and configuration
version <bcp14>MAY</bcp14> be shipped as one bundle or pushed independently --- the
usual case in large data centers using <strong>Puppet</strong>, <strong>Ansible</strong>, or similar.
Operators already monitor which software and configuration versions are
deployed; IPv6 gates <bcp14>SHOULD</bcp14> use those same signals.</t>
<t>Configuration commonly <strong>inherits and overrides</strong> along a hierarchy (for
example organisation, site, maintenance zone, application, host). A ready
package with a leftover override is still not ready. The gate is therefore
often &quot;upgrade to version X&quot; <strong>and/or</strong> &quot;remove the override so the general
value applies&quot; --- for instance dropping a host-level
<tt>java.net.preferIPv4Stack=true</tt> (see <xref target="runtime-resolution"></xref>).</t>
<t>Example gates: <em>upgrade <strong><tt>example-http-client</tt> to 2.4.0 or newer</strong></em>; <em>remove
application or host overrides of <tt>java.net.preferIPv4Stack</tt></em>. Versions or
profiles below the threshold remain <strong>blocked or flagged</strong> in the inventory
until both the package and the <strong>effective</strong> configuration match.</t>
<t><strong>Automate enforcement</strong> against that catalog: compare SBOMs, lockfiles, image
scans, and configuration-management reports (resolved inheritance, not only
the default) to the matrix on a schedule and in CI (see <xref target="observability"></xref>).
Crossing the software-version threshold <bcp14>SHOULD NOT</bcp14> by itself mark a
service ready. When version <strong>and</strong> configuration match the gate and
<strong>end-to-end validation</strong> on dual-stack and IPv6-only paths succeeds ---
dependency bumped, agent replaced, golden image refreshed, override removed
--- <strong>update its readiness label</strong> without requiring every engineer to audit
socket call sites by hand. Put the gates where teams already work (service
catalog, Renovate or equivalent dependency bots, configuration-management
dashboards, deployment checklists) and <bcp14>SHOULD</bcp14> tie change-advisory or
promotion policy to them so <strong>unknown</strong>, <strong>below-minimum</strong>, or
<strong>misconfigured</strong> software cannot reach production dual-stack or IPv6-only
paths unnoticed.</t>
</section>

<section anchor="static-analysis"><name>Static Analysis and Pull Request Automation</name>
<t>Manual review does not scale across large monorepos. <strong>Security and platform
teams SHOULD integrate IPv6 readiness checks into pull request (PR) workflows</strong>,
piggybacking on existing gates rather than relying on a separate audit cycle.</t>
</section>

<section anchor="pattern-scanners-in-ci"><name>Pattern Scanners in CI</name>
<t>Ship <strong>Semgrep</strong>, <strong>CodeQL</strong>, or equivalent rules that flag likely IPv4-only
patterns, for example:</t>

<ul spacing="compact">
<li>Literal <tt>127.0.0.1</tt> or <tt>0.0.0.0</tt> in <strong>listen/bind</strong> configuration (not every
client connect to <tt>127.0.0.1</tt>; see <xref target="localhost-pitfalls"></xref>), or dotted-decimal
regexes used as addresses</li>
<li>Calls to deprecated Python socket helpers (see <xref target="language-runtimes"></xref>)</li>
<li><tt>AF_INET</tt> sockets where dual-stack or <tt>AF_INET6</tt> is required</li>
<li>Database columns or structs sized for IPv4-only (<tt>CHAR(15)</tt>, 32-bit integers)</li>
<li>String splits on <tt>.</tt> to parse &quot;IP addresses&quot;</li>
<li><tt>getaddrinfo()</tt> (and language equivalents) that use only the first returned
address, or that treat DNS response order as load balancing without
within-family selection --- assumptions that ordinary review often misses
(see <xref target="address-selection"></xref> and <xref target="client-load-balancing"></xref>)</li>
</ul>
<t>Security teams often own the rule pack; application teams own remediation.
Rules <bcp14>SHOULD</bcp14> be published internally with examples and fix guidance.</t>
</section>

<section anchor="automated-remediation-pull-requests"><name>Automated Remediation Pull Requests</name>
<t>Beyond blocking merges, pipelines <bcp14>MAY</bcp14> open <strong>automatic PRs</strong> that propose
fixes when a scan finds matches on default branches or on a schedule. Some
findings are straightforward (replace <tt>gethostbyname</tt> with <tt>getaddrinfo</tt> usage);
others need context. <strong>AI-assisted patch generation</strong> can speed up bulk
refactors, but <bcp14>MUST</bcp14> be reviewed by a human --- expect <strong>false positives</strong>
(for example, code that intentionally handles IPv4-only legacy clients).</t>
<t>Treat auto-generated PRs like any other contribution: tests, ownership by code
owners, and rollback plan.</t>
</section>

<section anchor="opt-out-annotations-for-engineers"><name>Opt-Out Annotations for Engineers</name>
<t>Engineers <bcp14>SHOULD</bcp14> be able to <strong>suppress a finding on a specific line</strong> when
the IPv4-only behavior is intentional and documented --- for example, a
compatibility shim with a planned removal date. Define a <strong>codified comment</strong>
recognized by the scanner, placed <strong>immediately before</strong> the flagged line. An
example directive:</t>

<artwork><![CDATA[# ipv6-readiness: ignore-next-line -- see TICKET-123
]]></artwork>
<t>The project <bcp14>MUST</bcp14> document the exact directive string, required rationale
format, and whether ticket references are mandatory. Blanket disables of entire
files <bcp14>SHOULD NOT</bcp14> be allowed without security team approval.</t>
</section>
</section>

<section anchor="ai-coding-agent-skills"><name>AI Coding Agent Skills</name>
<t>Many teams now use <strong>AI coding agents</strong> in the IDE and in CI. Add an <strong>IPv6
readiness skill</strong> (or equivalent project rule) to the agent environment --- and
<strong>push the same skill into application repositories</strong> --- so generated patches
default to <strong>dual-stack APIs</strong>, <strong><tt>getaddrinfo()</tt>-style resolution</strong>, and
IPv6-safe listen/bind patterns. The skill <bcp14>SHOULD</bcp14> require agents to verify
that new network code works when AAAA records are present and when IPv4 is
absent (IPv6-only paths). Treat this as part of the same program as Semgrep
and CodeQL rules, not a substitute for automated tests on dual-stack and
IPv6-only runners (see <xref target="dev-environments"></xref>).</t>
</section>

<section anchor="documentation-examples"><name>Documentation and Presentations</name>
<t>Runbooks, architecture diagrams, wikis, training decks, and conference slides
<strong>SHOULD use IPv6 addresses in examples by default</strong>, unless the example is
inherently IPv4-specific. Using IPv4-only literals in internal documentation
normalizes the wrong protocol for new engineers and hides gaps until production
rollout. IETF documents follow the same principle: examples <bcp14>SHOULD</bcp14> use IPv6
and reserved documentation prefixes rather than arbitrary or production
addresses <xref target="RFC3849"></xref> <xref target="RFC5737"></xref>.</t>
<t>When an example needs an IP address or prefix, follow <strong>IETF documentation
address rules</strong>:</t>

<ul spacing="compact">
<li><strong>IPv6 (preferred):</strong> use the documentation prefixes reserved in <xref target="RFC3849"></xref>
(<tt>2001:db8::/32</tt>) and <xref target="RFC9637"></xref> (<tt>3fff::/20</tt> for larger or more realistic
layouts). Represent addresses in <strong>canonical text form</strong> per <xref target="RFC5952"></xref>
(lowercase hex, suppress leading zeros, use <tt>::</tt> compression).</li>
<li><strong>IPv4 (only when required):</strong> use the TEST-NET blocks in <xref target="RFC5737"></xref>
(<tt>192.0.2.0/24</tt>, <tt>198.51.100.0/24</tt>, <tt>203.0.113.0/24</tt>) --- not production
space, arbitrary <tt>10.0.0.0/8</tt> lab subnets, or other unreserved ranges that
could collide with real deployments.</li>
<li><strong>Names:</strong> use example domain names from <xref target="RFC2606"></xref> (<tt>example.com</tt>,
<tt>example.net</tt>, <tt>example.org</tt>) rather than real operator domains.</li>
</ul>
<t>Review documentation the same way code is reviewed: a slide full of <tt>10.x.x.x</tt>
or <tt>192.168.x.x</tt> examples teaches habits that conflict with IPv6-first data
center operation. Prefer <tt>2001:db8:...</tt> and service names unless the document
explicitly covers legacy IPv4 behavior.</t>
</section>
</section>

<section anchor="part-iv-pitfalls"><name>Part IV: Pitfalls</name>

<section anchor="oob-management"><name>Out-of-Band Management and Network Boot</name>
<t>Software readiness is insufficient if servers cannot be <strong>installed, booted, or
power-cycled</strong> over IPv6. This area <strong>SHOULD be tackled very early</strong> in an IPv6
program --- before application tiers --- because <strong>hardware refresh cycles can
take up to five years</strong>. A server bought today with an IPv4-only baseboard
management controller (BMC) or provisioning stack may still block IPv6-only
operation long after application code is ready. Align purchase and RFP language
with that timeline (see <xref target="procurement"></xref>).</t>

<section anchor="often-forgotten-infrastructure-devices"><name>Often-Forgotten Infrastructure Devices</name>
<t>Out-of-band work is not limited to compute <strong>IPMI</strong>, <strong>Redfish</strong>, and <strong>PXE</strong>.
Teams routinely overlook <strong>facility and operations gear</strong> that shares the same
management VLANs and must be reachable during incidents:</t>

<ul spacing="compact">
<li><strong>UPS</strong> and power distribution monitoring</li>
<li><strong>Climate control</strong> (CRAC, chillers, environmental sensors)</li>
<li><strong>NTP</strong> appliances or stratum servers on dedicated hardware</li>
<li><strong>Console servers</strong> and serial concentrators</li>
<li><strong>KVM switches</strong>, rack PDUs, and other <strong>data center infrastructure
management</strong> devices</li>
</ul>
<t>These systems often ship with <strong>fixed IPv4-only interfaces</strong>, embedded web UIs
bound to <tt>192.168.x.x</tt>, and long firmware cadences. Include them in the same
IPv6 readiness inventory as production servers (see <xref target="application-readiness"></xref> and
<xref target="observability"></xref>); they become blockers during IPv4 decommissioning even when
every application pod is dual-stack.</t>
</section>

<section anchor="firmware-and-pxe-uefi-boot"><name>Firmware and PXE/UEFI Boot</name>
<t>Many <strong>BIOS</strong> implementations still lack usable IPv6. <strong>UEFI network boot</strong>
over IPv6 exists but <strong>varies by server vendor</strong> in ways that affect
automated provisioning. Network appliance <strong>EFI</strong> implementations are similarly
inconsistent. An IPv6-only provisioning VLAN requires explicit qualification of
every hardware generation in the fleet.</t>
</section>

<section anchor="ipmi-and-redfish"><name>IPMI and Redfish</name>
<t><strong>IPMI over IPv6</strong> is <strong>essential</strong> for <strong>remote power cycle and reboot</strong> when
management networks move to IPv6-only. Without a working BMC address on v6,
automation cannot recover a hung host without a physical visit. The same
requirement applies to the <strong>provisioning and reboot toolchain</strong> --- imaging,
PXE/UEFI orchestration, configuration management kickstart, and out-of-band
serial concentrators <bcp14>SHOULD</bcp14> be <strong>dual-stack or IPv6-only capable</strong> before
internal management VLANs drop IPv4.</t>
<t><strong>IPMI</strong> and <strong>Redfish</strong> IPv6 support differs by vendor and firmware generation:
some platforms support SLAAC, others DHCPv6, others require initial IPv4
configuration before enabling IPv6. Linux <tt>ipmitool</tt> subcommands and output
formats vary with firmware. Enterprises often <strong>defer firmware upgrades</strong> because
failed BMC updates require physical data center visits --- plan IPv6 on management
networks with spare in-rack capacity and conservative change windows.</t>
</section>
</section>

<section anchor="dns-registration"><name>DNS Registration and Dynamic Addressing</name>
<t>IPv6's default autoconfiguration (SLAAC) generates addresses from interface
identifiers. Without operational discipline, <strong>DNS lags behind actual
addresses</strong>, and break-glass access by name fails.</t>

<section anchor="slaac-switches-and-the-dns-gap"><name>SLAAC, Switches, and the DNS Gap</name>
<t>Wi-Fi controllers often integrate with DNS to register client names; <strong>access
switches frequently do not</strong>. To populate DNS for wired servers using SLAAC,
operators need <strong>MAC and address visibility</strong> from switches (for example, via
Neighbor Discovery logging or sFlow/IPFIX) correlated with inventory to derive
hostnames. Ideally, selected <strong>Neighbor Discovery events</strong> would be exported to
a registration service --- a gap in many switch implementations.</t>
</section>

<section anchor="dhcpv6-and-hostname-registration"><name>DHCPv6 and Hostname Registration</name>
<t>Enterprises that distrust client self-registration prefer <strong>DHCPv6</strong> with
central lease logging. Clients <bcp14>SHOULD</bcp14> send <strong>DHCPv6 Option 39 (Client
FQDN)</strong> so the server can register forward and reverse DNS <xref target="RFC4704"></xref>
<xref target="RFC8415"></xref>. Support for Option 39 has varied by OS; operators <bcp14>SHOULD</bcp14>
verify current behavior on every deployed OS image (including macOS, Windows,
Linux, and container base images) rather than assuming parity.</t>
<t>Device-side <strong>Dynamic DNS updates</strong> remain possible but are often disabled in
enterprise policy. For why reverse zones matter during incidents, see
<xref target="network-diagnostics"></xref>.</t>
</section>

<section anchor="dhcpv6-suitability-considerations"><name>DHCPv6 Suitability Considerations</name>
<t>DHCPv4 is extremely common in IPv4 deployments, as it is best mechanism
to automatically provide network information (such as IP address,
router, netmask, recursive DNS resolvers) to nodes.  This, combined
with a desire to have centralized logging of assigned addresses, leads
to a desire for DHCPv6 in new IPv6 deployments.  However, IPv6 includes
much of this functionality in the base protocol; a central server is not
needed. Moreover, operating system support for DHCPv6 is not as
universal as for DHCPv4, so it is not a full replacement for SLAAC.  This
means that using DHCPv6 for centralized logging of addresses or DNS
synchronization either means that some clients may be logged (as they will
use SLAAC), or some clients may not work at all (if SLAAC is disabled on
the network).  Operators <bcp14>SHOULD</bcp14> verify DHCPv6 support for all existing
and planned hardware before relying on it for logging features.</t>
</section>
</section>

<section anchor="icmpv6-pmtud"><name>ICMPv6, PMTUD, and Middleboxes</name>

<section anchor="do-not-block-icmpv6"><name>Do Not Block ICMPv6</name>
<t>Teams trained to block ICMPv4 &quot;for security&quot; sometimes apply the same policy
to ICMPv6. <strong>ND and PMTUD depend on ICMPv6</strong> <xref target="RFC4443"></xref> <xref target="RFC8201"></xref>. Blocking
ICMPv6 produces hung connections, mysterious TLS timeouts, and DNS failures
that are misdiagnosed as application bugs. Filter <strong>specific message types</strong>
judiciously; do not implement blanket deny rules. For <strong>echo request/reply</strong>
used in reachability testing inside the data center, see <xref target="network-diagnostics"></xref>.</t>
<t>Blanket deny is often a <strong>sequencing failure</strong>, not only a knowledge gap:
security meets IPv6 for the first time at the perimeter firewall late in the
rollout, with no agreed threat model and full accountability for residual risk.
Agree filtering with security when the addressing plan is written (see
<xref target="programme-sponsorship"></xref>), not as the last firewall change. Treat <xref target="RFC4890"></xref>
training as a <strong>prerequisite</strong> to the rule change.</t>
</section>

<section anchor="path-mtu-discovery"><name>Path MTU Discovery</name>
<t>When many organizations enabled IPv6 on their web sites during <strong>World IPv6 Day</strong>
(2011) and <strong>World IPv6 Launch</strong> (2012), <strong>Path MTU Discovery failures</strong> forced
operators to <strong>lower TCP MSS</strong> on servers and load balancers until paths were
validated --- a reminder that IPv6 MTU assumptions differ from internal IPv4
MTU 1500 end-to-end paths. Mobile operators (for example, T-Mobile USA and
Reliance Jio in India) run <strong>IPv6-only</strong> access networks successfully at scale;
problems on enterprise fixed networks often come from <strong>middleboxes and
policy</strong>, not from IPv6 itself.</t>
<t>Hard PMTUD failures also interact with <strong>DNS over large responses</strong> when
fragmentation is mishandled. If fragmented UDP is dropped, DNS appears
&quot;flaky&quot; only for some large records. Where classic ICMP-based PMTUD is unreliable,
operators and implementers <bcp14>MAY</bcp14> also use Packetization Layer Path MTU
Discovery (DPLPMTUD) <xref target="RFC8899"></xref>.</t>
</section>

<section anchor="vpns-and-nat64"><name>VPNs and NAT64</name>
<t>Some VPN products treat translated packets as attacks. <strong>NAT64</strong> <xref target="RFC6146"></xref>
changes headers; a VPN that validates packet integrity on IPv4 paths may <strong>drop
NAT64 flows</strong>. Prefer <strong>edge gateways</strong> for translation as described in
<xref target="internet-egress"></xref> and <xref target="ipv4-only-wrappers"></xref> rather than sprouting translators on
every host. Long-term, <strong>VPN endpoints should be native IPv6</strong> on the data
center side. Until then, document which access paths require IPv4 literal
connectivity vs IPv6.</t>
</section>
</section>

<section anchor="localhost-pitfalls"><name>Hard-Coded Addresses and Localhost Pitfalls</name>
<t><strong>Listening</strong> and <strong>connecting</strong> to loopback are different problems.</t>
<t><tt>::1</tt> is <tt>localhost</tt>; <tt>127.0.0.1</tt> is <tt>localhost</tt>. <strong>Do not embed IP addresses
in application code</strong> when a name will do --- especially for <strong>listen/bind</strong>
targets. Use hostnames and service discovery; resolve names at connection time.
Clients that connect to <tt>127.0.0.1</tt> remain acceptable where IPv4 loopback stays
on <tt>lo</tt> (see <xref target="localhost-pitfalls"></xref>).</t>
<t>A recurring <strong>server-side</strong> defect is binding services to <strong><tt>127.0.0.1</tt></strong>
instead of <strong><tt>localhost</tt></strong> (or an explicit dual-stack listen). On dual-stack
hosts, <tt>127.0.0.1</tt> listens <strong>IPv4 loopback only</strong>; IPv6 clients that resolve
<tt>localhost</tt> to <tt>::1</tt> cannot connect even when the service &quot;runs locally.&quot; The
fix is to use name-based bind targets (<tt>localhost</tt>), listen on <strong>both</strong> loopback
families (<tt>127.0.0.1</tt> and <tt>::1</tt>), or use explicit dual-stack sockets depending
on platform API.</t>
<t><strong>Client-side</strong> use of <strong><tt>127.0.0.1</tt> as a connect target</strong> is a different case.
Local agents, scripts, and libraries that dial <tt>127.0.0.1</tt> continue to work on
hosts where IPv4 loopback remains on <tt>lo</tt> --- which is the normal state even on
systems that are IPv6-only on application interfaces and, on Linux, cannot
disable IPv4 in the kernel entirely. Migration programs are not required to
spend effort replacing every client connect to <tt>127.0.0.1</tt> when loopback IPv4 is left
in place; prioritize <strong>listen</strong> misconfigurations that block IPv6-only local
clients. To surface applications that wrongly assume IPv4 loopback is present,
<xref target="I-D.ietf-v6ops-ipv6-app-testing"></xref> recommends testing in an environment
without IPv4 on the loopback interface.</t>
<t>DNS (or an equivalent naming and service registry) becomes <strong>essential</strong> in
IPv6 because humans cannot memorize 128-bit addresses. Operational maturity
includes forward and reverse DNS for infrastructure, health checks keyed on
names, and monitoring that labels series by hostname rather than by address
literals.</t>
<t>Similar <strong>listen-side</strong> bugs appear with <strong><tt>0.0.0.0</tt></strong> vs <strong><tt>::</tt></strong> semantics,
health probes that curl IPv4 literals against services bound IPv6-only, and
container images that ship <tt>/etc/hosts</tt> without IPv6 entries.</t>
</section>

<section anchor="name-resolution"><name>Resolving Hostnames to Addresses</name>
<t>This section covers name-to-address APIs and client resolution behavior --- the
connection layer above application readiness gaps cataloged above.</t>
<t>Turning a hostname into addresses is a separate step from choosing which
address to connect to. Prefer an <strong>address-family-agnostic</strong> API in the OS,
library, or framework that already returns the full candidate set and supports
both IPv4 and IPv6, unless there is a specific reason to do otherwise.
Application code <bcp14>MUST</bcp14> obtain <strong>all</strong> candidate addresses, then apply local
policy (retries, Happy Eyeballs <xref target="RFC8305"></xref>, load spreading --- see
<xref target="address-selection"></xref> and <xref target="client-load-balancing"></xref>). <strong>Prefer the OS or a shared
library's Happy Eyeballs implementation</strong> over reimplementing connection racing
in each application; when a custom implementation is unavoidable, <strong>delay the
IPv4 connection attempt</strong> so IPv6 has more time to succeed first --- consistent
with <xref target="RFC8305"></xref> and with ongoing work in the HAPPY working group.</t>
<t>Even with correct client retry logic, <strong>missing or wrong IPv6 routes</strong> can send
internal AAAA targets out an Internet default route. Edge hosts in transitional
layouts <bcp14>SHOULD</bcp14> install <strong><tt>unreachable</tt></strong> routes for internal aggregates so
address-family fallback can succeed (see <xref target="dual-homed-transitional-routing"></xref>).</t>

<section anchor="use-getaddrinfo-not-legacy-one-address-apis"><name>Use getaddrinfo(), Not Legacy One-Address APIs</name>
<t>On POSIX systems, when a higher-level family-agnostic helper is not available,
the correct resolver entry point is <strong><tt>getaddrinfo()</tt></strong>
<xref target="RFC3493"></xref>. It takes a hostname (or numeric address string), service/port hints,
and an <tt>addrinfo</tt> hints structure, and returns a <strong>linked list of <tt>addrinfo</tt>
structures</strong> --- one node per destination address candidate. The caller
<strong>MUST iterate over the entire list</strong> (the <tt>ai_next</tt> chain) trying to connect
to each candidate until either successful or no candidates are left,
and <bcp14>MUST</bcp14> release the list with <tt>freeaddrinfo()</tt> afterwards.</t>
<t>Please note: <strong><tt>getaddrinfo()</tt></strong> is the name-to-address API for retrieving a
full list; it is not the same as:</t>

<ul spacing="compact">
<li><strong><tt>gethostbyname()</tt></strong> and <strong><tt>gethostbyname2()</tt></strong> --- deprecated, not
thread-safe, and still present in old tutorials.</li>
<li><strong><tt>inet_addr()</tt></strong>, <strong><tt>inet_aton()</tt></strong>, and <strong><tt>inet_pton()</tt></strong> --- parse a
<strong>literal</strong> address string into binary; they perform <strong>no DNS lookup</strong> and
return a single address only.</li>
<li>Higher-level HTTP or RPC helpers that resolve a name internally and connect to
<strong>one</strong> chosen address without exposing the full set --- fine for quick
clients, unsuitable when the service relies on multiple A/AAAA records.</li>
</ul>
<t>To request both IPv4 and IPv6 results, set <tt>hints.ai_family</tt> to <tt>AF_UNSPEC</tt>
(unless a deliberate single-family policy applies). Inspect <tt>ai_family</tt>,
<tt>ai_addrlen</tt>, and <tt>ai_addr</tt> on <strong>each</strong> list element; do not assume every node
has the same address family.</t>
<t>Language runtimes expose the same idea under different names:</t>

<ul spacing="compact">
<li><strong>Python:</strong> <tt>socket.getaddrinfo()</tt> returns a list of tuples --- iterate all
entries; avoid <tt>socket.gethostbyname()</tt>, which returns one IPv4 address.</li>
<li><strong>Go:</strong> <tt>net.DefaultResolver.LookupIPAddr()</tt> or <tt>LookupIP()</tt>;
better use <tt>net.Dialer</tt> which provides Happy Eyeballs support.</li>
<li><strong>Java:</strong> <tt>InetAddress.getAllByName()</tt> returns an array; <strong><tt>getByName()</tt></strong>
returns only the first address and is a common source of &quot;works in the lab&quot;
failures under round-robin DNS.</li>
<li><strong>Node.js:</strong> <tt>dns.promises.lookup()</tt> or <tt>dns.lookup()</tt> with <tt>{ all: true }</tt>
as the default <tt>lookup()</tt> without <tt>all: true</tt> returns a single address;
better use <tt>net.connect</tt> with <tt>autoSelectFamily</tt> which provides Happy Eyeballs support.</li>
</ul>
<t>Pay special attention when connecting to a <strong>hostname</strong> (as opposed to a numeric
literal): resolution can return both IPv4 and IPv6 addresses, and often more than
one of each. A failed <tt>connect()</tt> to <strong>one</strong> of those addresses does <strong>not</strong>
mean the host is unreachable. Application code <bcp14>MUST NOT</bcp14> report the
destination as down after trying only the first AAAA or A record and never
the other family, or after IPv4 fails while unused IPv6 candidates remain (and
vice versa). Try other addresses from the resolved list --- or use Happy Eyeballs
<xref target="RFC8305"></xref> --- before concluding that the service cannot be reached. When
<strong>none</strong> of the candidates succeed, do <strong>not</strong> surface only the error from the
first attempt: preferably report all failures encountered. If this is not feasible,
report at least the <strong>most pertinent</strong> failure --- typically the attempt
that progressed furthest (for example TCP handshake completed but TLS or
application protocol failed, or a clear ICMP unreachable rather than a
timeout on an earlier candidate).</t>
</section>

<section anchor="why-the-full-list-matters"><name>Why the Full List Matters</name>
<t>DNS often publishes <strong>multiple A and AAAA records</strong> for availability and load
distribution. Connecting to <tt>result-&gt;ai_addr</tt> and ignoring <tt>ai_next</tt> defeats
that design. After collecting the list, the application (or a shared library)
may ether rely on the order produced by the libc implementation (usually following  <xref target="RFC6724"></xref>)
or apply a more sophisticated re-ordering strategy based on Happy Eyeballs,
within-family random or weighted selection for equivalent data-center backends.
There is no guarantee that the first entry is the best choice,
reflects order from DNS or is even functional at all.</t>
<t>Note that libc implementations may <strong>reorder</strong> the list per <xref target="RFC6724"></xref> before
returning it (see <xref target="address-selection"></xref>). You still need every element --- reorder
yourself if policy requires --- but you cannot skip resolution and hope DNS
order survives unchanged.</t>
</section>

<section anchor="numeric-input-at-the-edge"><name>Numeric Input at the Edge</name>
<t>When configuration or user input contains an address <strong>literal</strong> rather than a
hostname, <strong><tt>inet_pton()</tt></strong> (or the language equivalent) converts it to binary
for storage. When input might be either a name or a literal, <strong><tt>getaddrinfo()</tt></strong>
accepts both; alternatively, try literal parse first, then fall back to DNS.
Either way, convert once to binary and use binary forms internally.</t>
</section>

<section anchor="address-selection"><name>Address Selection, gai.conf, and DNS Round Robin</name>
<t>The Linux file <tt>/etc/gai.conf</tt> and the algorithms in <xref target="RFC6724"></xref> control
<strong>address selection order</strong> for dual-stack hosts --- which address family and
which destination address are tried first. This is invisible in application
source but visible in production load distribution.</t>
<t>RFC 6724 has two axes that operators often conflate:</t>

<ul spacing="compact">
<li>The <strong>policy table</strong> decides which <em>class</em> wins (for example ULA vs GUA vs
IPv4). <xref target="I-D.ietf-6man-rfc6724-update"></xref> updates that table so known-local
ULA-ULA is preferred over IPv4 and, for local use, over GUA. That helps
dual-stack sites that use ULAs internally. It does <strong>not</strong> change Rule 9.</li>
<li><strong>Rule 9</strong> (&quot;Use longest matching prefix&quot;) decides which <em>same-family</em>
destination is tried first. It compares each candidate with its likely
source address and <strong>sorts addresses deterministically</strong> <xref target="RFC6724"></xref>.
Resolver libraries such as <strong>glibc</strong> implement this sorting inside
<tt>getaddrinfo()</tt>.</li>
</ul>
<t><strong>Rule 9 is a problem if you expect DNS load balancing.</strong> A rotated set of A
or AAAA records can collapse to &quot;always try the same address first&quot; once
Rule 9 runs, concentrating connections on one backend. The problem is subtle
on IPv4 but <strong>often severe on IPv6</strong>, especially inside a data center where
many servers are functionally equidistant and operators expect DNS or anycast
to spread load. Changing <tt>/etc/gai.conf</tt> adjusts precedence tables but
<strong>does not fully disable Rule 9</strong> in all implementations.</t>
<t><xref target="I-D.martin-ipv6-addr-selection-updates"></xref> is <strong>trying to address</strong> that gap
at the resolver: operators would configure prefix ranges for which Rule 9
does not apply, so <tt>getaddrinfo()</tt> preserves same-family DNS order without
application changes. That is not something operators can assume on the fleet
today.</t>
<t><strong>Meanwhile, load balancing MUST be treated as something the client handles</strong>
--- a shared library, service-discovery client, or mesh --- not DNS order
after <tt>getaddrinfo()</tt>. The discipline matches Happy Eyeballs: <strong>do not
assume</strong> destination selection is correct for every language, runtime, and
client. <strong>Review it per client</strong>, especially inside a data center where
Rule 9 is most harmful. DNS load balancing is often an <strong>implicit
assumption</strong> buried in connection code --- &quot;we publish multiple AAAA records,
so clients will spread&quot; --- so ordinary code review may never surface it.
Pattern scanners such as <strong>Semgrep</strong> or <strong>CodeQL</strong> (see <xref target="static-analysis"></xref>)
<bcp14>SHOULD</bcp14> flag <tt>getaddrinfo()</tt> and language equivalents that take only the
first result, skip within-family spreading, or otherwise treat DNS order as
load balancing, so each call site is questioned rather than assumed correct.</t>
<t>Mitigations while Rule 9 still reorders:</t>

<ul spacing="compact">
<li><strong>Internal / cluster backends</strong> intended to be equivalent: within-family
random or weighted selection (or service mesh / anycast). Do <strong>not</strong> trust
DNS or <tt>getaddrinfo()</tt> order for spread. Do <strong>not</strong> shuffle the <strong>entire</strong>
resolved list across families --- that breaks IPv6 preference; partition by
family first, then randomize or weight <strong>within</strong> each family.</li>
<li><strong>External Internet destinations:</strong> keep RFC 6724 family and prefix-class
order (do not shuffle IPv4 with IPv6). Same-family DNS round-robin is still
not a load-balancing strategy while Rule 9 runs.</li>
<li>Prefer putting resolution, Happy Eyeballs, and within-family spreading in
<strong>shared client libraries</strong> so each application team does not rediscover
the same interaction (see <xref target="client-load-balancing"></xref>).</li>
</ul>
</section>

<section anchor="runtime-resolution"><name>Runtime-Specific Resolution (Not Always glibc)</name>
<t>Examples above assume POSIX <strong><tt>getaddrinfo()</tt></strong> via <strong>glibc</strong> (or an equivalent
libc). Not every language or runtime uses libc for name resolution. <strong>Java</strong>
maintains its own resolver stack and system properties such as
<strong><tt>java.net.preferIPv4Stack</tt></strong> and <strong><tt>java.net.preferIPv6Addresses</tt></strong> that
override address-family preference independently of <tt>/etc/gai.conf</tt>. A JVM
configured to prefer IPv4 can appear &quot;IPv6 broken&quot; even when the OS resolver
returns AAAA records. Test Java services with explicit property settings and
with <strong><tt>InetAddress.getAllByName()</tt></strong>, not <strong><tt>getByName()</tt></strong>.
<xref target="I-D.ietf-v6ops-ipv6-app-testing"></xref> catalogs these destination-address-selection
and address-filtering deviations (including Java preferring IPv4 and resolvers
such as NGINX that ignore address-family availability) as common IPv6 failure
sources.</t>
<t>In extreme cases, an <strong><tt>/etc/resolv.conf</tt></strong> that lists <strong>only IPv6 nameserver
addresses</strong> can interact badly with runtimes that bootstrap DNS over IPv4 first
or assume a v4-reachable resolver path. Symptoms include slow resolution,
timeouts, or unexpected family ordering. Qualify resolver configuration on
dual-stack and IPv6-only hosts for each runtime in the fleet, not only for C
callers of <tt>getaddrinfo()</tt>.</t>
</section>
</section>

<section anchor="address-representation"><name>Address Representation</name>
<t>IPv6 addresses have several equivalent textual forms <xref target="RFC4291"></xref>:</t>

<ul spacing="compact">
<li>Full form: <tt>2001:db8:0:0:0:0:0:1</tt></li>
<li>Compressed zeros: <tt>2001:db8::1</tt></li>
<li>Loopback: <tt>::1</tt> (compare IPv4 <tt>127.0.0.1</tt>)</li>
<li>Unspecified: <tt>::</tt></li>
<li>IPv4-mapped IPv6: <tt>::ffff:192.0.2.1</tt></li>
</ul>
<t>In <strong>dual-stack</strong> environments, IPv4 addresses also appear in multiple forms
in code and configuration:</t>

<ul spacing="compact">
<li>Dotted decimal: <tt>192.0.2.1</tt></li>
<li>Integer (historical APIs): <tt>3232235521</tt></li>
<li>Hex packed in configs: <tt>0xC0000201</tt></li>
<li>Mapped in IPv6 APIs: <tt>::ffff:192.0.2.1</tt></li>
</ul>
<t>In software, addresses <bcp14>SHOULD</bcp14> be stored in a <strong>normalized</strong> form ---
preferably a <strong>binary field or structure sized for 128 bits</strong> (for example,
<tt>in6_addr</tt>, <tt>sockaddr_storage</tt>, or an equivalent language type), so the same
field can hold IPv4 or IPv6 and equality is unambiguous. Binary storage provides
normalization by construction. If a string form is unavoidable, apply a <strong>strict
canonicalization</strong> function (for example <xref target="RFC5952"></xref>) at write time and compare
only normalized values --- never parse or compare address strings ad hoc in
application logic. Provide helpers to convert between binary and human-readable
forms at display and configuration I/O boundaries. When addresses are handled as
data (logging, ACLs, management output), test that code accepts all valid
representations <xref target="RFC4291"></xref> and renders canonical text <xref target="RFC5952"></xref>;
<xref target="I-D.ietf-v6ops-ipv6-app-testing"></xref> covers this &quot;addresses as data&quot; testing.</t>
<t>For <strong>human comparison</strong> in fixed-width tables, spreadsheets, or IPAM grids,
operators <bcp14>MAY</bcp14> deliberately diverge from <xref target="RFC5952"></xref> --- for example by
suppressing <tt>::</tt> compression or zero-padding hextets --- so columns align and
adjacent addresses are easier to scan. That form <bcp14>SHOULD</bcp14> be consistent
within the display context. Interchange formats, APIs, logs-as-data, and
configuration that software parses <bcp14>SHOULD</bcp14> still use binary storage or
canonical text per <xref target="RFC5952"></xref>; do not treat a tabular display convention as
the on-the-wire or storage format.</t>
<t>Applications <bcp14>SHOULD</bcp14> treat names, not literal addresses, as the stable
interface (see <xref target="name-resolution"></xref>). To turn a name into addresses, use the
APIs described in <xref target="name-resolution"></xref> --- not legacy one-address helpers and
not string parsing.</t>
</section>

<section anchor="client-load-balancing"><name>Client-Side Load Balancing</name>
<t>Client-side load balancing builds on the resolution patterns in <xref target="name-resolution"></xref>
when services publish multiple A/AAAA records.</t>
<t>As described in <xref target="address-selection"></xref>, <strong>RFC 6724 Rule 9</strong> reorders addresses
returned from DNS. In data centers that rely on multiple AAAA records for
spread, connection counts can skew badly --- one backend receives most IPv6
connections while others appear idle. This section assumes the application has
already obtained the <strong>full address list</strong> using the patterns in
<xref target="name-resolution"></xref>.</t>
<t><strong>Recommended pattern</strong> (when the shared library does not already encapsulate
this --- prefer OS or library Happy Eyeballs and service-discovery clients
first; see <xref target="name-resolution"></xref> and the HAPPY working group):</t>

<ol spacing="compact">
<li>Resolve the service name to all addresses (or refresh from service discovery).</li>
<li>Partition addresses by address family.</li>
<li>Apply family preference policy (operator choice: IPv6-first, happy eyeballs,
or parallel). For Happy Eyeballs, <strong>start IPv4 attempts after a deliberate
delay</strong> so IPv6 connections have priority time to complete.</li>
<li>For <strong>equivalent data-center backends</strong>, <strong>randomize or round-robin within
each family</strong> rather than trusting DNS order after <tt>getaddrinfo()</tt> --- Rule 9
defeats DNS load balancing today (see <xref target="address-selection"></xref>);
<xref target="I-D.martin-ipv6-addr-selection-updates"></xref> is trying to fix that in the
resolver, but clients must handle spreading until hosts implement it. When
service discovery or endpoint metadata provides <strong>weights</strong>, prefer
<strong>weighted</strong> selection within a family. For <strong>external Internet</strong>
destinations, keep family preference from RFC 6724 / Happy Eyeballs; do
<strong>not</strong> shuffle IPv4 and IPv6 together. Like Happy Eyeballs, destination
selection is a <strong>client behavior to inventory and review</strong>, not a property
of DNS.</li>
<li>Optionally implement retries across the full set on failure.</li>
</ol>
<t><strong>Endpoint freshness:</strong> treat selection policy as distinct from
<strong>discovery and refresh</strong>. Re-resolve on DNS TTL expiry or refresh from
service discovery so drained, replaced, or newly added backends enter and
leave the candidate set; otherwise clients keep balancing across stale
addresses.</t>
<t><strong>Long-lived connections:</strong> for HTTP/2, gRPC, and similar multiplexed pools,
endpoint selection often occurs only when a connection is opened. Equal
distribution of <strong>connections</strong> does not imply equal distribution of
<strong>requests</strong>, and weight or membership changes may take effect only as old
connections drain.</t>
<t>Implement load balancing in <strong>shared client libraries</strong> so every service does
not rediscover the same RFC 6724 interaction. Most software engineers are not
DNS or path-selection specialists, and they should not have to be: put
resolution, Happy Eyeballs, and within-family spreading in <strong>one</strong> (or a small
set of) platform libraries used across the codebase, then <strong>review each client</strong>
that still rolls its own destination selection --- the same discipline as
Happy Eyeballs coverage. Because DNS-spread expectations are often implicit,
pair that review with the Semgrep / CodeQL patterns in <xref target="static-analysis"></xref>
rather than relying on humans to notice every <tt>getaddrinfo()</tt> call site.
Platform and SRE teams can then clear IPv6 readiness
by saying <strong>upgrade the shared client to version X</strong> and apply (or stop
overriding) the documented dual-stack profile, rather than teaching each
application team how to rewrite connection logic --- the same readiness-gate
pattern as <xref target="application-readiness"></xref>.</t>
</section>

<section anchor="ip-address-storage-in-application-data"><name>IP Address Storage in Application Data</name>
<t>Many services store client or server IP addresses in databases, logs, caches,
and message queues using <strong>fixed-width fields</strong> (32-bit integers, <tt>CHAR(15)</tt>)
or parsers that accept dotted decimal only. IPv6 requires <strong>structured address
types</strong> (128-bit binary, or text with adequate length) and family-aware
comparison.</t>
<t>Affected areas include:</t>

<ul spacing="compact">
<li><strong>Geolocation databases</strong> (for example, MaxMind and similar) used for
compliance, fraud, and ad targeting --- coverage and accuracy for IPv6 vary
widely.</li>
<li><strong>Real User Monitoring (RUM)</strong> and <strong>DNS steering</strong> products that map clients
to &quot;nearest&quot; PoP --- if the probe or edge logic is IPv4-only, steering
decisions silently degrade for IPv6 clients.</li>
<li><strong>Rate limiting and abuse detection</strong> keyed on &quot;IP&quot; strings with naive
splitting on <tt>.</tt> characters.</li>
</ul>
<t>Refactoring often touches every schema, serializer, and analytics job that
touched the field --- plan migration as a <strong>program</strong>, not a one-line fix.</t>
</section>

<section anchor="databases-acls-and-security-tools"><name>Databases, ACLs, and Security Tools</name>
<t><strong>MySQL and MariaDB</strong> host-based ACLs are historically <strong>string comparisons</strong>
on the client address field. IPv6 literals contain colons and zone identifiers;
copying IPv4 ACL patterns without testing produces false denials or overly
broad grants. Test <tt>USER@'2001:db8::/32'</tt>-style entries explicitly.</t>
<t>Security agents (EDR, IDS, WAF) may lack IPv6 decode paths even when they claim
dual-stack support. Validate <strong>both directions</strong> --- ingress to the service and
egress from the service --- under IPv6-only client paths. The same teams can
extend PR checks with static analysis rules (see <xref target="static-analysis"></xref>).</t>
</section>

<section anchor="language-runtimes"><name>Language Runtimes and Libraries</name>
<t><strong>Python</strong> exposes several <strong>deprecated socket helpers that are IPv4-only or
return only one address</strong>, yet remain common in production code and older
tutorials. Examples include:</t>

<ul spacing="compact">
<li><strong><tt>socket.gethostbyname()</tt></strong> and <strong><tt>socket.gethostbyname_ex()</tt></strong> --- resolve
a name to IPv4 only; use <strong><tt>socket.getaddrinfo()</tt></strong> and iterate all results
(see <xref target="name-resolution"></xref>).</li>
<li><strong><tt>socket.gethostbyaddr()</tt></strong> --- reverse lookup with IPv4-centric assumptions;
prefer <strong><tt>getnameinfo()</tt></strong> with a binary <tt>sockaddr</tt> from the connection.</li>
<li><strong><tt>socket.inet_aton()</tt></strong> and <strong><tt>socket.inet_ntoa()</tt></strong> --- convert IPv4
literals only; use <strong><tt>socket.inet_pton()</tt></strong> and <strong><tt>socket.inet_ntop()</tt></strong> for
both address families.</li>
</ul>
<t>These APIs <strong>will not return IPv6</strong> even when the host has AAAA records and
IPv6 connectivity. Replacing them is rarely a one-line change --- call sites,
tests, and error handling often assume 32-bit or dotted-decimal form.</t>
<t>Other languages have similar legacy (<tt>inet_aton</tt> assumptions, IPv4-only standard
library gaps). Code review checklists <bcp14>SHOULD</bcp14> include:</t>

<ul spacing="compact">
<li>No unparsed string IPs in business logic</li>
<li>Resolve names with a <strong>full-list</strong> API (see <xref target="name-resolution"></xref>); never call
legacy one-address helpers in new code</li>
<li>Tests that run against <strong>IPv6 literals and DNS names with AAAA records</strong></li>
</ul>
</section>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>
<t>IPv6 restores global routability; <strong>absence of NAT is not absence of need for
firewall policy</strong>. ULAs and link-local addresses still require filtering at
boundaries. ICMPv6 filtering must preserve ND and PMTUD. Application-level
ACLs and security products must parse IPv6 literals correctly (see
<xref target="application-readiness"></xref>).</t>
<t><strong>Security appliances and host security software are notoriously weak on IPv6</strong>
--- incomplete decode, IPv4-only dashboards, agents that drop or mislabel v6
traffic, and policies that silently fail open or closed. Engage the <strong>security
organization very early</strong> in the IPv6 program --- as a Part I stakeholder gate
(see <xref target="programme-sponsorship"></xref>), in parallel with out-of-band and network design
(see <xref target="oob-management"></xref>). In many enterprises, application SREs
<strong>do not have full visibility</strong> into which tools the security team deploys;
there is often deliberate <strong>operational secrecy</strong> around EDR, NDR, DLP, and
forensics platforms. Assume unknown agents exist on every host until proven
otherwise (see <xref target="host-agents"></xref>); establish a shared readiness process with
security leadership rather than discovering blockers during the first IPv6-only
pilot.</t>
<t>Security monitoring systems <bcp14>MUST</bcp14> receive IPv6 traffic mirrors, tap coverage,
and metadata <strong>on parity with IPv4</strong> before declaring IPv6 production-ready.
Validate that incident response playbooks (pcap collection, IP blocking,
geo blocking, threat intel feeds) work with <strong>128-bit addresses</strong> and canonical
text forms <xref target="RFC5952"></xref>. PR static analysis for IPv4-only patterns
(see <xref target="static-analysis"></xref>) complements but does not replace security-tool
qualification.</t>
<t>Operator inventory practices in <xref target="application-readiness"></xref> also reduce supply-chain
risk from undeclared IPv4-only dependencies in the control plane.</t>
</section>

<section anchor="iana-considerations"><name>IANA Considerations</name>
<t>This document has no IANA actions.</t>
</section>

<section anchor="acknowledgments"><name>Acknowledgments</name>
<t>The authors thank the following people who contributed suggestions and
editorial improvements to this document:</t>

<ul spacing="compact">
<li><strong>Jason Healy</strong> (Suffield Academy)</li>
<li><strong>Spiro Stathakis</strong> (isp6)</li>
<li><strong>Sulabh Soneji</strong></li>
<li><strong>Andrew Yourtchenko</strong> (Cisco)</li>
</ul>
</section>

</middle>

<back>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1918.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3493.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3596.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3849.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4193.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4291.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4443.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4704.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4861.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4890.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5737.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5952.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6146.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6724.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6890.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8200.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8201.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8415.xml"/>
</references>
<references><name>Informative References</name>
<reference anchor="ARCEP-IPV6-GUIDE" target="https://www.arcep.fr/fileadmin/cru-1648459125/reprise/observatoire/ipv6/guide-entreprises-how-to-deploy-IPv6-march-2022.pdf">
  <front>
    <title>How to Deploy IPv6 in Your Enterprise (Guide for Enterprises)</title>
    <author>
      <organization>ARCEP</organization>
    </author>
    <date year="2022" month="March"></date>
  </front>
</reference>
<reference anchor="ARIN-APPS-V6" target="https://www.arin.net/resources/guide/ipv6/preparing_apps_for_v6.pdf">
  <front>
    <title>Preparing Applications for IPv6: A Software Developers Guide to Writing and Migrating Networked Applications for Use on IPv6 Networks</title>
    <author>
      <organization>ARIN</organization>
    </author>
  </front>
</reference>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-6man-rfc6724-update.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-v6ops-ipv6-app-testing.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-v6ops-ipv6-only.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.martin-ipv6-addr-selection-updates.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2606.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4038.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7381.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8305.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8899.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9637.xml"/>
</references>

<section anchor="ipv6-fundamentals"><name>IPv6 Fundamentals for Software Engineers</name>
<t>Software engineers who have worked only in IPv4 environments often discover
that IPv6 is not &quot;IPv4 with longer addresses.&quot; The differences below affect
code, configuration, monitoring, and troubleshooting daily.</t>

<section anchor="address-size-and-header-format"><name>Address Size and Header Format</name>
<t>IPv4 addresses are <strong>32 bits</strong>; IPv6 addresses are <strong>128 bits</strong>
<xref target="RFC8200"></xref>. The IPv4 header has a <strong>variable length</strong> because options are
carried in the main header. The IPv6 header has a <strong>fixed 40-byte length</strong>,
which simplifies fast-path processing on routers and hosts. Additional IPv6
options live in <strong>extension headers</strong> chained after the main header; routers
<strong>do not need to process</strong> most extension headers for forwarding
<xref target="RFC8200"></xref>.</t>
</section>

<section anchor="checksums-jumbo-frames-and-fragmentation"><name>Checksums, Jumbo Frames, and Fragmentation</name>
<t>IPv6 removed the header checksum present in IPv4; integrity is assumed to be
covered by upper-layer protocols (for example, TCP, UDP, and SCTP) and link
layers where applicable <xref target="RFC8200"></xref>. Operators can use <strong>jumbo frames</strong> on
supported paths to reduce per-packet overhead and acknowledgment rates on
high-throughput links. Jumbo frames are an operational choice on the LAN and
require end-to-end support; they are not an IPv6 requirement but are often
easier to reason about once NAT middleboxes are removed.</t>
<t>IPv4 allowed routers to fragment packets in transit. IPv6 <strong>fragments only at
endpoints</strong> <xref target="RFC8200"></xref>. If a packet exceeds the path MTU, the source discovers
the limit through Path MTU Discovery (see <xref target="icmpv6-pmtud"></xref>) rather than relying
on router fragmentation. Application teams that tune MSS or disable PMTUD on
IPv4 often <strong>cannot</strong> copy those habits to IPv6: endpoints alone fragment, and
paths that depended on router fragmentation or aggressive MSS clamping may fail
until PMTUD (or DPLPMTUD <xref target="RFC8899"></xref>) works end-to-end (see <xref target="icmpv6-pmtud"></xref>).</t>
</section>

<section anchor="icmpv6-and-neighbor-discovery"><name>ICMPv6 and Neighbor Discovery</name>
<t>IPv4 Address Resolution Protocol (ARP) is replaced in IPv6 by <strong>Neighbor
Discovery (ND)</strong> carried in <strong>ICMPv6</strong> <xref target="RFC4861"></xref> <xref target="RFC4443"></xref>. ND resolves
addresses on the local link, discovers routers, and performs other essential
functions. <strong>ICMPv6 therefore MUST NOT be blocked wholesale</strong> on IPv6 paths
the way some IPv4 deployments block all ICMP. Blocking ICMPv6 breaks ND and
PMTUD and produces failures that look like application bugs.  Guidance exists
to identify essential ICMPv6 traffic that should not be blocked <xref target="RFC4890"></xref>.</t>
</section>

<section anchor="end-to-end-connectivity"><name>End-to-End Connectivity</name>
<t>IPv4 data centers often rely on Network Address Translation (NAT), carrier-grade
NAT (CGNAT), and overlapping private address space <xref target="RFC1918"></xref>. IPv6 restores
the <strong>end-to-end principle</strong>: globally unique addresses (with deliberate
exceptions noted below) can be routed on the Internet without translation.
Routing replaces NAT for many multi-tenant container scenarios, which simplifies
traffic inspection but requires disciplined prefix planning (see
<xref target="internet-addressing"></xref>).</t>
</section>

<section anchor="address-types"><name>Address Types and Terminology</name>
<t>Careless use of the word &quot;IPv6&quot; causes outages. This document uses the
following terms:</t>
<t><strong>Link-local address</strong>: An address in <tt>fe80::/10</tt> used only on a single link
<xref target="RFC4291"></xref>. Link-local addresses are <strong>not</strong> routed on the Internet. On
Linux, connecting to a link-local destination requires a <strong>zone identifier</strong>
(for example, <tt>fe80::1%eth0</tt>) because the same link-local prefix exists on
every interface.</t>
<t><strong>Unique Local Address (ULA)</strong>: An address in <tt>fc00::/7</tt> intended for local
use and <strong>not</strong> globally routed <xref target="RFC4193"></xref>. ULAs resemble IPv4 private space
in purpose but are uncommon in many data center designs that use provider-
aggregated global unicast space internally. Like IPv4 private address space,
ULAs can create <strong>renumbering work</strong> when companies merge or networks are
combined --- a data center network is never final.</t>
<t><strong>Global Unicast Address (GUA)</strong>: A globally routable IPv6 address assigned
from an organization's allocation of IPv6 addresses.</t>
<t>Unlike IPv4, there is <strong>no RFC 1918 equivalent that dominates data center
design</strong>. With rare exceptions (link-local, ULA, and special-purpose ranges
in <xref target="RFC6890"></xref>), <strong>IPv6 unicast addresses are designed to be globally
unique and routable</strong>. Security boundaries are enforced by routing policy and
firewall rules, not by assuming addresses are inherently non-routable.  We
use two additional terms to distinguish addresses based on these policies:</t>
<t><strong>Internal global unicast address</strong>: A globally routable IPv6 address used
<strong>inside</strong> the data center.  These addresses are reachable according to
routing and security policy, not because they are &quot;private.&quot;</t>
<t><strong>External global unicast address</strong>: A globally routable address presented to
clients on the Internet, often via load balancers or anycast.</t>
<t>Unlike IPv4, nodes typically have multiple IPv6 addresses assigned to each
of their interfaces.  The link-local addresses are necessary to participate
in Neighbor Discovery and so serve a vital purpose even though they are not
globally routable.  Additionally, because so many IPv6 addresses are
available, some machines may use multiple global addresses simultaneously
for purposes such as privacy or temporary use. The number of addresses per
host can matter for <strong>TCAM and ACL scale</strong> on switches and firewalls --- another
reason to prefer an explicit addressing plan and to avoid unexpected
autoconfigured addresses (see <xref target="prefix-allocation"></xref> and the RA/SLAAC double
safeguard under Static Addressing, Router Advertisements, and IPAM).</t>
</section>
</section>

</back>

</rfc>
