diff options
Diffstat (limited to 'libexec/rc/rc.d/routing')
-rwxr-xr-x | libexec/rc/rc.d/routing | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/libexec/rc/rc.d/routing b/libexec/rc/rc.d/routing new file mode 100755 index 000000000000..dd75604125a3 --- /dev/null +++ b/libexec/rc/rc.d/routing @@ -0,0 +1,442 @@ +#!/bin/sh +# +# Configure routing and miscellaneous network tunables +# +# + +# PROVIDE: routing +# REQUIRE: netif ppp stf +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="routing" +desc="Routing setup" +start_cmd="routing_start doall" +stop_cmd="routing_stop" +extra_commands="options static" +static_cmd="routing_start static" +options_cmd="routing_start options" + +ROUTE_CMD="/sbin/route" + +routing_start() +{ + local _cmd _af _if _a _ret + _cmd=$1 + _af=$2 + _if=$3 + _ret=0 + + case $_if in + ""|[Aa][Ll][Ll]|[Aa][Nn][Yy]) _if="" ;; + esac + + case $_af in + ""|[Aa][Ll][Ll]|[Aa][Nn][Yy]) + for _a in inet inet6; do + afexists $_a || continue + setroutes $_cmd $_a $_if || _ret=1 + done + ;; + *) + if afexists $_af; then + setroutes $_cmd $_af $_if || _ret=1 + else + err 1 "Unsupported address family: $_af." + fi + ;; + esac + + return $_ret +} + +routing_stop() +{ + local _af _if _a + _af=$1 + _if=$2 + + case $_if in + ""|[Aa][Ll][Ll]|[Aa][Nn][Yy]) _if="" ;; + esac + + case $_af in + ""|[Aa][Ll][Ll]|[Aa][Nn][Yy]) + for _a in inet inet6; do + afexists $_a || continue + eval static_${_a} delete $_if + # When $_if is specified, do not flush routes. + if ! [ -n "$_if" ]; then + eval routing_stop_${_a} + fi + done + ;; + *) + if afexists $_af; then + eval static_${_af} delete $_if + # When $_if is specified, do not flush routes. + if ! [ -n "$_if" ]; then + eval routing_stop_${_af} + fi + else + err 1 "Unsupported address family: $_af." + fi + ;; + esac +} + +setroutes() +{ + local _ret + _ret=0 + case $1 in + static) + static_$2 add $3 + _ret=$? + ;; + options) + options_$2 + ;; + doall) + static_$2 add $3 + _ret=$? + options_$2 + ;; + esac + return $_ret +} + +routing_stop_inet() +{ + ${ROUTE_CMD} -n flush -inet +} + +routing_stop_inet6() +{ + local i + + ${ROUTE_CMD} -n flush -inet6 + for i in `list_net_interfaces`; do + if ipv6if $i; then + ifconfig $i inet6 -defaultif + fi + done +} + +get_fibmod() +{ + local _fibs + + _fibs=$((`${SYSCTL_N} net.fibs` - 1)) + if [ ${_fibs} -gt 0 ]; then + echo "-fib 0-${_fibs}" + else + echo + fi +} + +static_inet() +{ + local _action _if _skip _fibmod _fibs + _action=$1 + _if=$2 + + _fibmod=`get_fibmod` + _fibs=$((`${SYSCTL_N} net.fibs` - 1)) + + # Provide loopback route in all routing tables. This has to come + # first so that any following routes can be added. + static_routes="_loopback ${static_routes}" + route__loopback="-inet 127.0.0.1 -iface lo0 ${_fibmod}" + + # Add default route. + case ${defaultrouter} in + [Nn][Oo] | '') + ;; + *) + static_routes="${static_routes} _default" + route__default="default ${defaultrouter}" + ;; + esac + + # Add default routes for fibs + if [ ${_fibs} -gt 0 ]; then + for _fibnum in `jot ${_fibs}` ; do + eval _fib_gw=\${defaultrouter_fib${_fibnum}} + case ${_fib_gw} in + [Nn][Oo] | '') + ;; + *) + static_routes="${static_routes} _default_fib${_fibnum}" + eval route__default_fib${_fibnum}="'default ${_fib_gw} -fib ${_fibnum}'" + ;; + esac + done + fi + + + # Install configured routes. + if [ -n "${static_routes}" ]; then + for i in ${static_routes}; do + _skip=0 + if [ -n "$_if" ]; then + case $i in + *:$_if) ;; + *) _skip=1 ;; + esac + fi + if [ $_skip = 0 ]; then + route_args=`get_if_var ${i%:*} route_IF` + if [ -n "$route_args" ]; then + ${ROUTE_CMD} ${_action} ${route_args} + else + warn "route_${i%:*} not found." + fi + fi + done + fi +} + +static_inet6() +{ + local _action _if _skip fibmod _fibs + _action=$1 + _if=$2 + + fibmod=`get_fibmod` + _fibs=$((`${SYSCTL_N} net.fibs` - 1)) + + # Add pre-defined static routes first. + ipv6_static_routes="_v4mapped _v4compat ${ipv6_static_routes}" + ipv6_static_routes="_lla _llma ${ipv6_static_routes}" + ipv6_static_routes="_loopback ${ipv6_static_routes}" + + # disallow "internal" addresses to appear on the wire + ipv6_route__v4mapped="::ffff:0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}" + ipv6_route__v4compat="::0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}" + + # Create a loopback route in every fib + ipv6_route__loopback="::1 -prefixlen 128 -iface lo0 ${fibmod}" + + # Disallow link-local unicast packets without outgoing scope + # identifiers. However, if you set "ipv6_default_interface", + # for the host case, you will allow to omit the identifiers. + # Under this configuration, the packets will go to the default + # interface. + ipv6_route__lla="fe80:: -prefixlen 10 ::1 -reject ${fibmod}" + ipv6_route__llma="ff02:: -prefixlen 16 ::1 -reject ${fibmod}" + + # Add default route. + case ${ipv6_defaultrouter} in + [Nn][Oo] | '') + ;; + *) + ipv6_static_routes="${ipv6_static_routes} _default" + ipv6_route__default="default ${ipv6_defaultrouter}" + ;; + esac + + # Add default routes for fibs + if [ ${_fibs} -gt 0 ]; then + for _fibnum in `jot ${_fibs}` ; do + eval _fib_gw=\${ipv6_defaultrouter_fib${_fibnum}} + case ${_fib_gw} in + [Nn][Oo] | '') + ;; + *) + ipv6_static_routes="${ipv6_static_routes} _default_fib${_fibnum}" + eval ipv6_route__default_fib${_fibnum}="'default ${_fib_gw} -fib ${_fibnum}'" + ;; + esac + done + fi + + + # Install configured routes. + if [ -n "${ipv6_static_routes}" ]; then + for i in ${ipv6_static_routes}; do + _skip=0 + if [ -n "$_if" ]; then + case $i in + *:$_if) ;; + *) _skip=1 ;; + esac + fi + if [ $_skip = 0 ]; then + ipv6_route_args=`get_if_var ${i%:*} ipv6_route_IF` + if [ -n "$ipv6_route_args" ]; then + ${ROUTE_CMD} ${_action} \ + -inet6 ${ipv6_route_args} + else + warn "route_${i%:*} not found" + fi + fi + done + fi + + # Install the "default interface" to kernel, which will be used + # as the default route when there's no router. + + # Disable installing the default interface when we act + # as router to avoid conflict between the default + # router list and the manual configured default route. + if checkyesno ipv6_gateway_enable; then + return + fi + + case "${ipv6_default_interface}" in + [Nn][Oo] | [Nn][Oo][Nn][Ee]) + return + ;; + [Aa][Uu][Tt][Oo] | "") + for i in ${ipv6_network_interfaces}; do + case $i in + [Nn][Oo][Nn][Ee]) + return + ;; + lo0) + continue + ;; + esac + laddr=`network6_getladdr $i exclude_tentative` + case ${laddr} in + '') + ;; + *) + ipv6_default_interface=$i + break + ;; + esac + done + ;; + esac + + ifconfig ${ipv6_default_interface} inet6 defaultif + ${SYSCTL} net.inet6.ip6.use_defaultzone=1 > /dev/null +} + +ropts_init() +{ + if [ -z "${_ropts_initdone}" ]; then + echo -n "Additional $1 routing options:" + _ropts_initdone=yes + fi +} + +_check_dynamicrouting() +{ + local skip file name rcvar + + # copied from /etc/rc + skip="-s nostart" + if check_jail jailed; then + skip="$skip -s nojail" + fi + [ -n "$local_startup" ] && find_local_scripts_new + [ -n "$system_rc" ] && find_system_scripts + + for file in $( rcorder ${skip} ${system_rc} ${local_rc} 2>/dev/null | + xargs grep -lE '^# PROVIDE:.*\<dynamicrouting\>' ); do + (set -- enabled; . $file) && return 0; + done + + return 1 +} + +options_inet() +{ + local _icmp_drop_redirect + + _ropts_initdone= + if checkyesno icmp_bmcastecho; then + ropts_init inet + echo -n ' broadcast ping responses=YES' + ${SYSCTL} net.inet.icmp.bmcastecho=1 > /dev/null + else + ${SYSCTL} net.inet.icmp.bmcastecho=0 > /dev/null + fi + + _icmp_drop_redirect="${icmp_drop_redirect}" + case "${_icmp_drop_redirect}" in + [Aa][Uu][Tt][Oo] | "") + if _check_dynamicrouting; then + _icmp_drop_redirect="yes" + else + _icmp_drop_redirect="no" + fi + ;; + esac + if checkyesno _icmp_drop_redirect; then + ropts_init inet + echo -n ' ignore ICMP redirect=YES' + ${SYSCTL} net.inet.icmp.drop_redirect=1 > /dev/null + else + ${SYSCTL} net.inet.icmp.drop_redirect=0 > /dev/null + fi + + if checkyesno icmp_log_redirect; then + ropts_init inet + echo -n ' log ICMP redirect=YES' + ${SYSCTL} net.inet.icmp.log_redirect=1 > /dev/null + else + ${SYSCTL} net.inet.icmp.log_redirect=0 > /dev/null + fi + + if checkyesno gateway_enable; then + ropts_init inet + echo -n ' gateway=YES' + ${SYSCTL} net.inet.ip.forwarding=1 > /dev/null + else + ${SYSCTL} net.inet.ip.forwarding=0 > /dev/null + fi + + if checkyesno forward_sourceroute; then + ropts_init inet + echo -n ' do source routing=YES' + ${SYSCTL} net.inet.ip.sourceroute=1 > /dev/null + else + ${SYSCTL} net.inet.ip.sourceroute=0 > /dev/null + fi + + if checkyesno accept_sourceroute; then + ropts_init inet + echo -n ' accept source routing=YES' + ${SYSCTL} net.inet.ip.accept_sourceroute=1 > /dev/null + else + ${SYSCTL} net.inet.ip.accept_sourceroute=0 > /dev/null + fi + + if checkyesno arpproxy_all; then + ropts_init inet + echo -n ' ARP proxyall=YES' + ${SYSCTL} net.link.ether.inet.proxyall=1 > /dev/null + else + ${SYSCTL} net.link.ether.inet.proxyall=0 > /dev/null + fi + + [ -n "${_ropts_initdone}" ] && echo '.' +} + +options_inet6() +{ + _ropts_initdone= + + if checkyesno ipv6_gateway_enable; then + ropts_init inet6 + echo -n ' gateway=YES' + ${SYSCTL} net.inet6.ip6.forwarding=1 > /dev/null + else + ${SYSCTL} net.inet6.ip6.forwarding=0 > /dev/null + fi + + [ -n "${_ropts_initdone}" ] && echo '.' +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +routing_svcj="NO" + +run_rc_command "$@" |