{"id":6128,"date":"2026-09-02T20:40:10","date_gmt":"2026-09-02T11:40:10","guid":{"rendered":"https:\/\/eternalsphere.net\/echoes\/?p=6128"},"modified":"2026-09-12T17:17:03","modified_gmt":"2026-09-12T08:17:03","slug":"9s59gbb57e4qpck","status":"publish","type":"post","link":"https:\/\/blog.eternalsphere.net\/index.php\/2026\/09\/02\/9s59gbb57e4qpck\/","title":{"rendered":"Post-Upgrade OpenWrt Audit and Clean IPv4-Only Configuration"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An OpenWrt upgrade can complete successfully while still leaving behind configuration warnings, transitional IPv6 state, or service messages that appear more serious than they actually are.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A useful post-upgrade review should therefore answer two separate questions:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Is the router operationally healthy?<\/li>\n\n\n\n<li>Does the current configuration still reflect the intended network design?<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">This distinction matters especially on networks where the ISP does not provide IPv6 and all local devices are intentionally operated over IPv4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The example environment used throughout this article is deliberately generic:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Router LAN:     192.168.10.1\nPVE host:       192.168.10.10\nPBS host:       192.168.10.20\nLAN subnet:     192.168.10.0\/24<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">All names, addresses, identifiers, domains, and other deployment-specific details are sanitized.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Start With a Read-Only Audit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A post-upgrade audit should begin without changing anything.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Useful commands include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/etc\/openwrt_release\nuname -a\nuptime\nfree\ndf -h\nip -br addr\nip route\nip -6 route\nlogread\ndmesg\nservice list<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Important areas to review include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>kernel version;<\/li>\n\n\n\n<li>uptime and boot history;<\/li>\n\n\n\n<li>memory and flash usage;<\/li>\n\n\n\n<li>DHCP service;<\/li>\n\n\n\n<li>DNS service;<\/li>\n\n\n\n<li>firewall4\/nftables;<\/li>\n\n\n\n<li>WAN state;<\/li>\n\n\n\n<li>LAN bridge state;<\/li>\n\n\n\n<li>PPPoE state if used;<\/li>\n\n\n\n<li>static DHCP mappings;<\/li>\n\n\n\n<li>port-forwarding rules;<\/li>\n\n\n\n<li>service failures;<\/li>\n\n\n\n<li>kernel panic or OOM evidence;<\/li>\n\n\n\n<li>repeated interface resets.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">A healthy router may still contain warnings. The goal is not an empty log. The goal is to distinguish harmless warnings from active faults.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Common IPv6 Warning on an IPv4-Only Network<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A common message is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>odhcpd: No default route present, setting ra_lifetime to 0!<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This message frequently appears when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>LAN IPv6 services remain enabled;<\/li>\n\n\n\n<li>the WAN has no usable IPv6 default route;<\/li>\n\n\n\n<li>the router still attempts to generate Router Advertisements.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The message does not mean IPv4 routing is broken.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It means the router cannot advertise itself as a valid IPv6 default gateway.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the ISP provides no IPv6 and IPv6 is not needed on the LAN, the configuration should reflect that design explicitly.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Disable Unused IPv6 Distribution on LAN<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For an intentionally IPv4-only LAN, disable:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>IPv6 assignment on LAN;<\/li>\n\n\n\n<li>Router Advertisement;<\/li>\n\n\n\n<li>DHCPv6;<\/li>\n\n\n\n<li>NDP proxy.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The resulting UCI configuration should contain no LAN <code>ip6assign<\/code> entry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uci show network.lan<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected form:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>network.lan=interface\nnetwork.lan.device='br-lan'\nnetwork.lan.proto='static'\nnetwork.lan.ipaddr='192.168.10.1'\nnetwork.lan.netmask='255.255.255.0'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The DHCP section should remain IPv4-only:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uci show dhcp.lan<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dhcp.lan=dhcp\ndhcp.lan.interface='lan'\ndhcp.lan.start='100'\ndhcp.lan.limit='150'\ndhcp.lan.leasetime='12h'\ndhcp.lan.dhcpv4='server'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If WAN6 is unused, keeping it explicitly disabled is appropriate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>network.wan6.disabled='1'<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Remove an Unused ULA Prefix<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">OpenWrt often generates a ULA prefix automatically:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fdxx:xxxx:xxxx::\/48<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It can be inspected with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uci show network.globals<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>network.globals=globals\nnetwork.globals.ula_prefix='fd12:3456:789a::\/48'\nnetwork.globals.packet_steering='1'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When LAN IPv6 assignment has already been disabled, the remaining ULA prefix may produce:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>You have delegated IPv6-prefixes but haven't assigned them to any interface.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For a deliberately IPv4-only network, removing the unused ULA prefix is reasonable:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uci delete network.globals.ula_prefix\nuci commit network\n\/etc\/init.d\/network reload<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Only the unused ULA prefix should be removed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Other global settings such as packet steering or default DUID should remain untouched unless there is a separate reason to change them.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Why Old IPv6 Addresses May Remain Temporarily<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After IPv6 is disabled, a command such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ip -6 addr show dev br-lan<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">may still show an old ULA address:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>inet6 fd12:3456:789a::1\/60 scope global deprecated dynamic\nvalid_lft 6900sec preferred_lft 0sec<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is normal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The important fields are:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>deprecated\npreferred_lft 0sec<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The address is no longer preferred for new connections.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A non-zero <code>valid_lft<\/code> means the kernel is retaining it temporarily so existing state is not destroyed abruptly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The corresponding route may also remain:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fd12:3456:789a::\/60 dev br-lan<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It disappears naturally when the valid lifetime expires.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No manual route deletion is necessary.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">6. DHCPv6 Leases Can Also Remain Temporarily<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The LuCI status page may continue showing old DHCPv6 leases after DHCPv6 has been disabled.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These entries are historical state with remaining lease lifetimes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">They should disappear naturally.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The important test is whether <strong>new<\/strong> IPv6 leases continue to appear after the old lifetimes have expired.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If no new leases appear, the IPv6 cleanup is working correctly.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Link-Local IPv6 Should Remain<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Even on an IPv4-only operational network, interfaces may still show:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fe80::\/64<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These are IPv6 link-local addresses.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Their presence does not mean DHCPv6, Router Advertisement, or public IPv6 routing is active.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is normally no reason to disable the IPv6 stack globally or remove link-local addressing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Global kernel-level IPv6 disabling is unnecessary for most OpenWrt installations and creates additional maintenance complexity.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Interpreting Other Upgrade Warnings<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Several warnings often appear during boot without indicating a fault.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Examples include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Not supported (-95)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">during wireless initialization, or:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>possible DNS-rebind attack detected<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">from dnsmasq.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first may simply indicate a driver feature probe that is not supported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The second generally means DNS rebind protection successfully blocked a suspicious or inappropriate DNS response.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Context matters more than keywords.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A message containing <code>warning<\/code>, <code>failed<\/code>, or <code>error<\/code> is not automatically an operational failure.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">9. Final IPv4-Only State<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A clean IPv4-only OpenWrt configuration should look conceptually like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ISP\n |\n | IPv4 \/ PPPoE\n |\nWAN\n |\nOpenWrt\n |\nLAN 192.168.10.1\/24\n |\nIPv4 clients<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected state:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>WAN6                         disabled\nLAN IPv6 assignment         disabled\nRouter Advertisement        disabled\nDHCPv6                      disabled\nNDP proxy                   disabled\nGlobal ULA prefix           absent\nIPv4 DHCP                   enabled\nIPv4 NAT                    enabled\nIPv4 forwarding             enabled<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The router may still retain <code>fe80::<\/code> link-local addresses.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is normal.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A successful OpenWrt upgrade does not require removing every IPv6-related package or suppressing every warning.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A better approach is to make the configuration accurately reflect the intended network design.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For an IPv4-only deployment:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>disable unused IPv6 distribution;<\/li>\n\n\n\n<li>remove the unused ULA prefix;<\/li>\n\n\n\n<li>retain the standard IPv6 stack;<\/li>\n\n\n\n<li>allow deprecated addresses and leases to expire naturally;<\/li>\n\n\n\n<li>verify firewall, DHCP, DNS, NAT, and routing independently.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The result is a cleaner configuration with fewer misleading warnings and no unnecessary kernel-level modifications.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction An OpenWrt upgrade can complete successfully while still leaving behind configuration warnings, transitional IPv6 state, or service messages that appear more serious than they actually are. A useful post-upgrade review should therefore answer two separate questions: This distinction matters especially on networks where the ISP does not provide IPv6 &hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[120],"tags":[334],"class_list":["post-6128","post","type-post","status-publish","format-standard","hentry","category-1s3b6h7r2zay02x","tag-routers"],"_links":{"self":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts\/6128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/comments?post=6128"}],"version-history":[{"count":1,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts\/6128\/revisions"}],"predecessor-version":[{"id":6129,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts\/6128\/revisions\/6129"}],"wp:attachment":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/media?parent=6128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/categories?post=6128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/tags?post=6128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}