What's new

ipv6 with controld stops working after about 2 hours

innov8ideas4u

Occasional Visitor
Ipv6 stops working after 2 hours , I have a gt axe 16000 , my telus gateway is in bridge mode to the router and I'm using controld for DoT . I have tried literally every setting possible on my router and endpoint and can not get ipv6 to keep working after approx 2 hours. I have tried the controld daemon , and manual settings , I even changed to DoH and the problem still was happening. If I change any setting in the ipv6 menu and save then it starts working again, but only for 2 hours. When I got to the syslog on webgui and go to ipv6 tab it will show that I have and address but the WAN gateway will be blank. I have tried cronjobs and DDNS and literally every setting that I can change. I have spent hours and hours talking with "barry" the controld ai but can not figure this out. Any help or ideas from anyone would be greatly appreciated! Thanks!
 
Sounds like your IPv6 address or route expired without getting renewed. Check in /tmp/wan0_bound6.env to see what lifetime numbers appear after the address or prefix.
 
Sounds like your IPv6 address or route expired without getting renewed. Check in /tmp/wan0_bound6.env to see what lifetime numbers appear after the address or prefix

PREFIXES=2001:56a:7854:d800::/56,7190,7490,class=0001b558
I'm not too sure how to interpret the contents of the file that well , I'm a student, still trying to learn linux , "barry" says this when I pasted the contents of the file to it

PREFIXES=2001:56a:7854:d800::/56,7190,7490,class=0001b558 <br>
Those 2 numbers after the prefix (7190, 7490) are likely the preferred lifetime and valid lifetime, both in seconds. That’s about 2 hours (7490 seconds ≈ 2 hours 5 min), matching your expiry window.
So, your router is handed a 2-hour IPv6 prefix from your ISP, and for some reason, it’s not getting renewed before expiry—thus, IPv6 breaks until you reapply settings and get a new lease.
The issue looks to be with how Telus delegates IPv6 over their bridged setup, not with Control D.
For further guidance, you’ll want to: See if your Merlin firmware has an option like “Enable DHCPv6 PD Renewal” or similar (sometimes via hidden nvram settings).

Thanks for your help with this! not having ipv6 isn't affecting me but more of personal mission to try and understand what the heck is going on with this and why I cant seem to fix it
 
I would suggest creating a Merlin custom script so you can see when the dhcp events occur. The script can be empty, it will still log the dhcp event in the system log.
Code:
echo "#!/bin/sh" > /jffs/scripts/dhcpc-event
chmod 750 /jffs/scripts/dhcpc-event
Make sure custom scripts are enabled in the firmware.

You can also enable IPv6 debugging with:
Code:
nvram set ipv6_debug=1
nvram commit
service restart_dhcp6c
 
I would suggest creating a Merlin custom script so you can see when the dhcp events occur. The script can be empty, it will still log the dhcp event in the system log.
Code:
echo "#!/bin/sh" > /jffs/scripts/dhcpc-event
chmod 750 /jffs/scripts/dhcpc-event
Make sure custom scripts are enabled in the firmware.

You can also enable IPv6 debugging with:
Code:
nvram set ipv6_debug=1
nvram commit
service restart_dhcp6c
I managed to figure out and fix it with the help of claude! I had a 4 hour long conversation with claude and now that its working I asked it to sum up what the issue was that I was having , it wrote this , and I asked it to sum of the fix that we did ( lol , it did, I just tried my best to understand what I was copy pasting into the terminal lol) Please let me know your thoughts on this and if this is a real fix or AI slop lol , its working for me though!

The bug:odhcp6c was dying before it ever got to the renewal point. We don't know exactly why it was dying — possible causes include:
  • A memory issue in this version of odhcp6c
  • A signal being sent to it by another Merlin process
  • A Merlin internal process inadvertently killing it during some background maintenance task

Root Cause:Merlin starts odhcp6c (the DHCPv6 client) correctly when the IPv6 GUI page is saved. However, odhcp6c was dying sometime before the lease renewal point (~2 hours). When it died, the IPv6 default route expired and nothing in Merlin automatically restarted it. There is no built-in watchdog for odhcp6c in Merlin firmware.
The Fix:A watchdog script at /jffs/scripts/ipv6-watchdog.sh that runs every 5 minutes via cron and checks three things:
  • Is odhcp6c running?
  • Does an IPv6 default route exist on eth0?
  • Does br0 have a global IPv6 address?
