#!/bin/sh # # Copyright (c) 2000 The KAME Project # 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. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. # # $FreeBSD$ # From: src/etc/rc.network6,v 1.29 2002/04/06 15:15:43 # # PROVIDE: network_ipv6 # REQUIRE: network2 # KEYWORD: FreeBSD name="network_ipv6" rcvar=`set_rcvar ipv6` start_cmd="network_ipv6_start" #required_files="/etc/rc.network6" hexdigit() { if [ $1 -lt 10 ]; then echo $1 else case $1 in 10) echo a ;; 11) echo b ;; 12) echo c ;; 13) echo d ;; 14) echo e ;; 15) echo f ;; esac fi } hexprint() { val=$1 str='' dig=`hexdigit $((${val} & 15))` str=${dig}${str} val=$((${val} >> 4)) while [ ${val} -gt 0 ]; do dig=`hexdigit $((${val} & 15))` str=${dig}${str} val=$((${val} >> 4)) done echo ${str} } network6_interface_setup() { interfaces=$* rtsol_interfaces='' case ${ipv6_gateway_enable} in [Yy][Ee][Ss]) rtsol_available=no ;; *) rtsol_available=yes ;; esac for i in $interfaces; do rtsol_interface=yes eval prefix=\$ipv6_prefix_$i if [ -n "${prefix}" ]; then rtsol_available=no rtsol_interface=no laddr=`network6_getladdr $i` hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'` for j in ${prefix}; do address=$j\:${hostid} ifconfig $i inet6 ${address} prefixlen 64 alias case ${ipv6_gateway_enable} in [Yy][Ee][Ss]) # subnet-router anycast address # (rfc2373) ifconfig $i inet6 $j:: prefixlen 64 \ alias anycast ;; esac done fi eval ipv6_ifconfig=\$ipv6_ifconfig_$i if [ -n "${ipv6_ifconfig}" ]; then rtsol_available=no rtsol_interface=no ifconfig $i inet6 ${ipv6_ifconfig} alias fi if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ] then case ${i} in lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*) ;; *) rtsol_interfaces="${rtsol_interfaces} ${i}" ;; esac else ifconfig $i inet6 fi done if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then # Act as endhost - automatically configured. # You can configure only single interface, as # specification assumes that autoconfigured host has # single interface only. sysctl net.inet6.ip6.accept_rtadv=1 set ${rtsol_interfaces} ifconfig $1 up rtsol $1 fi for i in $interfaces; do alias=0 while : ; do eval ipv6_ifconfig=\$ipv6_ifconfig_${i}_alias${alias} if [ -z "${ipv6_ifconfig}" ]; then break; fi ifconfig $i inet6 ${ipv6_ifconfig} alias alias=$((${alias} + 1)) done done } network6_stf_setup() { case ${stf_interface_ipv4addr} in [Nn][Oo] | '') ;; *) # assign IPv6 addr and interface route for 6to4 interface stf_prefixlen=$((16+${stf_interface_ipv4plen:-0})) OIFS="$IFS" IFS=".$IFS" set ${stf_interface_ipv4addr} IFS="$OIFS" hexfrag1=`hexprint $(($1*256 + $2))` hexfrag2=`hexprint $(($3*256 + $4))` ipv4_in_hexformat="${hexfrag1}:${hexfrag2}" case ${stf_interface_ipv6_ifid} in [Aa][Uu][Tt][Oo] | '') for i in ${ipv6_network_interfaces}; do laddr=`network6_getladdr ${i}` case ${laddr} in '') ;; *) break ;; esac done stf_interface_ipv6_ifid=`expr "${laddr}" : \ 'fe80::\(.*\)%\(.*\)'` case ${stf_interface_ipv6_ifid} in '') stf_interface_ipv6_ifid=0:0:0:1 ;; esac ;; esac ifconfig stf0 create >/dev/null 2>&1 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \ prefixlen ${stf_prefixlen} # disallow packets to malicious 6to4 prefix route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject ;; esac } network6_static_routes_setup() { # Set up any static routes. case ${ipv6_defaultrouter} in [Nn][Oo] | '') ;; *) ipv6_static_routes="default ${ipv6_static_routes}" ipv6_route_default="default ${ipv6_defaultrouter}" ;; esac case ${ipv6_static_routes} in [Nn][Oo] | '') ;; *) for i in ${ipv6_static_routes}; do eval ipv6_route_args=\$ipv6_route_${i} route add -inet6 ${ipv6_route_args} done ;; esac } network6_faith_setup() { case ${ipv6_faith_prefix} in [Nn][Oo] | '') ;; *) sysctl net.inet6.ip6.keepfaith=1 ifconfig faith0 create >/dev/null 2>&1 ifconfig faith0 up for prefix in ${ipv6_faith_prefix}; do prefixlen=`expr "${prefix}" : ".*/\(.*\)"` case ${prefixlen} in '') prefixlen=96 ;; *) prefix=`expr "${prefix}" : \ "\(.*\)/${prefixlen}"` ;; esac route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1 route change -inet6 ${prefix} -prefixlen ${prefixlen} \ -ifp faith0 done ;; esac } network6_default_interface_setup() { # Choose IPv6 default interface if it is not clearly specified. case ${ipv6_default_interface} in '') for i in ${ipv6_network_interfaces}; do case $i in lo0|faith[0-9]*) continue ;; esac laddr=`network6_getladdr $i exclude_tentative` case ${laddr} in '') ;; *) ipv6_default_interface=$i break ;; esac done ;; esac # Disallow unicast packets without outgoing scope identifiers, # or route such packets to a "default" interface, if it is specified. route add -inet6 fe80:: -prefixlen 10 ::1 -reject case ${ipv6_default_interface} in [Nn][Oo] | '') route add -inet6 ff02:: -prefixlen 16 ::1 -reject ;; *) laddr=`network6_getladdr ${ipv6_default_interface}` route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \ -cloning # Disable installing the default interface with the # case net.inet6.ip6.forwarding=0 and # net.inet6.ip6.accept_rtadv=0, due to avoid conflict # between the default router list and the manual # configured default route. case ${ipv6_gateway_enable} in [Yy][Ee][Ss]) ;; *) if [ `sysctl -n net.inet6.ip6.accept_rtadv` -eq 1 ] then ndp -I ${ipv6_default_interface} fi ;; esac ;; esac } network6_getladdr() { ifconfig $1 2>/dev/null | while read proto addr rest; do case ${proto} in inet6) case ${addr} in fe80::*) if [ -z "$2" ]; then echo ${addr} return fi case ${rest} in *tentative*) continue ;; *) echo ${addr} return esac esac esac done } network_ipv6_start() { # disallow "internal" addresses to appear on the wire route add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject route add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject case ${ipv6_network_interfaces} in [Aa][Uu][Tt][Oo]) # Get a list of network interfaces ipv6_network_interfaces="`ifconfig -l`" ;; [Nn][Oo][Nn][Ee]) ipv6_network_interfaces='' ;; esac if checkyesno ipv6_gateway_enable ; then # act as a router ${SYSCTL_W} net.inet6.ip6.forwarding=1 ${SYSCTL_W} net.inet6.ip6.accept_rtadv=0 # wait for DAD for i in $ipv6_network_interfaces; do ifconfig $i up done sleep `${SYSCTL_N} net.inet6.ip6.dad_count` sleep 1 else # act as endhost - start with manual configuration # Setup of net.inet6.ip6.accept_rtadv is done later by # network6_interface_setup. ${SYSCTL_W} net.inet6.ip6.forwarding=0 fi if [ -n "${ipv6_network_interfaces}" ]; then # Setup the interfaces network6_interface_setup $ipv6_network_interfaces # wait for DAD's completion (for global addrs) sleep `${SYSCTL_N} net.inet6.ip6.dad_count` sleep 1 fi # Filter out interfaces on which IPv6 initialization failed. if checkyesno ipv6_gateway_enable ; then ipv6_working_interfaces="" for i in ${ipv6_network_interfaces}; do laddr=`network6_getladdr $i exclude_tentative` case ${laddr} in '') ;; *) ipv6_working_interfaces="$i \ ${ipv6_working_interfaces}" ;; esac done ipv6_network_interfaces=${ipv6_working_interfaces} fi # Setup IPv6 to IPv4 mapping network6_stf_setup # Install the "default interface" to kernel, which will be used # as the default route when there's no router. network6_default_interface_setup # Setup static routes network6_static_routes_setup # Setup faith network6_faith_setup # Support for IPv4 address tacked onto an IPv6 address if checkyesno ipv6_ipv4mapping ; then echo 'IPv4 mapped IPv6 address support=YES' ${SYSCTL_W} net.inet6.ip6.v6only=0 >/dev/null else echo 'IPv4 mapped IPv6 address support=NO' ${SYSCTL_W} net.inet6.ip6.v6only=1 >/dev/null fi } load_rc_config $name run_rc_command "$1"