Much of the core bits are initially ported.

This should be mostly independent of my configs, now.
This commit is contained in:
2026-05-09 03:26:53 -04:00
parent 6b02d9d58e
commit 4d30691ee6
16 changed files with 1278 additions and 2 deletions
+1 -1
View File
@@ -220,7 +220,7 @@ If you develop a new program, and you want it to be of the greatest possible use
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
rc.router
Copyright (C) 2026 adam
Copyright (C) 2026 ADAM David Alan Martin
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+119 -1
View File
@@ -1,3 +1,121 @@
# rc.router
FreeBSD's Init/RC system could use some extensions for easy configuration of homelab routers.
The FreeBSD Init/RC system could use some extensions for easy configuration of homelab
and SOHO routers.
These files provide such a set of extensions. These extensions, while providing a lot
of advanced functionality, are not meant for anything other than edge routers.
"Core router" functionality (which bridges between transit networks) is not provided
for by this configuration mechanism.
`rc.router` requires FreeBSD-15 or greater. (It might work for some configurations
on FreeBSD-14, but I no longer run any routers with it on FreeBSD-14.)
## How to setup (Easy dual-stack example With Git)
Executing this sequence of sample commands will setup a basic Dual-stack router
for Verizon FIOS. There are a few pre-canned ISP configuration files which help
guide what settings are needed for which ISPs. (Mostly this impacts IPv6 settings
not IPv4 settings.)
```
$ cd /etc
$ mkdir router-conf
$ cd router-conf
$ git init .
$ echo << EOF > rc.conf
# Configure a basic external v4 ISP
external_card="em0"
add_canned_isp ${external_card} fios_1 verizon_fios
# Configure a basic internal v4 network
internal_card="re0"
add_net ${internal_card} 0 main
EOF
$ git add rc.conf
$ git submodule add rc.router https://gitea.nerdland.org/adam/rc.router
$ git commit -m "FIRST POST!!!"
$ echo 'rc_router_dir="/etc/router-conf/rc.router"' >> /etc/rc.conf
$ echo 'rc_router_conf_dif="/etc/router-conf"' >> /etc/rc.conf
$ echo ". ${rc_router_dir}/rc.entry" >> /etc/rc.conf
```
## How to setup (Easy v4-only example With Git)
Executing this sequence of sample commands will setup a basic v4 NAT/dhcp router.
```
$ cd /etc
$ mkdir router-conf
$ cd router-conf
$ git init .
$ echo << EOF > rc.conf
# Configure a basic external v4 ISP
external_card="em0"
add_v4_isp ${external_card} dhcp
# Configure a basic internal v4 network
internal_card="re0"
v4_net="172.26"
add_v4_net ${internal_card} 0 main
EOF
$ git add rc.conf
$ git submodule add rc.router https://gitea.nerdland.org/adam/rc.router
$ git commit -m "FIRST POST!!!"
$ echo 'rc_router_dir="/etc/router-conf/rc.router"' >> /etc/rc.conf
$ echo 'rc_router_conf_dif="/etc/router-conf"' >> /etc/rc.conf
$ echo ". ${rc_router_dir}/rc.entry" >> /etc/rc.conf
```
In this example, `em0` will be the uplink card, and will dhcpv4 configure itself. `re0` is
the primary internal interface card, which will be configured to host DHCP for internal
`172.26.0.0/24` addresses, in the basic default pool of `172.26.0.100` thru `172.26.0.200`.
The router's internal address in this subnet is `172.26.0.1/24`. And `8.8.8.8` will be used
as the default resolver for everyone within this subnet.
## Interoperation with regular FreeBSD `init` and `rc.conf` configuration
These scripts are not meant to replace the FreeBSD init script mechanisms. Instead these
scripts seek to augment the system. The scripts provide ways to set clusters of related
config variables (and to generate other related configuration files) such that hybrid
configurations can be made. The various commands, such as `add_v4_net` result in the
setting and updating of various `rc.conf` variables as-if the user simply wrote the correct
configuration settings at that point in the `rc.conf` file.
As such, these mechanisms are meant to co-exist with manual variable setting and manually
maintained configuration files for things such as DHCP. This permits an adoption path
other than "big bang cutover". The `rc.router` commands are careful to update-by-append
to certain variables, rather than to assume direct ownership of all variables. Thus,
`add_net xy0 402` and `ifconfig_xy0_43_alias0="192.168.10.4/24"` could be safely
intermingled. (Right now, the scripts assume ownership over specific related
variables for interfaces and vlans that they create.)
## IPv6 posture and readiness
`rc.router` is designed as an IPv6-first package. While IPv4-only networks are still
possible with this package, the defaults are tuned for and assume IPv6. Pre-canned
router configurations should gracefully (albeit with some timeouts) fail back to v4-only
modes, when IPv6 is not available from those ISPs, due to CPE concerns.
IPv6 configuration with `rc.router` permits DHCPv6 `IA_PD` with Router Advertisements or
static configuration for the ISP side. For the internal side, SLAAC is the only
configuration provided. DHCPv6 internally for `IA_NA` is not implemented. `rc.router`
is not expliticly incompatible with DHCPv6 internal provisioning, but no effort has
been made to implement or test it. Given that a large number of consumer devices
(Android, in particular) refuse to provision via DHCPv6, SLAAC must be used internally
for any deployment to accommodate the widest swathe of client devices.
`rc.router` installs `tayga` and users are encouraged to use its `map` feature in
the configuration file to provide IPv4 addresses for IPv6-only hosts, or vice-versa.
This is intended to permit incremental migration for IPv4-only homelabs to dual-stack
and IPv6-only deployments.
The DHCPv4 configuration generator is capable of emitting Option 108 for IPv6-mostly
deployments.
.
+43
View File
@@ -0,0 +1,43 @@
#!/bin/sh
# This is rc.conf defaults for rc.router - a file full of useful
# variables that you can set to change the default startup behavior
# of your system. You should not edit this file! Put any
# overrides into one of the ${rc_conf_files} instead and you will
# be able to update these defaults later without spamming your
# local configuration information.
#
# The ${rc_conf_files} files should only contain values which override
# values set in this file. This eases the upgrade path when defaults
# are changed and new features are added.
#
# All arguments must be in double or single quotes.
#
# For a more detailed explanation of all the rc.conf variables, please
# refer to the rc.conf(5) manual page.
#
# For the `rc.router` project, router configurations should be tuned in
# `${rc_router_conf_dir}/rc.conf`.
rc_router_debug="NO"
generate_internal_dhcpv4_enable='YES'
generate_isp_dhcp_enable='YES'
generate_rtadvd_conf_enable="YES"
rc_router_gen_dir=${rc_router_dir}/gen
localnet_enable='NO'
rtadvd_pltimedecr='NO'
rtadvd_vltimedecr='NO'
v4_net="192.168"
dhcpv4_pool_lo="100"
dhcpv4_pool_hi="200"
rc_router_network_name="Default Network Name"
rc_router_ula_prefix_size="48"
rtsold_flags="-F"
# vim: ft=bash
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
# This emulates a minimal `/etc/rc.conf` that one would create in FreeBSD to
# hand off control to `rc.router`.
rc_router_dir="${RC_ROUTER_HARNESS}/.."
rc_router_conf_dir="${RC_ROUTER_HARNESS}/../test-conf/"
. ${rc_router_dir}/rc.entry
# vim: ft=bash
+29
View File
@@ -0,0 +1,29 @@
#!/bin/sh
# This file exists to let me test the function of these scripts outside
# of the FreeBSD RC environment.
#
# Just enough bare minimum facilities are present, to permit my rc.d scripts
# to run. I mostly use this to test the scripts which generate configuration
# files.
load_rc_config()
{
true
}
run_rc_command()
{
if [ -z "${1}" ]
then
echo "Error. Must supply an rc.d script command."
exit 254
fi
eval \${${1}_cmd}
}
. ${RC_ROUTER_HARNESS}/etc/rc.conf
# vim: ft=bash
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
v6_prefix_len="56"
# vim: ft=bash
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
v6_prefix_len="60"
# vim: ft=bash
+73
View File
@@ -0,0 +1,73 @@
_genfile="${route_policy_file}"
if [ -z "${_genfile}" ]
then
_genfile="/dev/fd/1"
fi
__install_route_policy()
{
iface=$1;shift 1
network=$1;shift 1
table=$1;shift 1
echo "match out on ${iface} from !fd00::/8 to ${network} rtable ${table}" >> $1
echo "match in on ${iface} from ${network} to !fd00::/8 rtable ${table}" >> $1
}
__install_route_policy_v4()
{
iface=$1;shift 1
network=$1;shift 1
table=$1;shift 1
echo "match out on ${iface} to ${network} rtable ${table}" >> $1
echo "match in on ${iface} from ${network} rtable ${table}" >> $1
}
_install_route_policy()
{
iface=$1;shift 1
split=`echo $1 | sed -e 's/->/ /g'`;shift 1
__install_route_policy $iface ${split} $*
}
_install_route_policy_v4()
{
iface=$1;shift 1
split=`echo $1 | sed -e 's/->/ /g'`;shift 1
__install_route_policy_v4 $iface ${split} $*
}
install_route_policy()
{
_install_route_policy internal $* ${_genfile}
}
install_route_policy_v4()
{
_install_route_policy_v4 internal $* ${_genfile}
}
add_route_policy()
{
route_policies="${route_policies} $1->$2"
}
add_route_policy_v4()
{
route_policies_v4="${route_policies_v4} $1->$2"
}
clear_all_policies()
{
echo -n > $_genfile
}
#add_route_policy 2602:f6a8:1::/48@9
#add_route_policy 2001:db8:f6a8:1::/64@42
# vim: ft=bash
+35
View File
@@ -0,0 +1,35 @@
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: generate_internal_dhcpv4
# REQUIRE: netif
# BEFORE: isc-dhcp
# KEYWORD: shutdown
#
. ${RC_ROUTER_HARNESS}/etc/rc.subr
name='generate_internal_dhcpv4'
start_cmd='generate_dhcp_start'
stop_cmd='generate_dhcp_stop'
rcvar='generate_internal_dhcpv4_enable'
load_rc_config 'generate_internal_dhcpv4'
generate_dhcp_start()
{
_emit_dhcpv4
}
generate_dhcp_stop()
{
true
}
################ Epilogue
run_rc_command "$1"
# vim: ft=bash
+36
View File
@@ -0,0 +1,36 @@
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: generate_isp_dhcp
# REQUIRE: netif
# BEFORE: dhcp6c
# KEYWORD: shutdown
#
. ${RC_ROUTER_HARNESS}/etc/rc.subr
name='generate_isp_dhcp'
start_cmd='generate_isp_dhcp_start'
stop_cmd='generate_isp_dhcp_stop'
rcvar='generate_isp_dhcp_enable'
load_rc_config 'generate_isp_dhcp'
generate_isp_dhcp_start()
{
_emit_dhcpv6
cat ${rc_router_gen_dir}/dhcp6c.*.conf > ${rc_router_gen_dir}/dhcp6c.conf
}
generate_isp_dhcp_stop()
{
true
}
################ Epilogue
run_rc_command "$1"
# vim: ft=bash
+131
View File
@@ -0,0 +1,131 @@
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: generate_rtadvd_conf
# REQUIRE: dhcp6c
# BEFORE: rtadvd
# KEYWORD: shutdown
#
. ${RC_ROUTER_HARNESS}/etc/rc.subr
name='generate_rtadvd_conf'
start_cmd='generate_rtadvd_conf_start'
stop_cmd='generate_rtadvd_conf_stop'
rcvar='generate_rtadvd_conf_enable'
load_rc_config 'generate_rtadvd_conf'
[ -z "$generate_rtadvd_conf_enable" ] && generate_rtadvd_conf_enable='NO'
_prepare_var()
{
var=$1
opt=$2
eval _value=\${${var}}
eval _${opt}=""
if [ -n "${_value}" ]
then
_text="${opt}=\\\"${_value}\\\""
eval _${opt}=\"${_text}\"
fi
}
_prepare_num()
{
var=$1
opt=$2
eval _value=\${${var}}
eval _${opt}\=""
if [ -n "${_value}" ]
then
_text="${opt}\#${_value}"
eval _${opt}=\"${_text}\"
fi
}
_prepare_opt()
{
var=$1
opt=$2
eval _${opt}\=""
if [ `option_selected ${var}` = "YES" ]
then
_text="${opt}"
eval _${opt}=\"${_text}\"
fi
}
_build_rtadv()
{
gen_rtadv_dir=${rc_router_gen_dir}
rtadvd_conf=${gen_rtadv_dir}/rtadvd.conf
mkdir -p ${gen_rtadv_dir}
_search_list=""
if [ -n "${rtadvd_dns_search_list}" ]
then
_search_list=$( echo ${rtadvd_dns_search_list} | sed -e 's/ */,/g' -e 's/^,//' -e 's/,$//' )
fi
_prepare_var _search_list dnssl
_prepare_var rtadvd_pref64_prefix pref64
_prepare_num rtadvd_mininterval mininterval
_prepare_num rtadvd_maxinterval maxinterval
_prepare_num rtadvd_pltime pltime
_prepare_opt rtadvd_pltimedecr pltimedecr
_prepare_num rtadvd_vltime vltime
_prepare_opt rtadvd_vltimedecr vltimedecr
_prepare_num rtadvd_rltime rltime
cat ${rc_router_dir}/templates/rtadvd.conf \
| sed \
-e "s/@PREF64@/${_pref64}/" \
-e "s/@MININTERVAL@/${_mininterval}/" \
-e "s/@MAXINTERVAL@/${_maxinterval}/" \
-e "s/@PLTIME@/${_pltime}/" \
-e "s/@PLTIME_DECR@/${_pltimedecr}/" \
-e "s/@VLTIME@/${_vltime}/" \
-e "s/@VLTIME_DECR@/${_vltimedecr}/" \
-e "s/@RLTIME@/${_rltime}/" \
-e "s/@DNS_SEARCHLIST@/${_dnssl}/" \
-e "s/@DNS_SERVER@/${rtadvd_dns_server}/" \
> ${rtadvd_conf}
echo "" >> ${rtadvd_conf}
echo "" >> ${rtadvd_conf}
for interface in ${rtadvd_interfaces}
do
echo "${interface}:tc=settings" >> ${rtadvd_conf}
done
}
generate_rtadvd_conf_start()
{
_build_rtadv
}
generate_rtadvd_conf_stop()
{
true
}
################ Epilogue
run_rc_command "$1"
# vim: ft=bash
Executable
+103
View File
@@ -0,0 +1,103 @@
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: localnet
# REQUIRE: dhcp6c
# BEFORE: named
# KEYWORD: shutdown
#
# The purpose of this script is to generate various ISP prefix dependent files.
#
# Specifically, the DNS (BIND) acls file for handling various views, a local ISP
# range address for the router itself (on a dedicated loopback device), and
# attach any static addresses for this machine to another loopback device.
. ${RC_ROUTER_HARNESS}/etc/rc.subr
name='localnet'
extra_commands="rebuild_zoneinfo"
start_cmd='localnet_start'
stop_cmd='localnet_stop'
rebuild_zoneinfo_cmd="localnet_build_zoneinfo"
rcvar='localnet_enable'
load_rc_config 'localnet'
localnet_build_zoneinfo()
{
compute_addrs
localnet_build_zoneinfo_impl
}
localnet_build_zoneinfo_impl()
{
#build_zoneinfo ${isp_prefix} 31 ${router_conf_dir}/namedb/local-machines.defs
build_zoneinfo ${isp_prefix} 31 ${rc_router_conf_dir}/namedb/local-machines.defs > ${rc_router_gen_dir}/zone.hosts.nerdland.org
}
localnet_build_acls()
{
gen_acls_dir=${rc_router_gen_dir}/namedb
mkdir -p ${gen_acls_dir}
cat ${rc_router_dir}/templates/named.acls.conf \
| sed \
-e "s/@ISP_PREFIX@/${isp_prefix}/g" \
-e "s/@ULA_PREFIX@/${secret_ip6_net}/g" \
> ${gen_acls_dir}/acls.conf
}
compute_addrs() {
loop=0
while [ -z "${v6addr}" -a ${loop} -lt 5 ]
do
[ ${loop} -ne 0 ] && sleep 5
# todo: Adjust our ipv6 hint... get from a var?
v6addr=$(ifconfig ${localnet_first_nic} | grep "inet6 [23]...:" | head -1 | awk '{print $2}')
echo "V6 addr is: ${v6addr}"
loop=$(( ${loop} + 1 ))
done
echo "V6 addr is: ${v6addr}"
three_quads=$(echo ${v6addr} | awk -F ':' '{print $1":"$2":"$3}')
echo "First three quads are: ${three_quads}"
last_quad=$(echo ${v6addr} | awk -F ':' '{print $4}')
echo "Last quad is: ${last_quad}"
last_prefix=$(echo ${last_quad} | rev | awk '{print $1"0000"}' | cut -c 3,4 | rev | sed -e 's/^0//')
echo "Last prefix is: ${last_prefix}"
isp_prefix="${three_quads}:${last_prefix}"
base_addr=" inet6 ${isp_prefix}ff::1"
}
localnet_start() {
cp ${rc_router_conf_dir}/resolv.conf.master ${rc_router_conf_dir}/resolv.conf
compute_addrs
ifconfig lo1 create ${base_addr} prefer_source
# DO NOT USE prefer_source for this address...
# It will cause confusion for the wireguard tunnels underneath...
# It also could cause DNS recursion to fail -- routing as the nested
# connections...
localnet_build_acls
localnet_build_zoneinfo_impl
}
localnet_stop() {
compute_addrs
ifconfig lo0 ${base_addr} delete
ifconfig lo1 destroy
}
run_rc_command "$1"
# vim: ft=bash
+25
View File
@@ -0,0 +1,25 @@
#!/bin/sh
if [ -z "${rc_router_dir}" ]
then
echo "Unable to proceed -- rc_router_dir is not set." >& /dev/fd/2
echo "You must set this variable before sourcing `rc.router/rc.entry`" >& /dev/fd/2
exit 254
fi
if [ -z "${rc_router_conf_dir}" ]
then
echo "Unable to proceed -- rc_router_conf_dir is not set." >& /dev/fd/2
echo "You must set this variable before sourcing `rc.router/rc.entry`" >& /dev/fd/2
exit 254
fi
. ${rc_router_dir}/rc.subr
. ${rc_router_dir}/defaults/rc.conf
. ${rc_router_conf_dir}/rc.conf
_rc_router_epilogue
# vim: ft=bash
+629
View File
@@ -0,0 +1,629 @@
_debug()
{
echo 1>&2 $*
}
_echo()
{
if [ "${rc_router_debug}" = "YES" ]
then
_debug $*
fi
}
_warn()
{
if [ -x /usr/bin/logger ]; then
logger "$0: WARNING: $*"
fi
echo 1>&2 "$0: WARNING: $*"
}
__repeat()
{
__func=$1;shift 1
while [ "$1" != "" ]
do
${__func} $1
shift 1
done
}
__clone_interface()
{
_echo Adding $1 to cloned interfaces
cloned_interfaces="${cloned_interfaces} $1"
_echo "Cloned interfaces are now \"${cloned_interfaces}\""
}
clone_interfaces()
{
__repeat __clone_interface $*
}
clone_interface()
{
clone_interfaces $*
}
__add_wireguard_interface()
{
_echo "Adding $1 to ${wireguard_interfaces}"
wireguard_enable="YES"
wireguard_interfaces="${wireguard_interfaces} $1"
}
add_wireguard_interfaces()
{
__repeat __add_wireguard_interface $*
}
add_wireguard_interface()
{
add_wireguard_interfaces $*
}
add_wireguard_route()
{
add_route_policy $1 $2
add_wireguard_interface wg$2
}
add_wireguard_route_v4()
{
add_route_policy_v4 $1 $2
# Assuming v6 did this, for now...
#add_wireguard_interface wg$2
}
compute_56_net()
{
_echo Running 56 > /dev/fd/2
_echo 'Computing for `'$1'`' > /dev/fd/2
echo $1 | _hash | cut -c 1-12 | sed -e 's/\([0-9a-f][0-9a-f]\)/\1:/g' | awk -F: '{print "fd"$1":"$2$3":"$4$5":"$6}'
}
compute_48_net()
{
_echo Running 48 > /dev/fd/2
_echo 'Computing for `'$1'`' > /dev/fd/2
echo $1 | _hash | cut -c 1-10 | sed -e 's/\([0-9a-f][0-9a-f]\)/\1:/g' | awk -F: '{print "fd"$1":"$2$3":"$4$5":"}'
}
compute_net()
{
_echo 'Computing for `'$2'`' > /dev/fd/2
case $1 in
56)
compute_56_net "$2"
;;
48)
compute_48_net "$2"
;;
esac
}
compute_v4_net()
{
_card=$(echo ${_iface} | sed -e's/\.[0-9]*//')
eval _net=\${v4_net_${_card}}
if [ -z "${_net}" ]
then
_net=${v4_net}
fi
_prefix=${_net}
_subnet=$2
echo "${_prefix}.${_subnet}.1/24"
}
compute_v6_net()
{
_subnet=$2
_prefix=$1
echo "${_prefix}${_subnet}::1"
}
_compute_nets()
{
_card=$1
shift 1
_vlan=$1
shift 1
_base=$((${_vlan}%10))
_net=$((${_vlan}/100))
_subnet=${_net}${_base}
_extra_address=""
if [ -z "${1}" ]
then
echo "Error in configuration: No network class given"
exit 1
fi
_class=$1
shift 1
_priv="YES"
while true
do
case ${1} in
"no_ula")
_priv="NO"
;;
"no_isp")
_isp=""
;;
isp=*)
_isp=`echo ${1} | sed -e 's/isp=//'`
;;
*)
break
;;
esac
shift 1
done
while [ -n "${1}" ]
do
_extra_address="${_extra_address} $1"
shift 1
done
}
_add_vlan()
{
_card=$1
_vlan=$2
_vlans_var=vlans_${_card}
eval _vlans="\${${_vlans_var}}"
_echo "XXX ${_vlans} XXX"
_echo "QQQ ${_vlans} QQQ" | grep ${_vlan}
_qres=$?
_echo $_qres
echo "${_vlans}" | grep ${_vlan} > /dev/null
_res=$?
_echo $_res
if [ 0 -ne $_res ]
then
_echo vlans_${_card}="\${vlans_${_card}} ${_vlan}"
eval vlans_${_card}=\"\${vlans_${_card}} ${_vlan}\"
else
_echo "Not adding vlan ${_vlan} to card ${_card}"
fi
}
_add_rtadv()
{
_card=$1
_vlan=$2
_subcard="${_card}.${_vlan}"
_echo "XXX ${rtadvd_interfaces} XXX"
_echo "QQQ ${rtadvd_interfaces} QQQ" | grep ${_subcard}
_qres=$?
_echo $_qres
echo "${rtadvd_interfaces}" | grep ${_subcard} > /dev/null
_res=$?
_echo $_res
if [ 0 -ne $_res ]
then
_echo rtadvd_interfaces="${rtadvd_interfaces} ${_subcard}"
rtadvd_interfaces="${rtadvd_interfaces} ${_subcard}"
else
_echo "Not adding subcard ${_subcard} to ipv6 rtadvd list: ${rtadvd_interfaces}"
fi
}
_add_dhcpv6()
{
_iface=${1}
_isp=${2}
if [ -z "${_isp}" ]
then
echo "No ISP found..."
exit 255
fi
eval dhcpv6_${_isp}_list=\"\${dhcpv6_${_isp}_list} ${_iface}\"
}
add_dhcpv6()
{
_iface=${1}
_sla=${2}
_isp=${3}
if [ -z "${_isp}" ]
then
_isp=${default_isp}
fi
eval dhcpv6_${_isp}_supplement_list=\"\${dhcpv6_${_isp}_supplement_list} ${_iface}/${_sla}\"
}
_emit_dhcpv6_for_iface()
{
_iface=${1}
_sla=${2}
echo " prefix-interface ${_iface}" >> ${_dhcp_file}
echo " {" >> ${_dhcp_file}
echo " sla-id ${_sla};" >> ${_dhcp_file}
echo " sla-len $((64 - ${_prefix_len}));" >> ${_dhcp_file}
echo " };" >> ${_dhcp_file}
echo "" >> ${_dhcp_file}
}
_emit_dhcpv6_for_isp()
{
_isp=${1}
eval _interface=\"\${dhcp_interface_${_isp}}\"
_n=${2}
eval _prefix_len=\"\${dhcp_prefix_${_isp}}\"
mkdir -p ${rc_router_gen_dir}
_dhcp_file=${rc_router_gen_dir}/dhcp6c.${_isp}.conf
eval _isp_list=\${dhcpv6_${_isp}_list}
_echo "Checking ${_isp} against default: ${default_isp}"
if [ "${_isp}" = "${default_isp}" ]
then
_isp_list="${dhcpv6_default_list} ${_isp_list}"
fi
eval _isp_supplement_list=\${dhcpv6_${_isp}_supplement_list}
_echo "Building DHCP info for ${_isp} (interfaces: ${_isp_list})"
echo "######################" > ${_dhcp_file}
echo "# Configuration for ${_isp} on ${_interface}" >> ${_dhcp_file}
echo "######################" >> ${_dhcp_file}
echo "id-assoc pd $_n" >> ${_dhcp_file}
echo "{" >> ${_dhcp_file}
echo " prefix ::/${_prefix_len} infinity;" >> ${_dhcp_file}
for _iface_desc in ${_isp_supplement_list}
do
_iface=`echo ${_iface_desc} | sed -e 's;/.*$;;'`
_sla=`echo ${_iface_desc} | sed -e 's;^.*/;;'`
_emit_dhcpv6_for_iface ${_iface} ${_sla}
done
for _iface in ${_isp_list}
do
_vlan=`echo ${_iface} | sed -e 's/^.*\.//'`
_num=`echo ${_vlan} | sed -e 's/\([0-9]\)0\([0-9]\)/\1\2/'`
_vlan_sla=`printf "%d" 0x${_num}`
_emit_dhcpv6_for_iface ${_iface} ${_vlan_sla}
done
echo "};" >> ${_dhcp_file}
echo "" >> ${_dhcp_file}
echo "interface ${_interface} {" >> ${_dhcp_file}
echo " send ia-pd ${_n};" >> ${_dhcp_file}
echo "};" >> ${_dhcp_file}
echo "" >> ${_dhcp_file}
echo "" >> ${_dhcp_file}
}
_emit_dhcpv6()
{
_n=0
_echo "Emitting DHCPv6, and default ISP is: ${default_isp}"
for _isp in ${dhcp_isps}
do
_emit_dhcpv6_for_isp $_isp ${_n}
_n=$((${_n}+1))
done
}
add_v4_isp()
{
_iface="${1}" ; shift 1
eval ifconfig_${_iface}="$*"
}
add_v6_isp()
{
_echo "ISP added: $*"
_iface="${1}" ; shift 1
_name="${1}" ; shift 1
_isp_type="${1}" ; shift 1
eval _prefix_len="\${prefix_len_${_isp_type}}"
if [ "${1}" = "default" ]
then
_echo "Saw default, and overriding to ${_isp}"
default_isp="${_name}" ; shift 1
fi
if [ -z "${default_isp}" ]
then
default_isp=${_name}
fi
if [ "${default_isp}" = "${_name}" ]
then
rtsold_enable="YES"
ipv6_default_interface="${_iface}"
ipv6_cpe_wanif="${_iface}"
ipv6_isp_interfaces="${ipv6_isp_interfaces} ${_iface}"
dhcp_6c_enable="YES"
dhcp6c_config="${rc_router_gen_dir}/dhcp6c.conf"
fi
dhcp6c_interfaces="${dhcp6c_interfaces} ${_iface}"
eval dhcp_interface_${_name}="${_iface}"
eval dhcp_prefix_${_name}="${_prefix_len}"
dhcp_isps="${dhcp_isps} ${_name}"
}
add_canned_isp()
{
load_isp_hints # Make sure ISP hints are loaded, first
_iface="${1}" ; shift 1
_name="${1}" ; shift 1
_isp="${1}" ; shift 1
_v4_isp_config="\${rc_router_v4_isp_config_${_isp}}" # DHCP, usually
add_v4_isp ${_iface} ${_v4_isp_config}
add_v6_isp ${_iface} ${_name} ${_isp} $*
}
_emit_dhcpv4_for_iface()
{
_iface=${1}
_vlan=${2}
# Get a newline in there, to make output more readable
echo
_base=$((${_vlan}%10))
_net=$((${_vlan}/100))
_subnet=${_net}${_base}
eval _net=\${v4_net_${_iface}}
if [ -z "${_net}" ]
then
_net=${v4_net}
fi
eval _lo="\${dhcpv4_pool_lo_${_iface}}"
eval _hi="\${dhcpv4_pool_hi_${_iface}}"
[ -z "${_lo}" ] && _lo=${dhcpv4_pool_lo}
[ -z "${_hi}" ] && _hi=${dhcpv4_pool_hi}
_prefix="${_net}.${_subnet}"
echo "subnet ${_prefix}.0 netmask 255.255.255.0"
echo "{"
echo " option routers ${_prefix}.1;"
echo " range ${_prefix}.${_lo} ${_prefix}.${_hi};"
echo "}"
}
_emit_dhcpv4_defaults()
{
echo "option v6-mostly code 108 = integer 32;"
[ -z "${enable_v6_mostly}" ] && enable_v6_mostly="NO"
if [ `option_selected enable_v6_mostly` = "YES" ]
then
echo "option v6-mostly 7200;"
fi
if [ -n "${dhcpv4_dns}" ]
then
echo "option domain-name-servers ${dhcpv4_dns};"
fi
if [ -n "${dhcpv4_default_lease_time}" ]
then
echo "option default-lease-time ${dhcpv4_default_lease_time};"
fi
if [ -n "${dhcpv4_max_lease_time}" ]
then
echo "option max-lease-time ${dhcpv4_max_lease_time};"
fi
}
_emit_dhcpv4()
{
_dhcp_file=${rc_router_gen_dir}/dhcpd.subnets.conf
echo "" > ${_dhcp_file}
_emit_dhcpv4_defaults >> ${_dhcp_file}
for _iface in ${dhcpd_ifaces}
do
_iface_root=$( echo ${_iface} | sed -e 's/\.[0-9][0-9]*//' )
_vlan=$( echo ${_iface} | sed -e 's/[a-z][a-z]*[0-9][0-9]*\.//' )
_emit_dhcpv4_for_iface ${_iface_root} ${_vlan} >> ${_dhcp_file}
done
}
add_v4_net()
{
_compute_nets $*
_add_vlan $_card $_vlan
_class_group=""
if [ ! -z "${_class}" ]
then
_class_group="group ${_class}"
fi
eval ifconfig_${_card}_${_vlan}=\"$(compute_v4_net $_card $_subnet) group internal ${_class_group}\"
eval dhcpd_ifaces=\"${dhcpd_ifaces} ${_card}.${_vlan}\"
}
_add_v6_prefixes()
{
_next_alias=$1
shift 1
while [ -n "${1}" ]
do
eval ifconfig_${_card}_${_vlan}_alias${_next_alias}=\"inet6 $1/64\"
shift 1
_next_alias=`expr $_next_alias + 1`
done
}
add_v6_net()
{
_isp=""
_compute_nets $*
_add_vlan $_card $_vlan
_add_rtadv $_card $_vlan
_compute_ula_prefix
_class_group=""
if [ ! -z "${_class}" ]
then
_class_group="group ${_class}"
fi
eval ifconfig_${_card}_${_vlan}_ipv6=\"inet6 fe80::1/64 group internal ${_class_group}\"
_next_alias=0
if [ "${_priv}" = "YES" ]
then
eval ifconfig_${_card}_${_vlan}_alias${_next_alias}=\"inet6 $(compute_v6_net ${secret_ip6_net} ${_subnet})/64\"
_next_alias=1 # UGLY HACK!!! Does BASH increment work in BSD's sh?
fi
if [ -n "${_isp}" ]
then
_add_dhcpv6 ${_card}.${_vlan} ${_isp}
else
_echo "Adding ${_card}.${_vlan} to default (which is ${default_isp} at this time)"
_add_dhcpv6 ${_card}.${_vlan} default
fi
_add_v6_prefixes ${_next_alias} ${_extra_address}
}
add_net()
{
add_v4_net $*
add_v6_net $*
}
option_selected()
{
eval _value=\$${1}
_echo "option_selected: $1 is set to $_value."
case $_value in
# "yes", "true", "on", or "1"
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
echo "YES"
;;
# "no", "false", "off", or "0"
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
echo "NO"
;;
*)
_warn "\$${1} is not set properly - see rc.conf(5)."
echo "FAILED"
;;
esac
}
build_zoneinfo_for_host()
{
_ISP_PREFIX=${1};shift 1
_MAIN_SUBNET=${1};shift 1
_host=$( echo ${1} | sed -e 's/=.*$//' )
# Not really the MAC, but maybe that's the right way?
# For now it's host=SUFFIX
_MAC=$( echo ${1} | sed -e 's/^.*=//' )
#echo "Host: ${_host} --- MAC: ${_MAC}"
echo "${_host}" IN AAAA ${_ISP_PREFIX}${_MAIN_SUBNET}:${_MAC}
}
build_zoneinfo()
{
_prefix=${1} ; shift 1
_subnet=${1} ; shift 1
echo '$TTL 1h30m'
echo '@ IN SOA ns.nerdland.org. adam.imp-net.work. ('
date +'%s'
echo 7200
echo 1200
echo 7200
echo 5400
echo ')'
echo '$ORIGIN hosts.nerdland.org.'
echo '@ IN NS xns.nerdland.org.'
for _hostline in $(cat ${1})
do
#echo ${_prefix} ${_subnet} ${_hostline}
case "${_hostline}" in
"#"*)
continue
;;
esac
build_zoneinfo_for_host ${_prefix} ${_subnet} ${_hostline}
done
}
_hash()
{
sha1sum
}
# Now we compute a prefix from the hash of the network name.
# This lets us be deterministic, yet still know what our
# net name is.
#
_compute_ula_prefix()
{
secret_ip6_net=$(compute_net ${rc_router_ula_prefix_size} "${rc_router_network_name}")
}
load_isp_hints()
{
for _hint in $(ls ${rc_router_dir}/hints/*)
do
v4_setup="dhcp" # v4 usually defaults to DHCP
_isp=$( basename ${_hint} )
. ${rc_router_dir}/hints/${_isp}
eval rc_router_v4_isp_config_${_isp}=${v4_setup}
eval prefix_len_${_isp}=${v6_prefix_len}
done
}
_rc_router_epilogue()
{
rtsold_flags="${rtsold_flags} ${ipv6_isp_interfaces}"
}
#. ${router_conf_dir}/pf-framework.subr
# vim: ft=bash
Executable
+22
View File
@@ -0,0 +1,22 @@
#!/bin/sh
. ${RC_ROUTER_HARNESS}/etc/rc.conf
echo "Which nic?"
read nic
nic=`echo $nic | sed -e 's/\./_/g'`
echo "V6 net is: ${secret_ip6_net}"
eval echo "ifconfig_${nic}: \${ifconfig_${nic}}"
eval echo "ifconfig_${nic}_ipv6: \${ifconfig_${nic}_ipv6}"
eval echo "ifconfig_${nic}_alias0: \${ifconfig_${nic}_alias0}"
eval echo "ifconfig_${nic}_alias1: \${ifconfig_${nic}_alias1}"
eval echo "ifconfig_${nic}_alias2: \${ifconfig_${nic}_alias2}"
eval echo "ifconfig_${nic}_alias3: \${ifconfig_${nic}_alias3}"
eval echo "ifconfig_${nic}_alias4: \${ifconfig_${nic}_alias4}"
echo "rtadvd_interfaces: ${rtadvd_interfaces}"
echo "wireguard_interfaces: ${wireguard_interfaces}"
echo "cloned_interfaces: ${cloned_interfaces}"
set
+11
View File
@@ -0,0 +1,11 @@
settings:\
:@PREF64@:\
:@MININTERVAL@:\
:@MAXINTERVAL@:\
:@PLTIME@:\
:@PLTIME_DECR@:\
:@VLTIME@:\
:@VLTIME_DECR@:\
:@RLTIME@:\
:@DNS_SEARCHLIST@:\
:dnssl="@DNS_SERVER@":