657 lines
13 KiB
Bash
Executable File
657 lines
13 KiB
Bash
Executable File
_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 ) % 10 ) * 10 ))
|
|
_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()
|
|
{
|
|
_subcard="$1"
|
|
|
|
_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}="$*"
|
|
|
|
dhcpd_enable="YES"
|
|
gateway_enable="YES"
|
|
pf_enable="YES"
|
|
}
|
|
|
|
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}"
|
|
dhcp6c_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 $*
|
|
_card_and_vlan="${_card}_${_vlan}"
|
|
_card_dot_vlan="${_card}.${_vlan}"
|
|
if [ ${_vlan} -ne 0 ]
|
|
then
|
|
add_vlan $_card $_vlan
|
|
else
|
|
_card_and_vlan="${_card}"
|
|
_card_dot_vlan="${_card}"
|
|
fi
|
|
|
|
_class_group=""
|
|
if [ ! -z "${_class}" ]
|
|
then
|
|
_class_group="group ${_class}"
|
|
fi
|
|
eval ifconfig_${_card_and_vlan}=\"$(compute_v4_net $_card $_subnet) group internal ${_class_group}\"
|
|
eval dhcpd_ifaces=\"${dhcpd_ifaces} ${_card_dot_vlan}\"
|
|
}
|
|
|
|
_add_v6_prefixes()
|
|
{
|
|
_next_alias=$1
|
|
shift 1
|
|
|
|
while [ -n "${1}" ]
|
|
do
|
|
eval ifconfig_${_card_and_vlan}_alias${_next_alias}=\"inet6 $1/64\"
|
|
shift 1
|
|
_next_alias=`expr $_next_alias + 1`
|
|
done
|
|
}
|
|
|
|
add_v6_net()
|
|
{
|
|
_isp=""
|
|
_compute_nets $*
|
|
_card_and_vlan="${_card}_${_vlan}"
|
|
_card_dot_vlan="${_card}.${_vlan}"
|
|
if [ ${_vlan} -ne 0 ]
|
|
then
|
|
add_vlan $_card $_vlan
|
|
else
|
|
_card_and_vlan="${_card}"
|
|
_card_dot_vlan="${_card}"
|
|
fi
|
|
add_rtadv ${_card_dot_vlan}
|
|
|
|
_compute_ula_prefix
|
|
|
|
_class_group=""
|
|
if [ ! -z "${_class}" ]
|
|
then
|
|
_class_group="group ${_class}"
|
|
fi
|
|
|
|
eval ifconfig_${_card_and_vlan}_ipv6=\"inet6 fe80::1/64 group internal ${_class_group}\"
|
|
|
|
_next_alias=0
|
|
|
|
if [ "${_subnet}" = "0" ]
|
|
then
|
|
_subnet="00"
|
|
fi
|
|
|
|
if [ "${_priv}" = "YES" ]
|
|
then
|
|
eval ifconfig_${_card_and_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_dot_vlan} ${_isp}
|
|
else
|
|
_echo "Adding ${_card_dot_vlan} to default (which is ${default_isp} at this time)"
|
|
_add_dhcpv6 ${_card_dot_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 ${localnet_generated_zone_authority}. ${localnet_generated_zone_admin}. ('
|
|
date +'%s'
|
|
|
|
echo 7200
|
|
echo 1200
|
|
echo 7200
|
|
echo 5400
|
|
|
|
echo ')'
|
|
|
|
echo '$ORIGIN ${localnet_generated_zone}.'
|
|
|
|
echo '@ IN NS ${localnet_generated_zone_ns}.'
|
|
|
|
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()
|
|
{
|
|
_hints="$( find ${rc_router_dir}/hints/ -type f )"
|
|
if [ -d "${rc_router_conf_dir}/hints/" ]
|
|
then
|
|
_hints="${_hints} $( find ${rc_router_conf_dir}/hints/ -type f )"
|
|
fi
|
|
|
|
for _hint in $(ls ${_hints})
|
|
do
|
|
v4_setup="dhcp" # v4 usually defaults to DHCP
|
|
_isp=$( basename ${_hint} )
|
|
. ${_hint}
|
|
|
|
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
|