If any of these fail, it kills any stale odhcp6c process, cleans up the pidfile, and restarts odhcp6c with the exact command Merlin uses:
bash
odhcp6c -df -R -s /tmp/dhcp6c -N try -c 00030001a036bc71b554 -P 56:1b558 -r23 -r24 -k eth0
Key facts for others with this issue:
  • /tmp/dhcp6c is a symlink to /sbin/rc — Merlin's internal state-change handler, don't change this
  • The DUID (-c value) is unique to your router — get yours from ps output
  • No VLAN tagging needed on Telus FTTH if IPv4 is already working untagged
  • logread doesn't work on this router — no syslog buffer available
  • The watchdog is added to /jffs/scripts/services-start for reboot persistence
Telus uses DHCPv6 with prefix delegation to assign IPv6 to your router. The process works like this:
  1. odhcp6c starts and negotiates with Telus's DHCPv6 server
  2. Telus assigns a /56 prefix (2001:56a:785a:4c00::/56) and a lease with a ~2 hour lifetime
  3. Before the lease expires, odhcp6c is supposed to renew it
  4. When it renews, it also refreshes the IPv6 default route
 
Please let me know your thoughts on this
odhcp6c hasn’t been modified since 2019, so I doubt anything has changed there. Maybe your ISP sends junk packets. I still suggest enabling the debug and watching what happens and gets logged before your watchdog kicks in. How often is it restarting odhcp6c? Do you log when it actually takes action?

You don’t really need to run odhcp6c directly. Just have your script run service start_dhcp6c
 
The Fix:A watchdog script at /jffs/scripts/ipv6-watchdog.sh that runs every 5 minutes via cron and checks three things:
  • Is odhcp6c running?
  • Does an IPv6 default route exist on eth0?
  • Does br0 have a global IPv6 address?
If any of these fail, it kills any stale odhcp6c process, cleans up the pidfile, and restarts odhcp6c with the exact command Merlin uses:
bash
odhcp6c -df -R -s /tmp/dhcp6c -N try -c 00030001a036bc71b554 -P 56:1b558 -r23 -r24 -k eth0

So what is the contents of /jffs/scripts/ipv6-watchdog.sh ?
 
odhcp6c hasn’t been modified since 2019, so I doubt anything has changed there. Maybe your ISP sends junk packets. I still suggest enabling the debug and watching what happens and gets logged before your watchdog kicks in. How often is it restarting odhcp6c? Do you log when it actually takes action?

You don’t really need to run odhcp6c directly. Just have your script run service start_dhcp6c
Thanks ! when I pasted your reply to claude it said ,
Great response from dave14305 — he knows his stuff! Let's address each point:
On service start_dhcp6c:This is actually a better approach than running odhcp6c directly! It lets Merlin handle the startup properly rather than us manually invoking odhcp6c. We should update the watchdog to use this instead. Less likely to break if Merlin changes something internally.
On logging when it takes action:Good news — yes, the watchdog already logs restarts. From your log earlier:
<span><span>2026-02-27 12:00:00 ALERT: odhcp6c running but no IPv6 default route - restarting<br></span></span><span>2026-02-27 12:00:00 ACTION: Restarting odhcp6c...<br></span><span>2026-02-27 12:00:05 ACTION: odhcp6c restarted successfully (PID: 4081)</span>
So you can tell him it has restarted once so far.
On enabling debug logging:This is the key to finding the real root cause. He wants to know what odhcp6c sees before it dies — junk packets from Telus is a very plausible cause

How would I enable odhcp6c debug logging given that logread doesn't work on this router and /tmp is RAM based? Happy to capture what's happening before the watchdog kicks in if you can point me in the right direction
 
So what is the contents of /jffs/scripts/ipv6-watchdog.sh ?
# #!/bin/sh
# IPv6 Watchdog Script for Asus GT-AXE16000 / Merlin / Telus FTTH
# Monitors odhcp6c and IPv6 default route, restarts if either is dead
# Logs to /tmp/ipv6_watchdog.log

LOGFILE="/tmp/ipv6_watchdog.log"
PIDFILE="/var/run/odhcp6c.eth0.pid"
MAX_LOG_LINES=200

