3030# This script manipulates DHCPv6-PD-REF configuration.
3131#
3232
33- # TODO: set the upstream interface according to the environment variables of `script/setup`.
34- UPSTREAM_INTERFACE=" eth0"
35- WPAN_INTERFACE=" wpan0"
33+ INFRA_IF=" ${INFRA_IF_NAME:- eth0} "
34+ THREAD_IF=" wpan0"
3635LARGE_METRIC=" 2048" # A high metric value for loopback to make its routes less preferred.
3736
3837DHCPCD_ENTER_HOOK=" /etc/dhcpcd.enter-hook"
3938DHCPCD_EXIT_HOOK=" /etc/dhcpcd.exit-hook"
4039
40+ RADVD_CONF=" /etc/radvd.conf"
41+
4142PD_DAEMON_DIR=" /opt/pd-daemon"
4243PD_DAEMON_PATH=" ${PD_DAEMON_DIR} /dhcp6_pd_daemon.py"
4344PD_DAEMON_SERVICE_NAME=" dhcp6_pd_daemon.service"
@@ -57,14 +58,14 @@ noipv6rs # disable router solicitation
5758# default reject route for unassigned delegated prefixes on loopback interface,
5859# are less preferred.
5960# OpenThread will later install an active route for the delegated prefix on
60- # ${WPAN_INTERFACE } with a standard (lower) metric, ensuring it takes precedence.
61+ # ${THREAD_IF } with a standard (lower) metric, ensuring it takes precedence.
6162interface lo
6263 metric ${LARGE_METRIC}
63- interface ${UPSTREAM_INTERFACE }
64+ interface ${INFRA_IF }
6465 iaid 1
6566 ia_pd 2/::/64
6667release
67- # Disable Router Solicitations (RS) again, specifically for ${UPSTREAM_INTERFACE } .
68+ # Disable Router Solicitations (RS) again, specifically for ${INFRA_IF } .
6869# This ensures that accept_ra is prevented from being set to 0, allowing
6970# the interface to accepting Router Advertisements and configuring IPv6
7071# based on them. The exact reason for requiring 'noipv6rs' twice
@@ -82,6 +83,156 @@ noipv6rs # disable router solicitation
8283EOF
8384}
8485
86+ create_dhcpcd_enter_hook ()
87+ {
88+
89+ sudo tee ${DHCPCD_ENTER_HOOK} > /dev/null << EOF
90+ #!/bin/bash
91+
92+ INFRA_IF="${INFRA_IF} "
93+ THREAD_IF="${THREAD_IF} "
94+
95+ RADVD_CONF="${RADVD_CONF} "
96+ LOG_TAG="dhcpcd.enter.hook:"
97+
98+ EOF
99+
100+ sudo tee -a ${DHCPCD_ENTER_HOOK} > /dev/null << 'EOF '
101+ config_ra()
102+ {
103+ local old_prefix="$1"
104+ local old_prefix_len="$2"
105+ local new_prefix="$3"
106+ local new_prefix_len="$4"
107+ local new_pltime="$5"
108+ local new_vltime="$6"
109+
110+ local deprecate_old_prefix=false
111+ if [ -n "$old_prefix" ] && [ "$old_prefix/$old_prefix_len" != "$new_prefix/$new_prefix_len" ]; then
112+ deprecate_old_prefix=true
113+ fi
114+
115+ local publish_new_prefix=false
116+ if [ -n "$new_prefix" ] && [ -n "$new_prefix_len" ] && [ -n "$new_pltime" ] && [ -n "$new_vltime" ]; then
117+ publish_new_prefix=true
118+ fi
119+
120+ logger "$LOG_TAG $reason start config radvd"
121+
122+ sudo tee "${RADVD_CONF}" > /dev/null <<EEOOFF
123+ interface ${THREAD_IF}
124+ {
125+ IgnoreIfMissing on;
126+ AdvSendAdvert on;
127+ EEOOFF
128+
129+ if $deprecate_old_prefix; then
130+ logger "$LOG_TAG Deprecating old prefix $old_prefix/$old_prefix_len"
131+ sudo tee -a "${RADVD_CONF}" > /dev/null <<EEOOFF
132+ prefix "$old_prefix"/"$old_prefix_len"
133+ {
134+ AdvOnLink on;
135+ AdvAutonomous on;
136+ AdvRouterAddr off;
137+ AdvPreferredLifetime 0;
138+ AdvValidLifetime 0;
139+ };
140+ EEOOFF
141+ fi
142+
143+ if $publish_new_prefix; then
144+ logger "$LOG_TAG Publishing new prefix $new_prefix/$new_prefix_len PLTime: $new_pltime VLTime: $new_vltime"
145+ sudo tee -a "${RADVD_CONF}" > /dev/null <<EEOOFF
146+ prefix "$new_prefix"/"$new_prefix_len"
147+ {
148+ AdvOnLink on;
149+ AdvAutonomous on;
150+ AdvRouterAddr off;
151+ AdvPreferredLifetime "$new_pltime";
152+ AdvValidLifetime "$new_vltime";
153+ };
154+ EEOOFF
155+ fi
156+
157+ sudo tee -a "${RADVD_CONF}" > /dev/null <<EEOOFF
158+ };
159+ EEOOFF
160+ }
161+
162+
163+ if [ "$interface" = "${INFRA_IF}" ]; then
164+ case $reason in
165+ DELEGATED6 | REBIND6 | RENEW6 | BOUND6 )
166+ if { [ -n "$new_dhcp6_ia_pd1_prefix1" ] && [ -n "$new_dhcp6_ia_pd1_prefix1_length" ]; } || \
167+ { [ -n "$old_dhcp6_ia_pd1_prefix1" ] && [ -n "$old_dhcp6_ia_pd1_prefix1_length" ]; }; then
168+ config_ra "$old_dhcp6_ia_pd1_prefix1" "$old_dhcp6_ia_pd1_prefix1_length" \
169+ "$new_dhcp6_ia_pd1_prefix1" "$new_dhcp6_ia_pd1_prefix1_length" "$new_dhcp6_ia_pd1_prefix1_pltime" "$new_dhcp6_ia_pd1_prefix1_vltime"
170+ if systemctl is-active network.target; then
171+ sudo systemctl reload-or-restart radvd || logger "$LOG_TAG Failed to reload radvd"
172+ fi
173+ fi
174+ ;;
175+ esac
176+ fi
177+ EOF
178+ sudo chmod 755 ${DHCPCD_ENTER_HOOK}
179+ }
180+
181+ create_dhcpcd_exit_hook ()
182+ {
183+ sudo tee ${DHCPCD_EXIT_HOOK} > /dev/null << EOF
184+ #!/bin/bash
185+
186+ INFRA_IF="${INFRA_IF} "
187+ THREAD_IF="${THREAD_IF} "
188+
189+ LOG_TAG="dhcpcd.exit.hook:"
190+
191+ EOF
192+
193+ sudo tee -a ${DHCPCD_EXIT_HOOK} > /dev/null << 'EOF '
194+ config_ra()
195+ {
196+ logger "$LOG_TAG $reason start config radvd"
197+
198+ sudo tee "${RADVD_CONF}" > /dev/null <<EEOOFF
199+ interface ${THREAD_IF}
200+ {
201+ AdvSendAdvert on;
202+ prefix "$1"/"$2"
203+ {
204+ AdvOnLink on;
205+ AdvAutonomous on;
206+ AdvRouterAddr off;
207+ AdvPreferredLifetime "$3";
208+ AdvValidLifetime "$4";
209+ };
210+ };
211+ EEOOFF
212+ }
213+
214+
215+ if [ "$interface" = "$INFRA_IF" ]; then
216+
217+ case $reason in
218+ EXPIRE6 | STOP6 | RELEASE6 )
219+ # TODO: Handle multiple IA_PD prefixes (new_dhcp6_ia_pd{i}_prefix{j}, new_dhcp6_ia_pd{i}_prefix{j}_length, etc.)
220+ # and deprecate old prefixes properly for each. Currently, only one prefix is handled.)
221+ if [ -z "$old_dhcp6_ia_pd1_prefix1" ] || [ -z "$old_dhcp6_ia_pd1_prefix1_length" ]; then
222+ logger "$LOG_TAG WARNING: Missing DHCPv6 prefix information. Skipping radvd configuration."
223+ else
224+ config_ra "$old_dhcp6_ia_pd1_prefix1" "$old_dhcp6_ia_pd1_prefix1_length" 0 0
225+ if systemctl is-active network.target; then
226+ sudo systemctl reload-or-restart radvd
227+ fi
228+ fi
229+ ;;
230+ esac
231+ fi
232+ EOF
233+ sudo chmod 755 ${DHCPCD_EXIT_HOOK}
234+ }
235+
85236create_dhcp6_pd_daemon_service ()
86237{
87238 sudo tee ${PD_DAEMON_SERVICE_PATH} << EOF
104255
105256dhcpcd_uninstall ()
106257{
107- [[ ${OTBR_DHCP6_PD_CLIENT} == " dhcpcd " ]] || return 0
258+ with DHCPV6_PD_REF || return 0
108259
109260 if have systemctl; then
110261 sudo systemctl disable ${PD_DAEMON_SERVICE_NAME} || true
@@ -130,18 +281,18 @@ dhcpcd_uninstall()
130281
131282dhcpcd_install ()
132283{
133- [[ ${OTBR_DHCP6_PD_CLIENT} == " dhcpcd " ]] || return 0
284+ with DHCPV6_PD_REF || return 0
134285
135286 if [[ -f ${DHCP_CONFIG_PATH} ]]; then
136287 sudo mv ${DHCP_CONFIG_PATH} ${DHCP_CONFIG_ORIG_PATH}
137288 fi
138289
139- # Add dhcpcd.hooks
140- sudo install -m 755 " $( dirname " $0 " ) " /reference-device/dhcpcd.enter-hook ${DHCPCD_ENTER_HOOK}
141- sudo install -m 755 " $( dirname " $0 " ) " /reference-device/dhcpcd.exit-hook ${DHCPCD_EXIT_HOOK}
142290 sudo mkdir -p ${PD_DAEMON_DIR}
143291 sudo install -m 755 " $( dirname " $0 " ) " /reference-device/dhcp6_pd_daemon.py ${PD_DAEMON_PATH}
144292
293+ create_dhcpcd_enter_hook
294+ create_dhcpcd_exit_hook
295+
145296 create_dhcpcd_conf_pd
146297 create_dhcpcd_conf_no_pd
147298 create_dhcp6_pd_daemon_service
0 commit comments