How to Configure OSPFv3 for IPv6 on Cisco IOS
OSPFv3 is not OSPFv2 with IPv6 addresses pasted in. There is no network statement — you enable the protocol on each interface — the router ID is still a 32-bit dotted quad that you usually have to type yourself, and every next hop you verify will be a link-local FE80:: address. Those three differences account for most of the time people lose here, and none of them are obvious if you learned OSPF on IPv4. This guide configures OSPFv3 in area 0 on Cisco IOS, verifies it, steers a path with cost, and names the faults that look like nothing is wrong. It assumes single-area OSPFv2 already makes sense to you.
Practice on hands-on CCNA & CCNP labs.
What does not carry over from OSPFv2
Most of OSPF is unchanged. Areas, the backbone, cost, SPF, LSA flooding, DR and BDR election on a broadcast segment, the 10-second hello and 40-second dead interval on Ethernet, the MTU check during database exchange, and every neighbor state from DOWN to FULL all behave exactly as they do on IPv4. What changed is how you turn it on, what it rides on, and what you read back.
The table below is the short version. If you only remember two rows, make them the first two: OSPFv3 does not come up until ipv6 unicast-routing is on, and nothing under the process selects interfaces.
| Same job | OSPFv2 (IPv4) | OSPFv3 (IPv6) |
|---|---|---|
| Global prerequisite | IP routing is on by default on a router, so there is nothing to enable — a Layer 3 switch still needs ip routing | ipv6 unicast-routing must be configured first — without it OSPFv3 never forms an adjacency, and on the lab images IOS refuses the commands as you type them |
| Enabling it on a link | network <address> <wildcard> area <n> under the process, matched against interface addresses | ipv6 ospf <pid> area <n> on the interface itself. There is no network statement at all |
| Router ID | 32-bit dotted quad, taken from the highest loopback or highest active interface address | Still a 32-bit dotted quad, but an IPv6-only router has no IPv4 address to take one from, so you set it |
| Packet source and next hop | The interface's IPv4 address, which is what the neighbor table and routing table print | The interface's link-local address, so hellos are sourced from FE80:: and every route learned across the link takes an FE80:: next hop |
| Multicast destinations | 224.0.0.5 for all OSPF routers, 224.0.0.6 for DR and BDR | FF02::5 and FF02::6, carried in IPv6 next header 89 |
| What the adjacency is built on | The subnet: hellos carry a network mask, and a mismatch stops the adjacency on broadcast links | The link: there is no mask check, so two routers with different /64s still become neighbors |
| Authentication | ip ospf authentication message-digest plus ip ospf message-digest-key per interface | Those commands do not apply. OSPFv3 delegated authentication to IPsec; newer IOS-XE adds an authentication trailer under ospfv3 authentication |
| Address families per process | IPv4 only | One process carries IPv6, and on the address-family syntax it can carry IPv4 as well |
Step 1 — Turn on IPv6 routing before anything else
IPv6 forwarding is off by default on IOS. ipv6 unicast-routing switches it on, and it is a global command you type once per router. Leave it out and the router still accepts IPv6 addresses on interfaces and still answers a ping on its own link, but OSPFv3 never comes up. On the images these labs run on it does not get as far as a config: ipv6 router ospf 1 is rejected with % IPv6 routing not enabled, and ipv6 ospf 1 area 0 on an interface is rejected with % OSPFv3: IPv6 routing not enabled. Because those lines are refused as you enter them, none of them reach the running config, and every line that depends on the process — router-id, passive-interface, auto-cost reference-bandwidth — fails behind it. Type this one command before you touch OSPFv3 and the rest of the build lands.
Address the links next. Each interface that will run OSPFv3 needs to be up and to have IPv6 enabled on it; a global unicast address does that implicitly, and ipv6 enable does it on a transit link you do not want to number. See IPv6 addressing on Cisco IOS for the addressing itself, including EUI-64 and manual link-locals.
R1(config)# ipv6 unicast-routing
R1(config)# interface GigabitEthernet0/0
R1(config-if)# ipv6 address 2001:db8:acad:12::1/64
R1(config-if)# no shutdown
R1(config-if)# exit
R1(config)# interface GigabitEthernet0/1
R1(config-if)# ipv6 address 2001:db8:acad:10::1/64
R1(config-if)# no shutdownIPv6 forwarding first, then an address on the transit link and the LAN.
Step 2 — Start the process and set the router ID by hand
OSPFv3 identifies routers exactly as OSPFv2 does: a 32-bit value written as a dotted quad. That did not change with the protocol version, and it is not an IPv6 address. IOS derives one from the highest IPv4 address on a loopback, or failing that the highest IPv4 address on an active interface.
On an IPv6-only router there is nothing to derive it from. The process cannot allocate an ID, so it does not start, and IOS tells you it could not pick one. Nothing in the neighbor table is wrong — there is no process to have a neighbor table. Set router-id explicitly on every router whether or not IPv4 exists: it survives interface changes, it makes the LSDB readable, and it removes an entire class of failure from a build.
Use the process for the settings that are genuinely process-wide — the router ID, passive interfaces, the reference bandwidth, summarization on an ABR. Interface membership is not one of them.
R1(config)# ipv6 router ospf 1
R1(config-rtr)# router-id 1.1.1.1
R1(config-rtr)# passive-interface GigabitEthernet0/1
R1(config-rtr)# exitThe process, an explicit router ID, and the LAN interface kept quiet.
Two syntaxes do the same thing
Classic IOS uses ipv6 router ospf <pid> with ipv6 ospf <pid> area <n> on interfaces. Newer IOS-XE also offers the address-family form: router ospfv3 <pid>, then address-family ipv6 unicast, with ospfv3 <pid> ipv6 area <n> on interfaces. It is the same protocol and the same process; the address-family form exists so one OSPFv3 process can also carry IPv4.
Current IOS-XE images accept both forms, so pick one per router and stay with it. Use both on one device and what lands in the running config may not be the text you typed. Read the config back after you configure and troubleshoot against what the device stored — that is also what a grader reads. CCNA material and the graded labs on this site use the classic form, and this guide follows it.
Step 3 — Enable OSPFv3 on each interface
This is the step OSPFv2 habits break. Nothing under the OSPFv3 process selects interfaces, so there is nothing to get a wildcard mask wrong in. You go to each interface and enable the protocol there, naming the process and the area in one command.
The area is a property of the interface, which makes an area border router exactly what the name says: a router with interfaces in two areas, one of them area 0. The process ID stays local to the router, as it is in OSPFv2, so R1 can run process 1 while R2 runs process 20 and they will still be neighbors.
An interface without that line is not in OSPF, no matter how neatly its prefix fits the addressing plan. On a transit link that means no adjacency; on a LAN it means the /64 is never advertised and the rest of the network has no route to it. Neighbors up but routes missing almost always ends here.
- Both ends of a transit link need it, in the same area, or no adjacency forms.
- LAN interfaces need it too — that is how their prefix gets into the database. Pair it with
passive-interfaceso no hellos go out toward the hosts. - A link with only a link-local address works: run
ipv6 enableon it and OSPFv3 has everything it needs. - The instance ID defaults to 0 and must match.
ipv6 ospf 1 area 0 instance 1on one end only means no neighbor, with nothing else in the config looking wrong.
R1(config)# interface GigabitEthernet0/0
R1(config-if)# ipv6 ospf 1 area 0
R1(config-if)# exit
R1(config)# interface GigabitEthernet0/1
R1(config-if)# ipv6 ospf 1 area 0
R1(config-if)# endPer-interface activation — the replacement for every network statement you would have typed.
Step 4 — Verify, and expect FE80:: everywhere
Adjacency forms over link-local addresses. Both routers source their hellos from FE80::/10 addresses on the link, so the global prefixes play no part in bringing the neighbor up, and the next hop installed for every route learned across that link is the neighbor's link-local address. That looks wrong the first time and is entirely normal: a link-local address is unique only on its own link, which is all a next hop ever has to be, and it stays valid even when the link's global prefix is renumbered. Link-local versus global unicast covers the address types; RFC 5340 is the protocol specification.
show ipv6 ospf neighbor differs from its IPv4 counterpart in one column, and it trips people up. Where OSPFv2 prints the neighbor's address, OSPFv3 prints an Interface ID — the neighbor's own numeric identifier for its side of the link. To see the link-local address, add detail. The states are the same ones as v2, and FULL means the same thing.
Work outward from there. show ipv6 ospf interface brief lists which interfaces are actually in the process, with their area and cost, and is the fastest way to catch an interface you forgot to enable. show ipv6 route ospf proves prefixes are being learned. Then test from the hosts with ping and traceroute, because a routing table that looks right and a LAN that does not work is usually a gateway or a prefix-length problem on the host, not an OSPF problem.
R1# show ipv6 ospf neighbor
Neighbor ID Pri State Dead Time Interface ID Interface
2.2.2.2 1 FULL/BDR 00:00:33 4 GigabitEthernet0/0
R1# show ipv6 route ospf
O 2001:DB8:ACAD:20::/64 [110/2]
via FE80::2, GigabitEthernet0/0Illustrative, not a capture: the shape of a healthy OSPFv3 adjacency and a route learned across it.
Cost and path choice across multiple routers
Costing is identical to OSPFv2. Each interface gets a cost of reference bandwidth divided by interface bandwidth, with a minimum of 1, and the default reference bandwidth is 100 Mbps. That default is the usual trap on modern topologies: every gigabit and faster interface lands on cost 1, so a gigabit path and a ten-gigabit path score the same. Raise it with auto-cost reference-bandwidth under the process, and set the same value on every router in the domain — a mismatch means two routers score the same topology differently.
Override a single interface with ipv6 ospf cost <1-65535>, which ignores the bandwidth calculation entirely. Two rules decide whether your override actually does anything. First, cost is applied to traffic leaving an interface, so set it on the outbound interface of the router making the decision; setting it at the far end changes a path you are not looking at. Second, the total cost of every outbound interface along a route is what competes, so compare whole paths rather than single links.
A tie is not a steer. If your adjusted path totals the same as the path you meant to avoid, OSPF installs both as equal-cost multipath and traffic uses both, which reads as though the change did nothing. Make the intended path strictly cheaper. After a change, read the cost OSPF is actually using on the interface with show ipv6 ospf interface, then re-read the routing table once SPF has run.
R1(config)# interface GigabitEthernet0/0
R1(config-if)# ipv6 ospf cost 30
R1(config-if)# exit
R1(config)# ipv6 router ospf 1
R1(config-rtr)# auto-cost reference-bandwidth 10000An interface cost that overrides the bandwidth calculation, and the reference bandwidth that must match domain-wide.
Authentication: the OSPFv2 commands do not apply
ip ospf authentication message-digest and ip ospf message-digest-key are OSPFv2 commands and do not apply to OSPFv3. OSPFv3 originally delegated authentication to IPsec — AH or ESP configured per interface or per area — rather than carrying its own authentication field. Newer IOS-XE also supports the OSPFv3 authentication trailer from RFC 7166, configured with the ospfv3 authentication command.
The practical point for a lab or an exam: do not reuse the IPv4 message-digest syntax on an IPv6 interface and assume the adjacency is protected. A command the CLI takes is not necessarily one that is doing anything for OSPFv3. Check what your image supports before you design around it.
Common problems (and the fix)
Work down the list in order — each check is cheaper than the one after it. Read the running config first: the top fault is the one where the lines you typed are not in it, and every fault under it produces a config that reads correctly.
- None of your OSPFv3 lines are in the running config.
ipv6 unicast-routingwas missing when you typed them, so IOS rejected each one as it was entered. Add it globally, then re-enter the OSPFv3 configuration — turning on forwarding afterwards does not restore lines the router never accepted. - The process will not start. No router ID, on a router with no IPv4 address to borrow one from. Set
router-idunder the process. If the process was already running when you changed it, clear it withclear ipv6 ospf processso the new ID takes effect. - Neighbor is FULL, but a prefix is missing. The interface that owns the prefix was never enabled for OSPFv3, or it is shut.
show ipv6 ospf interface brieflists what is really in the process; compare that against your addressing plan, not against your intentions. - Stuck in EXSTART or EXCHANGE. The hellos match and the database exchange is failing, which on OSPFv3 means the same MTU check as OSPFv2. Compare the IPv6 MTU on both interfaces and make them equal. The wider symptom-by-state method in OSPF neighbor not forming applies unchanged.
- No neighbor on one interface while the rest of the router is fine. Area or instance ID mismatch. Both are set on the interface line in OSPFv3, so compare interface configs rather than process configs.
- Hosts get an address but reach nothing. The address itself proves router advertisements are arriving, so the gateway and the LAN link-local are fine — look past them. Either the LAN interface was never enabled for OSPFv3, so nothing outside has a route back, or an IPv6 ACL on it ends in an explicit deny. IOS permits neighbor discovery implicitly ahead of an IPv6 ACL's implicit deny, so a plain list does not break ND — but an explicit
deny ipv6 any anyat the end overrides those permits and stops address resolution on the segment, which looks like a routing fault and is not one. - The path did not move after a cost change. The cost went on the wrong end, or the two paths now total the same and both are installed. Recompute the totals and make the winner strictly cheaper.
Build it once, then build it again under grading
OSPFv3 is short enough to configure from memory after two or three passes, which is exactly why it is worth doing under a grader that reads your running config rather than your intent. The OSPFv3 labs below run on real Cisco IOS in CML: one forms an adjacency over link-local between two routers, one adds a third router and makes you steer the IPv6 path with cost, and the capstone puts OSPFv3 into a dual-stack site alongside SLAAC, stateless DHCPv6 and an IPv6 ACL.
Configure them without a walkthrough, then upload the config and read which checks failed. Start that reading with the two faults this guide opened with: IPv6 routing left off, and an interface never enabled for OSPFv3.
Frequently asked questions
Does OSPFv3 use network statements like OSPFv2?
No. OSPFv3 has no network command. You enable it on each interface with 'ipv6 ospf <process-id> area <area-id>', which names both the process and the area in one line. Nothing under the router process selects interfaces, so an interface without that command is not running OSPF regardless of what address it carries. This is the most common carry-over error from OSPFv2.
Why does OSPFv3 still need a 32-bit router ID on an IPv6-only network?
The router ID identifies a router inside the link-state database and it stayed 32 bits when the protocol moved to IPv6, so it is written as a dotted quad even though no IPv4 is involved. IOS normally derives one from the highest loopback or active interface IPv4 address. On an IPv6-only router there is none to derive, the process cannot allocate an ID, and it will not start until you configure router-id under the process.
Why are all my OSPFv3 next hops FE80:: addresses?
Because OSPFv3 adjacencies form over link-local addresses. Both routers source their hellos from the link-local address on the link, so the next hop installed for routes learned across it is the neighbor's link-local address, not its global one. This is correct behavior, not a fault. A link-local address only has to be unique on its own link, and it keeps working if the link's global prefix is renumbered.
Can one router run OSPFv2 and OSPFv3 at the same time?
Yes, and on a dual-stack network that is normal. They are separate processes with separate databases and separate neighbor tables: OSPFv2 carries IPv4 routes and OSPFv3 carries IPv6 routes, over the same physical links. Verify them separately with show ip ospf neighbor and show ipv6 ospf neighbor, because one can be perfectly healthy while the other is down.
Do the OSPF MD5 authentication commands work for OSPFv3?
No. The OSPFv2 commands ip ospf message-digest-key and ip ospf authentication do not apply to OSPFv3, which originally delegated authentication to IPsec using AH or ESP per interface or per area. Newer IOS-XE also supports the OSPFv3 authentication trailer from RFC 7166 through the ospfv3 authentication command, but the IPv4 message-digest syntax cannot be reused for IPv6.
Graded OSPFv3 labs
Configure OSPFv3 on real Cisco IOS in CML, then upload the config for a grade.
Practice on real Cisco IOS
Build it on real Cisco IOS and get instant pass/fail grading on your own config.