# The exact command Merlin uses to start odhcp6c - captured from ps output
# -d = daemonize (run in background)
# -f = don't send Client FQDN option
# -R = don't request any options except those specified with -r
# -s = script to call when state changes (/tmp/dhcp6c = symlink to /sbin/rc)
# -N try = request a new address but don't fail if server won't assign one
# -c = client DUID (your router's unique identifier to Telus)
# -P 56:1b558 = request a /56 prefix delegation, interface ID 1b558
# -r23 = request option 23 (DNS servers)
# -r24 = request option 24 (domain list)
# -k = don't send RELEASE when stopping
ODHCP6C_CMD="odhcp6c -df -R -s /tmp/dhcp6c -N try -c 00030001a036bc71b554 -P 56:1b558 -r23 -r24 -k eth0"

# Simple logging function - adds timestamp to every log line
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOGFILE"
}

# Keep log file from growing forever - trim to last MAX_LOG_LINES lines
trim_log() {
if [ -f "$LOGFILE" ]; then
lines=$(wc -l < "$LOGFILE")
if [ "$lines" -gt "$MAX_LOG_LINES" ]; then
tail -n "$MAX_LOG_LINES" "$LOGFILE" > "${LOGFILE}.tmp"
mv "${LOGFILE}.tmp" "$LOGFILE"
fi
fi
}

# Check if odhcp6c process is actually running
# Reads PID from pidfile, then checks if that PID exists in /proc/
is_odhcp6c_running() {
if [ ! -f "$PIDFILE" ]; then
return 1 # no pidfile = not running
fi
pid=$(cat "$PIDFILE" 2>/dev/null)
if [ -z "$pid" ]; then
return 1 # empty pidfile = not running
fi
if [ -f "/proc/${pid}/cmdline" ]; then
return 0 # PID exists in /proc/ = running
fi
return 1 # PID not in /proc/ = dead
}

# Check if a valid IPv6 default route exists via eth0
# This is what actually routes traffic to the internet
has_ipv6_default_route() {
ip -6 route show | grep -q "^default.*dev eth0"
}

# Check if br0 has a global (non-link-local) IPv6 address
# Link-local starts with fe80, global starts with 2001 etc
has_ipv6_global_addr() {
ip -6 addr show br0 | grep -q "scope global"
}

# Main restart function - kills any stale odhcp6c, cleans up, starts fresh
restart_ipv6() {
log "ACTION: Restarting odhcp6c..."

# Kill any existing odhcp6c processes (stale or zombie)
killall odhcp6c 2>/dev/null
sleep 2

# Clean up stale pidfile if it exists
rm -f "$PIDFILE"

# Start odhcp6c with the exact Merlin command
$ODHCP6C_CMD

# Wait a moment for it to start and write its pidfile
sleep 3

# Confirm it actually started
if is_odhcp6c_running; then
log "ACTION: odhcp6c restarted successfully (PID: $(cat $PIDFILE))"
else
log "ERROR: odhcp6c failed to start - manual intervention may be needed"
fi
}

# ---- MAIN LOGIC ----
trim_log

# Check odhcp6c process status
if ! is_odhcp6c_running; then
log "ALERT: odhcp6c is not running"
restart_ipv6
else
# odhcp6c is running, but also verify IPv6 is actually working
if ! has_ipv6_default_route; then
log "ALERT: odhcp6c running but no IPv6 default route - restarting"
restart_ipv6
elif ! has_ipv6_global_addr; then
log "ALERT: odhcp6c running but br0 has no global IPv6 address - restarting"
restart_ipv6
else
log "OK: IPv6 healthy - odhcp6c PID $(cat $PIDFILE), route and address present"
fi
fi
 
This is all very dystopian to me.
when I pasted your reply to claude it said ,
Great response from dave14305 — he knows his stuff!
Finally, the first sign of intelligence from AI!

You don’t need logread. You just need to view the system log in the GUI or look at the syslog.log files in /jffs.
 
This is all very dystopian to me.

Finally, the first sign of intelligence from AI!

