From d582435b4b21a4246dd1b40df6e0bb8b28e7be77 Mon Sep 17 00:00:00 2001 From: Maurice Walker Date: Mon, 18 Jul 2022 01:18:23 +0200 Subject: [PATCH] interfaces: add support for SLAAC WAN interfaces w/o DHCPv6 #5862; closes #5883 New script to be invoked by rtsold when Router Advertisements with RDNSS / DNSSL information are received. Uses ifctl to create the /tmp/$if_routerv6 file and creates the /tmp/$if_defaultgwv6 file directly. Fixes the issue that these files don't get created when the M and O flags in RAs are not set. Also, passes RDNSS / DNSSL info from RAs to ifctl. --- LICENSE | 1 + plist | 1 + src/etc/inc/interfaces.inc | 4 +- .../scripts/interfaces/rtsold_resolvconf.sh | 77 +++++++++++++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) create mode 100755 src/opnsense/scripts/interfaces/rtsold_resolvconf.sh diff --git a/LICENSE b/LICENSE index 84c5055f2..d4eb41601 100644 --- a/LICENSE +++ b/LICENSE @@ -35,6 +35,7 @@ Copyright (c) 2015 Manuel Faux Copyright (c) 2003-2006 Manuel Kasper Copyright (c) 2012 Marcello Coutinho Copyright (c) 2018 Martin Wasley +Copyright (c) 2022 Maurice Walker Copyright (c) 2010-2015 Michael Bostock Copyright (c) 2019-2021 Michael Muenz Copyright (c) 2019 Pascal Mathis diff --git a/plist b/plist index a5b7f85b3..6b777a247 100644 --- a/plist +++ b/plist @@ -806,6 +806,7 @@ /usr/local/opnsense/scripts/interfaces/ppp-linkup.sh /usr/local/opnsense/scripts/interfaces/ppp-uptime.sh /usr/local/opnsense/scripts/interfaces/reconfigure_vlans.php +/usr/local/opnsense/scripts/interfaces/rtsold_resolvconf.sh /usr/local/opnsense/scripts/interfaces/traffic_stats.php /usr/local/opnsense/scripts/interfaces/traffic_top.py /usr/local/opnsense/scripts/ipsec/connect.py diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index 6d64d5ca9..475108faf 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -2710,12 +2710,12 @@ function interface_dhcpv6_configure($interface, $wancfg) killbypid('/var/run/rtsold.pid', 'TERM', true); $rtsoldcommand = exec_safe( - '/usr/sbin/rtsold -p %s -M %s -O %s -R %s -a', + '/usr/sbin/rtsold -p %s -M %s -O %s -R %s -a -u', array( '/var/run/rtsold.pid', '/var/etc/rtsold_script.sh', '/var/etc/rtsold_script.sh', - '/usr/bin/true', /* XXX missing proper script to refresh resolv.conf */ + '/usr/local/opnsense/scripts/interfaces/rtsold_resolvconf.sh', ) ); diff --git a/src/opnsense/scripts/interfaces/rtsold_resolvconf.sh b/src/opnsense/scripts/interfaces/rtsold_resolvconf.sh new file mode 100755 index 000000000..d3546c7a8 --- /dev/null +++ b/src/opnsense/scripts/interfaces/rtsold_resolvconf.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +# Copyright (c) 2022 Maurice Walker +# +# 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. +# +# THIS SOFTWARE IS PROVIDED ``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 +# AUTHOR 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. + +# This script is to be invoked by rtsold when a Router Advertisement +# with RDNSS / DNSSL options is encountered. It extracts interface, +# router and DNS information from arguments and STDIN. + +if [ -z "${2}" ]; then + echo "Nothing to do." + exit 0 +fi + +# ${2} is 'ifname:slaac:[RA-source-address]', where 'ifname' is the +# interface the RA was received on. + +ifname=${2%%:*} +rasrca=${2##*:slaac:[} +rasrca=${rasrca%]} + +# XXX replace by exlusive 'ifname:slaac' use and falling back internally in ifctl? +if [ -n "$(/usr/local/sbin/ifctl -i ${ifname} -6r)" ]; then + echo "IPv6 gateway for ${ifname} already exists." + exit 0 +fi + +# ${1} indicates whether DNS information should be added or deleted. + +if [ "${1}" = "-a" ]; then + /usr/local/sbin/ifctl -i ${ifname} -6rd -a ${rasrca} + # XXX stop modifying defaultgw files in scripts + echo ${rasrca} > /tmp/${ifname}_defaultgwv6 + + # rtsold sends a resolv.conf(5) file to STDIN of this script + while IFS=' ' read -r type value; do + if [ "${type}" = "nameserver" ]; then + # in: nameserver 2001:db8::1 + # nameserver 2001:db8::2 + # nameserver 2001:db8::3 + # out: -a 2001:db8::1 -a 2001:db8::2 -a 2001:db8::3 + nameservers="${nameservers} -a ${value}" + elif [ "${type}" = "search" ]; then + # in: search example.com example.net example.org + # out: -a example.com -a example.net -a example.org + for entry in $value; do + searchlist="${searchlist} -a ${entry}" + done + fi + done + + /usr/local/sbin/ifctl -i ${ifname} -6nd ${nameservers} + /usr/local/sbin/ifctl -i ${ifname} -6sd ${searchlist} + /usr/local/sbin/configctl -d interface newipv6 ${ifname} +fi + +# XXX implement -d as well