network revision 1.53
11.1Slukem#!/bin/sh
21.1Slukem#
31.53Sreed# $NetBSD: network,v 1.53 2008/07/24 19:48:19 reed Exp $
41.1Slukem#
51.1Slukem
61.1Slukem# PROVIDE: network
71.19Slukem# REQUIRE: ipfilter ipsec mountcritlocal root tty sysctl
81.34Sthorpej# BEFORE:  NETWORKING
91.1Slukem
101.45Smycroft$_rc_subr_loaded . /etc/rc.subr
111.1Slukem
121.1Slukemname="network"
131.1Slukemstart_cmd="network_start"
141.14Slukemstop_cmd="network_stop"
151.1Slukem
161.1Slukemnetwork_start()
171.1Slukem{
181.1Slukem	# set hostname, turn on network
191.1Slukem	#
201.1Slukem	echo "Starting network."
211.1Slukem
221.1Slukem	# If $hostname is set, use it for my Internet name,
231.1Slukem	# otherwise use /etc/myname
241.1Slukem	#
251.20Snisimura	if [ -z "$hostname" ] && [ -f /etc/myname ]; then
261.46Schristos		hostname=$(cat /etc/myname)
271.1Slukem	fi
281.1Slukem	if [ -n "$hostname" ]; then
291.1Slukem		echo "Hostname: $hostname"
301.1Slukem		hostname $hostname
311.1Slukem	else
321.8Sthorpej		# Don't warn about it if we're going to run
331.8Sthorpej		# DHCP later, as we will probably get the
341.8Sthorpej		# hostname at that time.
351.8Sthorpej		#
361.46Schristos		if ! checkyesno dhclient && [ -z "$(hostname)" ]; then
371.8Sthorpej			warn "\$hostname not set."
381.8Sthorpej		fi
391.1Slukem	fi
401.1Slukem
411.1Slukem	# Check $domainname first, then /etc/defaultdomain,
421.1Slukem	# for NIS/YP domain name
431.1Slukem	#
441.20Snisimura	if [ -z "$domainname" ] && [ -f /etc/defaultdomain ]; then
451.46Schristos		domainname=$(cat /etc/defaultdomain)
461.1Slukem	fi
471.1Slukem	if [ -n "$domainname" ]; then
481.1Slukem		echo "NIS domainname: $domainname"
491.1Slukem		domainname $domainname
501.1Slukem	fi
511.1Slukem
521.1Slukem	# Flush all routes just to make sure it is clean
531.1Slukem	if checkyesno flushroutes; then
541.53Sreed		/sbin/route -qn flush
551.1Slukem	fi
561.1Slukem
571.1Slukem	# Set the address for the first loopback interface, so that the
581.1Slukem	# auto-route from a newly configured interface's address to lo0
591.1Slukem	# works correctly.
601.1Slukem	#
611.32Slukem	# NOTE: obscure networking problems will occur if lo0 isn't configured.
621.1Slukem	#
631.53Sreed	/sbin/ifconfig lo0 inet 127.0.0.1
641.10Sitojun
651.31Sitojun	# According to RFC1122, 127.0.0.0/8 must not leave the node.
661.10Sitojun	#
671.53Sreed	/sbin/route -q add -inet 127.0.0.0 -netmask 0xff000000 127.0.0.1 -reject
681.1Slukem
691.30Sitojun	# IPv6 routing setups, and host/router mode selection.
701.30Sitojun	#
711.53Sreed	if /sbin/ifconfig lo0 inet6 >/dev/null 2>&1; then
721.30Sitojun		# We have IPv6 support in kernel.
731.30Sitojun
741.30Sitojun		# disallow link-local unicast dest without outgoing scope
751.30Sitojun		# identifiers.
761.30Sitojun		#
771.53Sreed		/sbin/route -q add -inet6 fe80:: -prefixlen 10 ::1 -reject
781.30Sitojun
791.50Srpaulo		# disallow the use of the RFC3849 documentation address
801.50Srpaulo		#
811.53Sreed		/sbin/route -q add -inet6 2001:db8:: -prefixlen 32 ::1 -reject
821.50Srpaulo
831.50Srpaulo		# IPv6 site-local scoped address prefix (fec0::/10)
841.50Srpaulo		# has been deprecated by RFC3879.
851.30Sitojun		#
861.50Srpaulo		if [ -n "$ip6sitelocal" ]; then
871.50Srpaulo			warn "\$ip6sitelocal is no longer valid"
881.30Sitojun		fi
891.30Sitojun
901.30Sitojun		# disallow "internal" addresses to appear on the wire.
911.30Sitojun		#
921.53Sreed		/sbin/route -q add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject
931.30Sitojun
941.30Sitojun		# disallow packets to malicious IPv4 compatible prefix
951.30Sitojun		#
961.53Sreed		/sbin/route -q add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject
971.53Sreed		/sbin/route -q add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject
981.53Sreed		/sbin/route -q add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject
991.53Sreed		/sbin/route -q add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject
1001.30Sitojun
1011.30Sitojun		# disallow packets to malicious 6to4 prefix
1021.30Sitojun		#
1031.53Sreed		/sbin/route -q add -inet6 2002:e000:: -prefixlen 20 ::1 -reject
1041.53Sreed		/sbin/route -q add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject
1051.53Sreed		/sbin/route -q add -inet6 2002:0000:: -prefixlen 24 ::1 -reject
1061.53Sreed		/sbin/route -q add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject
1071.30Sitojun
1081.30Sitojun		# Completely disallow packets to IPv4 compatible prefix.
1091.30Sitojun		# This may conflict with RFC1933 under following circumstances:
1101.30Sitojun		# (1) An IPv6-only KAME node tries to originate packets to IPv4
1111.51Sreed		#     compatible destination.  The KAME node has no IPv4
1121.30Sitojun		#     compatible support.  Under RFC1933, it should transmit
1131.30Sitojun		#     native IPv6 packets toward IPv4 compatible destination,
1141.30Sitojun		#     hoping it would reach a router that forwards the packet
1151.30Sitojun		#     toward auto-tunnel interface.
1161.30Sitojun		# (2) An IPv6-only node originates a packet to IPv4 compatible
1171.30Sitojun		#     destination.  A KAME node is acting as an IPv6 router, and
1181.30Sitojun		#     asked to forward it.
1191.30Sitojun		# Due to rare use of IPv4 compatible address, and security
1201.30Sitojun		# issues with it, we disable it by default.
1211.30Sitojun		#
1221.53Sreed		/sbin/route -q add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject
1231.30Sitojun
1241.53Sreed		/sbin/sysctl -qw net.inet6.ip6.forwarding=0
1251.53Sreed		/sbin/sysctl -qw net.inet6.ip6.accept_rtadv=0
1261.30Sitojun
1271.30Sitojun		case $ip6mode in
1281.30Sitojun		router)
1291.30Sitojun			echo 'IPv6 mode: router'
1301.53Sreed			/sbin/sysctl -qw net.inet6.ip6.forwarding=1
1311.50Srpaulo
1321.50Srpaulo			# disallow unique-local unicast forwarding without
1331.50Srpaulo			# explicit configuration.
1341.50Srpaulo			if ! checkyesno ip6uniquelocal; then
1351.53Sreed				/sbin/route -q add -inet6 fc00:: -prefixlen 7 \
1361.50Srpaulo				    ::1 -reject
1371.50Srpaulo			fi
1381.30Sitojun			;;
1391.30Sitojun
1401.30Sitojun		autohost)
1411.30Sitojun			echo 'IPv6 mode: autoconfigured host'
1421.53Sreed			/sbin/sysctl -qw net.inet6.ip6.accept_rtadv=1
1431.30Sitojun			;;
1441.30Sitojun
1451.30Sitojun		host)	
1461.30Sitojun			echo 'IPv6 mode: host'
1471.30Sitojun			;;
1481.30Sitojun
1491.36Slukem		*)	warn "invalid \$ip6mode value "\"$ip6mode\"
1501.30Sitojun			;;
1511.30Sitojun
1521.30Sitojun		esac
1531.30Sitojun	fi
1541.30Sitojun
1551.1Slukem	# Configure all of the network interfaces listed in $net_interfaces;
1561.1Slukem	# if $auto_ifconfig is YES, grab all interfaces from ifconfig.
1571.1Slukem	# In the following, "xxN" stands in for interface names, like "le0".
1581.1Slukem	# For any interfaces that has an $ifconfig_xxN variable associated,
1591.1Slukem	# we do "ifconfig xxN $ifconfig_xxN".
1601.1Slukem	# If there is no such variable, we take the contents of the file
1611.1Slukem	# /etc/ifconfig.xxN, and run "ifconfig xxN" repeatedly, using each
1621.33Swiz	# line of the file as the arguments for a separate "ifconfig"
1631.1Slukem	# invocation.
1641.1Slukem	#
1651.1Slukem	# In order to configure an interface reasonably, you at the very least
1661.1Slukem	# need to specify "[addr_family] [hostname]" (e.g "inet my.domain.org"),
1671.1Slukem	# and probably a netmask (as in "netmask 0xffffffe0"). You will
1681.1Slukem	# frequently need to specify a media type, as in "media UTP", for
1691.1Slukem	# interface cards with multiple media connections that do not
1701.1Slukem	# autoconfigure. See the ifconfig manual page for details.
1711.1Slukem	#
1721.1Slukem	# Note that /etc/ifconfig.xxN takes multiple lines.  The following
1731.1Slukem	# configuration is possible:
1741.1Slukem	#	inet 10.1.1.1 netmask 0xffffff00
1751.1Slukem	#	inet 10.1.1.2 netmask 0xffffff00 alias
1761.50Srpaulo	#	inet6 2001:db8::1 prefixlen 64 alias
1771.1Slukem	#
1781.29Sitojun	# You can put shell script fragment into /etc/ifconfig.xxN by
1791.29Sitojun	# starting a line with "!".  Refer to ifconfig.if(5) for details.
1801.29Sitojun	#
1811.1Slukem	if [ "$net_interfaces" != NO ]; then
1821.1Slukem		if checkyesno auto_ifconfig; then
1831.53Sreed			tmp=$(/sbin/ifconfig -l)
1841.53Sreed			for cloner in $(/sbin/ifconfig -C 2>/dev/null); do
1851.25Swiz				for int in /etc/ifconfig.${cloner}[0-9]*; do
1861.23Snisimura					[ ! -f $int ] && break
1871.21Slukem					tmp="$tmp ${int##*.}"
1881.15Sthorpej				done
1891.15Sthorpej			done
1901.1Slukem		else
1911.1Slukem			tmp="$net_interfaces"
1921.1Slukem		fi
1931.1Slukem		echo -n 'Configuring network interfaces:'
1941.1Slukem		for int in $tmp; do
1951.20Snisimura			eval args=\$ifconfig_$int
1961.39Stron			if [ -n "$args" ] || [ -f /etc/ifconfig.$int ]; then
1971.53Sreed				if /sbin/ifconfig $int create 2>/dev/null && \
1981.39Stron				   checkyesno ipfilter; then
1991.39Stron					# resync ipf(4)
2001.53Sreed					/sbin/ipf -y >/dev/null
2011.39Stron				fi
2021.39Stron			fi
2031.52Sjoerg			if [ "$args" = "dhcp" ]; then
2041.52Sjoerg				echo -n " $int"
2051.53Sreed				/sbin/dhcpcd -n ${dhcpcd_flags} $int
2061.52Sjoerg			elif [ -n "$args" ]; then
2071.1Slukem				echo -n " $int"
2081.53Sreed				/sbin/ifconfig $int $args
2091.1Slukem			elif [ -f /etc/ifconfig.$int ]; then
2101.1Slukem				echo -n " $int"
2111.20Snisimura				while read args; do
2121.26Snisimura					[ -z "$args" ] && continue
2131.29Sitojun					case "$args" in
2141.39Stron					"#"*|create)
2151.29Sitojun						;;
2161.29Sitojun					"!"*)
2171.29Sitojun						eval ${args#*!}
2181.29Sitojun						;;
2191.52Sjoerg					dhcp)
2201.53Sreed						/sbin/dhcpcd -n ${dhcpcd_flags} \
2211.52Sjoerg						    $int
2221.52Sjoerg						;;
2231.29Sitojun					*)
2241.53Sreed						eval /sbin/ifconfig $int $args
2251.29Sitojun						;;
2261.29Sitojun					esac
2271.20Snisimura				done < /etc/ifconfig.$int
2281.1Slukem			else
2291.1Slukem				if ! checkyesno auto_ifconfig; then
2301.1Slukem					echo
2311.1Slukem					warn \
2321.1Slukem			"/etc/ifconfig.$int missing and ifconfig_$int not set;"
2331.1Slukem					warn "interface $int not configured."
2341.1Slukem				fi
2351.1Slukem				continue
2361.1Slukem			fi
2371.1Slukem			configured_interfaces="$configured_interfaces $int"
2381.1Slukem		done
2391.1Slukem		echo "."
2401.1Slukem	fi
2411.1Slukem
2421.44Sjdc	# Check $defaultroute, then /etc/mygate, for the name or address
2431.44Sjdc	# of my IPv4 gateway host. If using a name, that name must be in
2441.44Sjdc	# /etc/hosts.
2451.1Slukem	#
2461.20Snisimura	if [ -z "$defaultroute" ] && [ -f /etc/mygate ]; then
2471.46Schristos		defaultroute=$(cat /etc/mygate)
2481.1Slukem	fi
2491.1Slukem	if [ -n "$defaultroute" ]; then
2501.53Sreed		/sbin/route add default $defaultroute
2511.44Sjdc	fi
2521.44Sjdc
2531.44Sjdc	# Check $defaultroute6, then /etc/mygate6, for the name or address
2541.44Sjdc	# of my IPv6 gateway host. If using a name, that name must be in
2551.44Sjdc	# /etc/hosts.  Note that the gateway host address must be a link-local
2561.44Sjdc	# address if it is not using an stf* interface.
2571.44Sjdc	#
2581.44Sjdc	if [ -z "$defaultroute6" ] && [ -f /etc/mygate6 ]; then
2591.46Schristos		defaultroute6=$(cat /etc/mygate6)
2601.44Sjdc	fi
2611.44Sjdc	if [ -n "$defaultroute6" ]; then
2621.44Sjdc		if [ "$ip6mode" = "autohost" ]; then
2631.44Sjdc			echo
2641.44Sjdc			warn \
2651.44Sjdc	    "ip6mode is set to 'autohost' and a v6 default route is also set."
2661.44Sjdc		fi
2671.53Sreed		/sbin/route add -inet6 default $defaultroute6
2681.1Slukem	fi
2691.1Slukem
2701.48Scjs	echo -n "Adding interface aliases:"
2711.48Scjs
2721.1Slukem	# Check if each configured interface xxN has an $ifaliases_xxN variable
2731.1Slukem	# associated, then configure additional IP addresses for that interface.
2741.1Slukem	# The variable contains a list of "address netmask" pairs, with
2751.1Slukem	# "netmask" set to "-" if the interface default netmask is to be used.
2761.1Slukem	#
2771.1Slukem	# Note that $ifaliases_xxN works only with certain configurations and
2781.1Slukem	# considered not recommended.  Use /etc/ifconfig.xxN if possible.
2791.1Slukem	# 
2801.1Slukem	#
2811.48Scjs	for int in lo0 $configured_interfaces; do
2821.20Snisimura		eval args=\$ifaliases_$int
2831.1Slukem		if [ -n "$args" ]; then
2841.1Slukem			set -- $args
2851.1Slukem			while [ $# -ge 2 ]; do
2861.1Slukem				addr=$1 ; net=$2 ; shift 2
2871.1Slukem				if [ "$net" = "-" ]; then
2881.16Sjdolecek					# for compatibility only, obsolete
2891.53Sreed					/sbin/ifconfig $int inet alias $addr
2901.1Slukem				else
2911.53Sreed					/sbin/ifconfig $int inet alias $addr \
2921.1Slukem					    netmask $net
2931.1Slukem				fi
2941.48Scjs				echo -n " $int:$addr"
2951.1Slukem			done
2961.1Slukem		fi
2971.1Slukem	done
2981.1Slukem
2991.1Slukem	# /etc/ifaliases, if it exists, contains the names of additional IP
3001.1Slukem	# addresses for each interface. It is formatted as a series of lines
3011.1Slukem	# that contain
3021.1Slukem	#	address interface netmask
3031.1Slukem	#
3041.1Slukem	# Note that /etc/ifaliases works only with certain cases only and its
3051.1Slukem	# use is not recommended.  Use /etc/ifconfig.xxN instead.
3061.1Slukem	#
3071.1Slukem	#
3081.1Slukem	if [ -f /etc/ifaliases ]; then
3091.1Slukem		while read addr int net; do
3101.1Slukem			if [ -z "$net" ]; then
3111.16Sjdolecek				# for compatibility only, obsolete
3121.53Sreed				/sbin/ifconfig $int inet alias $addr
3131.1Slukem			else
3141.53Sreed				/sbin/ifconfig $int inet alias $addr netmask $net
3151.1Slukem			fi
3161.20Snisimura		done < /etc/ifaliases
3171.1Slukem	fi
3181.1Slukem
3191.48Scjs	echo
3201.48Scjs
3211.30Sitojun	# IPv6 interface autoconfiguration.
3221.1Slukem	#
3231.53Sreed	if /sbin/ifconfig lo0 inet6 >/dev/null 2>&1; then
3241.17Sitojun		# wait till DAD is completed. always invoke it in case
3251.17Sitojun		# if are configured manually by ifconfig
3261.17Sitojun		#
3271.53Sreed		dadcount=$(/sbin/sysctl -n net.inet6.ip6.dad_count 2>/dev/null)
3281.17Sitojun		sleep $dadcount
3291.17Sitojun		sleep 1
3301.17Sitojun
3311.1Slukem		if checkyesno rtsol; then
3321.1Slukem			if [ "$ip6mode" = "autohost" ]; then
3331.1Slukem				echo 'Sending router solicitation...'
3341.53Sreed				/sbin/rtsol $rtsol_flags
3351.1Slukem			else
3361.1Slukem				echo
3371.1Slukem				warn \
3381.1Slukem			    "ip6mode must be set to 'autohost' to use rtsol."
3391.1Slukem			fi
3401.17Sitojun
3411.18Sitojun			# wait till DAD is completed, for global addresses
3421.18Sitojun			# configured by router advert message.
3431.17Sitojun			#
3441.17Sitojun			sleep $dadcount
3451.17Sitojun			sleep 1
3461.1Slukem		fi
3471.42Schristos	fi
3481.42Schristos
3491.1Slukem	# XXX this must die
3501.1Slukem	if [ -s /etc/netstart.local ]; then
3511.1Slukem		sh /etc/netstart.local start
3521.1Slukem	fi
3531.1Slukem}
3541.1Slukem
3551.1Slukemnetwork_stop()
3561.1Slukem{
3571.1Slukem	echo "Stopping network."
3581.1Slukem
3591.1Slukem	# XXX this must die
3601.1Slukem	if [ -s /etc/netstart.local ]; then
3611.1Slukem		sh /etc/netstart.local stop
3621.1Slukem	fi
3631.1Slukem
3641.1Slukem	echo "Deleting aliases."
3651.1Slukem	if [ -f /etc/ifaliases ]; then
3661.1Slukem		while read addr int net; do
3671.53Sreed			/sbin/ifconfig $int inet delete $addr
3681.20Snisimura		done < /etc/ifaliases
3691.1Slukem	fi
3701.1Slukem
3711.53Sreed	for int in $(/sbin/ifconfig -lu); do
3721.20Snisimura		eval args=\$ifaliases_$int
3731.1Slukem		if [ -n "$args" ]; then
3741.1Slukem			set -- $args
3751.1Slukem			while [ $# -ge 2 ]; do
3761.1Slukem				addr=$1 ; net=$2 ; shift 2
3771.53Sreed				/sbin/ifconfig $int inet delete $addr
3781.1Slukem			done
3791.1Slukem		fi
3801.1Slukem	done
3811.1Slukem
3821.1Slukem	# down interfaces
3831.1Slukem	#
3841.1Slukem	echo -n 'Downing network interfaces:'
3851.1Slukem	if [ "$net_interfaces" != NO ]; then
3861.1Slukem		if checkyesno auto_ifconfig; then
3871.53Sreed			tmp=$(/sbin/ifconfig -l)
3881.1Slukem		else
3891.1Slukem			tmp="$net_interfaces"
3901.1Slukem		fi
3911.1Slukem		for int in $tmp; do
3921.20Snisimura			eval args=\$ifconfig_$int
3931.2Sveego			if [ -n "$args" ] || [ -f /etc/ifconfig.$int ]; then
3941.1Slukem				echo -n " $int"
3951.53Sreed				/sbin/dhcpcd -k $int 2> /dev/null
3961.53Sreed				/sbin/ifconfig $int down
3971.53Sreed				if /sbin/ifconfig $int destroy 2>/dev/null && \
3981.39Stron				   checkyesno ipfilter; then
3991.39Stron					# resync ipf(4)
4001.53Sreed					/sbin/ipf -y >/dev/null
4011.39Stron				fi
4021.1Slukem			fi
4031.1Slukem		done
4041.1Slukem		echo "."
4051.1Slukem	fi
4061.1Slukem
4071.1Slukem	# flush routes
4081.1Slukem	#
4091.53Sreed	/sbin/route -qn flush
4101.38Stron
4111.1Slukem}
4121.1Slukem
4131.47Slukemload_rc_config $name
4141.47Slukemload_rc_config_var dhclient dhclient
4151.47Slukemload_rc_config_var ipfilter ipfilter
4161.1Slukemrun_rc_command "$1"
417