| #!/bin/bash |
| # |
| # Copyright (c) 2024, The OpenThread Authors. |
| # All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are met: |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # 3. Neither the name of the copyright holder nor the |
| # names of its contributors may be used to endorse or promote products |
| # derived from this software without specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| # POSSIBILITY OF SUCH DAMAGE. |
| # |
| # Description: |
| # This script manipulates DHCPv6-PD-REF configuration. |
| # |
| |
| # TODO: set the upstream interface according to the environment variables of `script/setup`. |
| UPSTREAM_INTERFACE="eth0" |
| WPAN_INTERFACE="wpan0" |
| LARGE_METRIC="2048" # A high metric value for loopback to make its routes less preferred. |
| |
| DHCPCD_ENTER_HOOK="/etc/dhcpcd.enter-hook" |
| DHCPCD_EXIT_HOOK="/etc/dhcpcd.exit-hook" |
| |
| PD_DAEMON_DIR="/opt/pd-daemon" |
| PD_DAEMON_PATH="${PD_DAEMON_DIR}/dhcp6_pd_daemon.py" |
| PD_DAEMON_SERVICE_NAME="dhcp6_pd_daemon.service" |
| PD_DAEMON_SERVICE_PATH="/etc/systemd/system/${PD_DAEMON_SERVICE_NAME}" |
| |
| DHCP_CONFIG_PATH="/etc/dhcpcd.conf" |
| DHCP_CONFIG_ORIG_PATH="/etc/dhcpcd.conf.orig" |
| DHCP_CONFIG_PD_PATH="/etc/dhcpcd.conf.pd" |
| DHCP_CONFIG_NO_PD_PATH="/etc/dhcpcd.conf.no-pd" |
| |
| # Create dhcpcd configuration file with ipv6 prefix request. |
| create_dhcpcd_conf_pd() |
| { |
| sudo tee ${DHCP_CONFIG_PD_PATH} >/dev/null <<EOF |
| noipv6rs # disable router solicitation |
| # The 'interface lo' block with a high 'metric' value ensures that dhcpcd's |
| # default reject route for unassigned delegated prefixes on loopback interface, |
| # are less preferred. |
| # OpenThread will later install an active route for the delegated prefix on |
| # ${WPAN_INTERFACE} with a standard (lower) metric, ensuring it takes precedence. |
| interface lo |
| metric ${LARGE_METRIC} |
| interface ${UPSTREAM_INTERFACE} |
| iaid 1 |
| ia_pd 2/::/64 |
| release |
| # Disable Router Solicitations (RS) again, specifically for ${UPSTREAM_INTERFACE}. |
| # This ensures that accept_ra is prevented from being set to 0, allowing |
| # the interface to accepting Router Advertisements and configuring IPv6 |
| # based on them. The exact reason for requiring 'noipv6rs' twice |
| # is not fully understood but has been observed to be necessary through |
| # experimentation. |
| noipv6rs |
| EOF |
| } |
| |
| # Create dhcpcd configuration file with no prefix request. |
| create_dhcpcd_conf_no_pd() |
| { |
| sudo tee ${DHCP_CONFIG_NO_PD_PATH} >/dev/null <<EOF |
| noipv6rs # disable router solicitation |
| EOF |
| } |
| |
| create_dhcp6_pd_daemon_service() |
| { |
| sudo tee ${PD_DAEMON_SERVICE_PATH} <<EOF |
| [Unit] |
| Description=Daemon to manage dhcpcd based on otbr-agent's PD state change |
| ConditionPathExists=${PD_DAEMON_PATH} |
| Requires=otbr-agent.service |
| After=otbr-agent.service |
| |
| [Service] |
| Type=simple |
| User=root |
| ExecStart=/usr/bin/python3 ${PD_DAEMON_PATH} |
| Restart=on-failure |
| |
| [Install] |
| WantedBy=multi-user.target |
| EOF |
| } |
| |
| dhcpcd_uninstall() |
| { |
| [[ ${OTBR_DHCP6_PD_CLIENT} == "dhcpcd" ]] || return 0 |
| |
| if have systemctl; then |
| sudo systemctl disable ${PD_DAEMON_SERVICE_NAME} || true |
| sudo systemctl stop ${PD_DAEMON_SERVICE_NAME} || true |
| sudo rm -f ${PD_DAEMON_SERVICE_PATH} || true |
| fi |
| |
| if [[ -f ${DHCP_CONFIG_ORIG_PATH} ]]; then |
| sudo mv ${DHCP_CONFIG_ORIG_PATH} ${DHCP_CONFIG_PATH} |
| fi |
| |
| sudo rm -f ${DHCPCD_ENTER_HOOK} ${DHCPCD_EXIT_HOOK} |
| sudo rm -f ${PD_DAEMON_PATH} |
| |
| if have systemctl; then |
| sudo systemctl daemon-reload |
| |
| if systemctl is-active dhcpcd; then |
| sudo systemctl restart dhcpcd || true |
| fi |
| fi |
| } |
| |
| dhcpcd_install() |
| { |
| [[ ${OTBR_DHCP6_PD_CLIENT} == "dhcpcd" ]] || return 0 |
| |
| if [[ -f ${DHCP_CONFIG_PATH} ]]; then |
| sudo mv ${DHCP_CONFIG_PATH} ${DHCP_CONFIG_ORIG_PATH} |
| fi |
| |
| # Add dhcpcd.hooks |
| sudo install -m 755 "$(dirname "$0")"/reference-device/dhcpcd.enter-hook ${DHCPCD_ENTER_HOOK} |
| sudo install -m 755 "$(dirname "$0")"/reference-device/dhcpcd.exit-hook ${DHCPCD_EXIT_HOOK} |
| sudo mkdir -p ${PD_DAEMON_DIR} |
| sudo install -m 755 "$(dirname "$0")"/reference-device/dhcp6_pd_daemon.py ${PD_DAEMON_PATH} |
| |
| create_dhcpcd_conf_pd |
| create_dhcpcd_conf_no_pd |
| create_dhcp6_pd_daemon_service |
| |
| # The dhcp6_pd_daemon is currently disabled because it restarts dhcpcd |
| # when the PD state changes. This restart disrupts mDNS, causing |
| # connectivity issues. The daemon and its associated systemd service |
| # files are still installed for potential future use. |
| # |
| # TODO: Re-enable and start the daemon when a solution is found |
| # for dhcpcd restarts breaking mDNS. |
| # |
| # if have systemctl; then |
| # sudo systemctl daemon-reload |
| # sudo systemctl enable ${PD_DAEMON_SERVICE_NAME} |
| # sudo systemctl start ${PD_DAEMON_SERVICE_NAME} |
| # fi |
| |
| # Always enable PD, which is a workaround for the currently disabled |
| # dhcp6_pd_daemon which caused mDNS disruptions. |
| sudo cp ${DHCP_CONFIG_PD_PATH} ${DHCP_CONFIG_PATH} |
| |
| if have systemctl; then |
| sudo systemctl daemon-reload |
| |
| # Restart dhcpcd only if it's running. This is unnecessary when the dhcp6_pd_daemon |
| # is enabled, as the daemon will handle dhcpcd restarts based on PD state changes. |
| if systemctl is-active dhcpcd; then |
| sudo systemctl restart dhcpcd || true |
| fi |
| |
| sudo systemctl enable radvd |
| fi |
| } |