You don’t need logread. You just need to view the system log in the GUI or look at the syslog.log files in /jffs.
This is incredibly revealing! Now we can see the actual root cause. Look at this sequence at 12:00:00:
<span><span>lldpd: removal request for address of 2001:56a:785c:d900::1%39, but no knowledge of it<br></span></span><span>dnsmasq-dhcp: router advertisement on 2001:56a:785c:d900::, old prefix for br0</span>

Merlin is killing and restarting odhcp6c itself at exactly 12:00:00! It's not a bug in odhcp6c — Merlin's own internal watchdog (rc_service) is triggering a DHCPv6 restart, probably on a 2-hour timer. Notice the new PID 4185 appearing at 12:00:06 — that's a brand new odhcp6c started by Merlin itself!
Also very interesting — look at this line:
<span><span>dhcp6_client: bound prefix 2001:56a:7851:ba00::/64</span></span>
That's a different prefix than what you normally get (2001:56a:785a:4200::/64). Telus is assigning a different prefix on each renewal — that's normal, but Merlin might not be handling the prefix change cleanly.
The good news: Your watchdog caught it and fixed it at 12:00. The better news: This gives you great info to post back to dave14305.
Post this to the forum and ask him — is Merlin triggering this restart itself on a 2-hour cycle, and why isn't the built-in restart handling it cleanly without the watchdog?
 
@innov8ideas4u Can you please make clear what parts of your posts are your own thoughts/observations and which parts you're quoting from AI (and what it was responding to). It's very confusing.
 
for some reason when i try to post the logs it keeps saying "ran into some problems"
There's likely some banned text related to hosts files in the log. Upload to pastebin or some other site like that and share the link.

Another option instead of restarting odhcp6c is just force a renew if it's still alive with killall -SIGUSR1 odhcp6c.
 
I'm just going to summarize what I would be doing next. Hopefully the bot agrees with me.

This will enable odhcp6c debugging and prevent the release of the prefix after a restart.
Code:
nvram set ipv6_debug=1
nvram set ipv6_dhcp6c_release=0
nvram commit
service restart_dhcp6c
See what's immediately in the syslog upon it starting up and requesting an address:
Code:
grep odhcp6c /jffs/syslog.log

Install tcpdump from Entware to capture the DHCPv6 conversation with the ISP:
Code:
opkg update
opkg install tcpdump
tcpdump -nvpei eth0 udp and port 547

In another SSH window, force a renewal:
Code:
killall -SIGUSR1 odhcp6c

Review the tcpdump session in the previous window to see how the ISP is responding. Keep it running when the next renewal is approaching and capture the results.
 
I'm just going to summarize what I would be doing next. Hopefully the bot agrees with me.

This will enable odhcp6c debugging and prevent the release of the prefix after a restart.
Code:
nvram set ipv6_debug=1
nvram set ipv6_dhcp6c_release=0
nvram commit
service restart_dhcp6c
See what's immediately in the syslog upon it starting up and requesting an address:
Code:
grep odhcp6c /jffs/syslog.log

Install tcpdump from Entware to capture the DHCPv6 conversation with the ISP:
Code:
opkg update
opkg install tcpdump
tcpdump -nvpei eth0 udp and port 547

In another SSH window, force a renewal:
Code:
killall -SIGUSR1 odhcp6c

Review the tcpdump session in the previous window to see how the ISP is responding. Keep it running when the next renewal is approaching and capture the results.
LMFAO Claude "That's an excellent plan and dave14305 clearly knows exactly what he's doing! I agree with all of it!" "Overall — dave's approach is going to get us to the true root cause rather than just working around it. The watchdog is still a good safety net either way! 😄" I will try everything you just said to do later this evening when I have a few mins of time! Thanks so much for your help with this, I have learned so much and am really looking forward to starting CCNA course next month! I just finished the (stupid and frustrating) compTIA courses with 98.15% , highest mark my teacher has ever seen. I really love this router and hope that this will be a helping contribution anyone else that was having this issue!
 
Merlin is killing and restarting odhcp6c itself at exactly 12:00:00! It's not a bug in odhcp6c — Merlin's own internal watchdog (rc_service) is triggering a DHCPv6 restart, probably on a 2-hour timer. Notice the new PID 4185 appearing at 12:00:06 — that's a brand new odhcp6c started by Merlin itself!
I'd still like to see what logs triggered this "finding".
 

Similar threads

Latest threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Back
Top