dhcp6c on ddwrt cannot get new IPv6 routing prefix after PPPoE reconnectThis does not always happen, but rather probabilistic.
I suspect that dhcp6c
crashes (or more likely, killed by ddwrt) after PPPoE reconnect, but somehow leaves radvd
alive.
It seems that dhcp6c
accidentally not marking its listening socket on port 546 (DHCPv6 client) as SOCK_CLOEXEC
, and is inherited by radvd
.
As radvd
is not killed, and inherits dhcp6c
‘s listening socket on 546, the newly started (after PPPoE reconnect) dhcp6c
cannot get messages, including DHCP6/PD response, from port 546. netstat
confirms this:
123456 # netstat -np --udp --listenActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name[...]udp 0 0 :::546 :::* 123/radvd[...]
Usually, 546 should be listened by dhcp6c
:
123456 # netstat -np --udp --listenActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name[...]udp 0 0 :::546 :::* 111/dhcp6c[...]
So I wrote a script which manually kill all radvd
and dhcp6c
instances, and restart dhcp6c
manually after sleeping 1 seconds (so that they have really exited.):
12345678910111213141516171819202122232425 #!/usr/bin/env bashset -e # Indeed this is NOT a firewall rule.## It seems that dhcp6c (with a chance) fails to obtain new IPv6 prefix after PPPoE# reconnect.## I'm not sure why it is but it seems that after PPPoE reconnect radvd (rather# than dhcp6c) is listening on port 546 (DHCPv6 client), thus dhcp6c cannot# receive DHCPv6 server's response.## Not sure if this is the same as https://unix.stackexchange.com/questions/127407## It seems to me that dhcp6c was actually dead for some reason, and left it's# child radvd alive, who incidentally inherit its fd listening on 546. And after# dhcp6c restart (if at all), it can no longer receive DHCPv6 announcement.## As firewall scripts are run every time PPPoE is reconnected, we kill radvd and# restart dhcp6c here. killall -9 radvdkillall -9 dhcp6csleep 1dhcp6c -c /tmp/dhcp6c.conf -T LL ppp0
I added this script to ddwrt’s firewall command.
Not sure if this helps, though. It still needs more observation.
This does not always happen, but rather probabilistic.
I suspect that dhcp6c
crashes (or more likely, killed by ddwrt) after PPPoE reconnect, but somehow leaves radvd
alive.
It seems that dhcp6c
accidentally not marking its listening socket on port 546 (DHCPv6 client) as SOCK_CLOEXEC
, and is inherited by radvd
.
As radvd
is not killed, and inherits dhcp6c
‘s listening socket on 546, the newly started (after PPPoE reconnect) dhcp6c
cannot get messages, including DHCP6/PD response, from port 546. netstat
confirms this:
1 2 3 4 5 6 | # netstat -np --udp --listen Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name [...] udp 0 0 :::546 :::* 123/radvd [...] |
Usually, 546 should be listened by dhcp6c
:
1 2 3 4 5 6 | # netstat -np --udp --listen Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name [...] udp 0 0 :::546 :::* 111/dhcp6c [...] |
So I wrote a script which manually kill all radvd
and dhcp6c
instances, and restart dhcp6c
manually after sleeping 1 seconds (so that they have really exited.):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #!/usr/bin/env bash set -e # Indeed this is NOT a firewall rule. # # It seems that dhcp6c (with a chance) fails to obtain new IPv6 prefix after PPPoE # reconnect. # # I'm not sure why it is but it seems that after PPPoE reconnect radvd (rather # than dhcp6c) is listening on port 546 (DHCPv6 client), thus dhcp6c cannot # receive DHCPv6 server's response. # # Not sure if this is the same as https://unix.stackexchange.com/questions/127407 # # It seems to me that dhcp6c was actually dead for some reason, and left it's # child radvd alive, who incidentally inherit its fd listening on 546. And after # dhcp6c restart (if at all), it can no longer receive DHCPv6 announcement. # # As firewall scripts are run every time PPPoE is reconnected, we kill radvd and # restart dhcp6c here. killall -9 radvd killall -9 dhcp6c sleep 1 dhcp6c -c /tmp/dhcp6c.conf -T LL ppp0 |
I added this script to ddwrt’s firewall command.
Not sure if this helps, though. It still needs more observation.