xref: /openbsd/etc/netstart (revision e57a083b)
1df930be7Sderaadt#!/bin/sh -
2df930be7Sderaadt#
3*e57a083bSrpe#	$OpenBSD: netstart,v 1.160 2015/11/12 22:50:46 rpe Exp $
45116749bSrpe
55116749bSrpe# Turn off Strict Bourne shell mode.
65116749bSrpeset +o sh
78fc5e153Smillert
8*e57a083bSrpe# Strip comment lines from a file.
9*e57a083bSrpe# Strip leading and trailing whitespace if IFS is set.
10*e57a083bSrpe# Usage: stripcom /path/to/file
118fc5e153Smillertstripcom() {
12*e57a083bSrpe	local _file=$1 _line
13*e57a083bSrpe
14*e57a083bSrpe	[[ -f $_file ]] || return
15*e57a083bSrpe
16*e57a083bSrpe	while read _line; do
17*e57a083bSrpe		[[ -n ${_line%%#*} ]] && print -r -- "$_line"
18*e57a083bSrpe	done <$_file
198fc5e153Smillert}
2004e0ac27Smillert
21*e57a083bSrpe# Start a single interface.
22*e57a083bSrpe# Usage: ifstart if1
23dfc209d0Smiodifstart() {
24f5319bdcSderaadt	if=$1
25dfc209d0Smiod	# Interface names must be alphanumeric only.  We check to avoid
26dfc209d0Smiod	# configuring backup or temp files, and to catch the "*" case.
2752d1b2ceSrpe	[[ $if != +([[:alpha:]])+([[:digit:]]) ]] && return
28dfc209d0Smiod
29bc53e65aSderaadt	file=/etc/hostname.$if
3049352c7bStodd	if ! [ -f $file ]; then
3149352c7bStodd		echo "netstart: $file: No such file or directory"
3249352c7bStodd		return
3349352c7bStodd	fi
34300d0407Srpe	# Not using stat(1), we can't rely on having /usr yet.
3541e7db73Ssthen	set -A stat -- `ls -nL $file`
3641e7db73Ssthen	if [ "${stat[0]#???????} ${stat[2]} ${stat[3]}" != "--- 0 0" ]; then
37bc53e65aSderaadt		echo "WARNING: $file is insecure, fixing permissions"
3831ecad01Ssthen		chmod -LR o-rwx $file
3931ecad01Ssthen		chown -LR root.wheel $file
40bc53e65aSderaadt	fi
41d7c3aec1Srpe	# Check for ifconfig'able interface.
42d7c3aec1Srpe	(ifconfig $if || ifconfig $if create) >/dev/null 2>&1 || return
43dfc209d0Smiod
44300d0407Srpe	# Now parse the hostname.* file.
45dfc209d0Smiod	while :; do
46dfc209d0Smiod		if [ "$cmd2" ]; then
47dfc209d0Smiod			# We are carrying over from the 'read dt dtaddr'
48dfc209d0Smiod			# last time.
49dfc209d0Smiod			set -- $cmd2
50dfc209d0Smiod			af="$1" name="$2" mask="$3" bcaddr="$4" ext1="$5" cmd2=
51dfc209d0Smiod			# Make sure and get any remaining args in ext2,
52300d0407Srpe			# like the read below.
53dfc209d0Smiod			i=1
549e0429c5Ssimon			while [ $i -lt 6 -a -n "$1" ]; do shift; let i=i+1; done
55dfc209d0Smiod			ext2="$@"
56dfc209d0Smiod		else
57dfc209d0Smiod			# Read the next line or exit the while loop.
58dfc209d0Smiod			read af name mask bcaddr ext1 ext2 || break
59dfc209d0Smiod		fi
60300d0407Srpe		# $af can be "dhcp", "up", "rtsol", an address family, commands,
61300d0407Srpe		# or a comment.
62dfc209d0Smiod		case "$af" in
63300d0407Srpe		"#"*|"") # Skip comments and empty lines.
64dfc209d0Smiod			continue
65dfc209d0Smiod			;;
66300d0407Srpe		"!"*) # Parse commands.
67dfc209d0Smiod			cmd="${af#*!} ${name} ${mask} ${bcaddr} ${ext1} ${ext2}"
68dfc209d0Smiod			;;
69dfc209d0Smiod		"dhcp")
70dfc209d0Smiod			[ "$name" = "NONE" ] && name=
71dfc209d0Smiod			[ "$mask" = "NONE" ] && mask=
72dfc209d0Smiod			[ "$bcaddr" = "NONE" ] && bcaddr=
735141b41fSclaudio			cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 down"
7419d144d8Stodd			cmd="$cmd;dhclient $if"
757c4030c5Stodd			dhcpif="$dhcpif $if"
76dfc209d0Smiod			;;
77dfc209d0Smiod		"rtsol")
78f5319bdcSderaadt			rtsolif="$rtsolif $if"
7919d144d8Stodd			cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 up"
80dfc209d0Smiod			;;
81dfc209d0Smiod		*)
82dfc209d0Smiod			read dt dtaddr
83dfc209d0Smiod			if [ "$name"  = "alias" ]; then
84300d0407Srpe				# Perform a 'shift' of sorts.
85dfc209d0Smiod				alias=$name
86dfc209d0Smiod				name=$mask
87dfc209d0Smiod				mask=$bcaddr
88dfc209d0Smiod				bcaddr=$ext1
89dfc209d0Smiod				ext1=$ext2
90dfc209d0Smiod				ext2=
91dfc209d0Smiod			else
92dfc209d0Smiod				alias=
93dfc209d0Smiod			fi
94f5319bdcSderaadt			cmd="ifconfig $if $af $alias $name"
95dfc209d0Smiod			case "$dt" in
96dfc209d0Smiod			dest)
97dfc209d0Smiod				cmd="$cmd $dtaddr"
98dfc209d0Smiod				;;
9942a8ea81Stodd			*)
100dfc209d0Smiod				cmd2="$dt $dtaddr"
101dfc209d0Smiod				;;
102dfc209d0Smiod			esac
103dfc209d0Smiod			case $af in
104dfc209d0Smiod			inet)
1052817040cStodd				if [ ! -n "$name" ]; then
1062817040cStodd					echo "/etc/hostname.$if: inet alone is invalid"
1072817040cStodd					return
1082817040cStodd				fi
109dfc209d0Smiod				[ "$mask" ] && cmd="$cmd netmask $mask"
110dfc209d0Smiod				if [ "$bcaddr" -a "X$bcaddr" != "XNONE" ]; then
111dfc209d0Smiod					cmd="$cmd broadcast $bcaddr"
112dfc209d0Smiod				fi
113dfc209d0Smiod				;;
1142817040cStodd			inet6)
1152817040cStodd				if [ ! -n "$name" ]; then
1162817040cStodd					echo "/etc/hostname.$if: inet6 alone is invalid"
1172817040cStodd					return
1182817040cStodd				fi
1192817040cStodd				[ "$mask" ] && cmd="$cmd prefixlen $mask"
120dfc209d0Smiod				cmd="$cmd $bcaddr"
121dfc209d0Smiod				;;
122dfc209d0Smiod			*)
123dfc209d0Smiod				cmd="$cmd $mask $bcaddr"
124dfc209d0Smiod				;;
125dfc209d0Smiod			esac
126071f497cSmpi			cmd="$cmd $ext1 $ext2"
127dfc209d0Smiod			;;
128dfc209d0Smiod		esac
129dfc209d0Smiod		eval "$cmd"
130f5319bdcSderaadt	done </etc/hostname.$if
131dfc209d0Smiod}
132dfc209d0Smiod
1339ac6b043Stodd# Start multiple:
134300d0407Srpe# Usage: ifmstart "if1 if2" "if3 if4"
135300d0407Srpe#   Start "$1" interfaces in order or all interfaces if empty.
136300d0407Srpe#   Don't start "$2" interfaces.
1379ac6b043Stoddifmstart() {
1389ac6b043Stodd	for sif in ${1:-ALL}; do
1399ac6b043Stodd		for hn in /etc/hostname.*; do
140300d0407Srpe			# Strip off /etc/hostname. prefix.
1419ac6b043Stodd			if=${hn#/etc/hostname.}
142c1cf6742Srpe			[ "$if" = "*" ] && continue
1439ac6b043Stodd
144300d0407Srpe			# Skip unwanted ifs.
1459ac6b043Stodd			s=""
1469ac6b043Stodd			for xf in $2; do
147c1cf6742Srpe				[ "$xf" = "${if%%[0-9]*}" ] && s="1" && break
1489ac6b043Stodd			done
149c1cf6742Srpe			[ "$s" = "1" ] && continue
1509ac6b043Stodd
151300d0407Srpe			# Start wanted ifs.
152c1cf6742Srpe			[ "$sif" = "ALL" -o "$sif" = "${if%%[0-9]*}" ] &&
153c1cf6742Srpe				ifstart $if
1549ac6b043Stodd		done
1559ac6b043Stodd	done
1569ac6b043Stodd}
1579ac6b043Stodd
1586125fd66Ssthen# IPv6 autoconf the interfaces in the list at $rtsolif
1596125fd66Ssthen# Usage: ifautoconf
1606125fd66Ssthenifautoconf() {
1616125fd66Ssthen	# $ip6kernel will not have been set if we were invoked with a
1626125fd66Ssthen	# list of interface names
1636125fd66Ssthen	if ifconfig lo0 inet6 >/dev/null 2>&1; then
1646125fd66Ssthen		for curif in $rtsolif; do
1656125fd66Ssthen			ifconfig $curif inet6 autoconf
1666125fd66Ssthen		done
1676125fd66Ssthen	fi
1686125fd66Ssthen}
1696125fd66Ssthen
170a035c1adSrpe# Get network related vars from rc.conf using the parsing routine from rc.subr.
171a035c1adSrpeFUNCS_ONLY=1 . /etc/rc.d/rc.subr
1728799e9c8Srobert_rc_parse_conf
1730dc37902Sangelos
174dfc209d0Smiod# If we were invoked with a list of interface names, just reconfigure these
175dfc209d0Smiod# interfaces (or bridges) and return.
1760a295e45Srpeif (($# > 0)); then
1770a295e45Srpe	for _if; do ifstart $_if; done
1786125fd66Ssthen	ifautoconf
179dfc209d0Smiod	return
180dfc209d0Smiodfi
181dfc209d0Smiod
182dfc209d0Smiod# Otherwise, process with the complete network initialization.
183dfc209d0Smiod
184300d0407Srpe# /etc/myname contains my symbolic name.
1850a295e45Srpe[[ -f /etc/myname ]] && hostname "$(stripcom /etc/myname)"
18637bbdc83Shenning
1874fbd02fcSsobrado# Set the address for the loopback interface.  Bringing the interface up,
1884fbd02fcSsobrado# automatically invokes the IPv6 address ::1.
189d216f73bShenningifconfig lo0 inet 127.0.0.1/8
19098c28033Skstailey
1913d8fed7cSitojunif ifconfig lo0 inet6 >/dev/null 2>&1; then
1923d8fed7cSitojun	# IPv6 configurations.
1933d8fed7cSitojun	ip6kernel=YES
1943d8fed7cSitojun
195dfc209d0Smiod	# Disallow link-local unicast dest without outgoing scope identifiers.
19603056e2eSderaadt	route -qn add -inet6 fe80:: -prefixlen 10 ::1 -reject >/dev/null
19792aceabbSitojun
198dfc209d0Smiod	# Disallow site-local unicast dest without outgoing scope identifiers.
19992aceabbSitojun	# If you configure site-locals without scope id (it is permissible
20092aceabbSitojun	# config for routers that are not on scope boundary), you may want
20192aceabbSitojun	# to comment the line out.
20203056e2eSderaadt	route -qn add -inet6 fec0:: -prefixlen 10 ::1 -reject >/dev/null
20392aceabbSitojun
204dfc209d0Smiod	# Disallow "internal" addresses to appear on the wire.
20503056e2eSderaadt	route -qn add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject >/dev/null
20692aceabbSitojun
207dfc209d0Smiod	# Disallow packets to malicious IPv4 compatible prefix.
20803056e2eSderaadt	route -qn add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject >/dev/null
20903056e2eSderaadt	route -qn add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject >/dev/null
21003056e2eSderaadt	route -qn add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject >/dev/null
21103056e2eSderaadt	route -qn add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject >/dev/null
21292aceabbSitojun
213dfc209d0Smiod	# Disallow packets to malicious 6to4 prefix.
21403056e2eSderaadt	route -qn add -inet6 2002:e000:: -prefixlen 20 ::1 -reject >/dev/null
21503056e2eSderaadt	route -qn add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject >/dev/null
21603056e2eSderaadt	route -qn add -inet6 2002:0000:: -prefixlen 24 ::1 -reject >/dev/null
21703056e2eSderaadt	route -qn add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject >/dev/null
21892aceabbSitojun
219a4ee3723Sitojun	# Disallow packets without scope identifier.
220a4ee3723Sitojun	route -qn add -inet6 ff01:: -prefixlen 16 ::1 -reject >/dev/null
221a4ee3723Sitojun	route -qn add -inet6 ff02:: -prefixlen 16 ::1 -reject >/dev/null
222a4ee3723Sitojun
22392aceabbSitojun	# Completely disallow packets to IPv4 compatible prefix.
224300d0407Srpe	#
22592aceabbSitojun	# This may conflict with RFC1933 under following circumstances:
22692aceabbSitojun	# (1) An IPv6-only KAME node tries to originate packets to IPv4
2275e268fadSderaadt	#     compatible destination.  The KAME node has no IPv4 compatible
22892aceabbSitojun	#     support.  Under RFC1933, it should transmit native IPv6
22992aceabbSitojun	#     packets toward IPv4 compatible destination, hoping it would
23092aceabbSitojun	#     reach a router that forwards the packet toward auto-tunnel
23192aceabbSitojun	#     interface.
2325e268fadSderaadt	# (2) An IPv6-only node originates a packet to an IPv4 compatible
23392aceabbSitojun	#     destination.  A KAME node is acting as an IPv6 router, and
23492aceabbSitojun	#     asked to forward it.
235300d0407Srpe	#
2365e268fadSderaadt	# Due to rare use of IPv4 compatible addresses, and security issues
23792aceabbSitojun	# with it, we disable it by default.
23803056e2eSderaadt	route -qn add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject >/dev/null
23982c17b75Sitojun
24082c17b75Sitojun	rtsolif=""
2413d8fed7cSitojunelse
2423d8fed7cSitojun	ip6kernel=NO
2433d8fed7cSitojunfi
2443d8fed7cSitojun
245df930be7Sderaadt
2469ac6b043Stodd# Configure all the non-loopback interfaces which we know about, but
2474eb97611Sderaadt# do not start interfaces which must be delayed. Refer to hostname.if(5)
248c2c86627Sclaudioifmstart "" "trunk svlan vlan carp gif gre pfsync pppoe tun tap bridge pflow"
24982c17b75Sitojun
2504bdcd471Sbrad# The trunk interfaces need to come up first in this list.
251f45bd3bdSmpf# The (s)vlan interfaces need to come up after trunk.
2524bdcd471Sbrad# Configure all the carp interfaces which we know about before default route.
253f45bd3bdSmpfifmstart "trunk svlan vlan carp"
2544bdcd471Sbrad
2556125fd66Ssthen# Now that $rtsolif has been populated, IPv6 autoconf those interfaces
2566125fd66Ssthenifautoconf
25782c17b75Sitojun
25880819bdcStodd# Look for default routes in /etc/mygate.
2597c4030c5Stodd[[ -z $dhcpif ]] && stripcom /etc/mygate | while read gw; do
2607c4030c5Stodd		[[ $gw == @(*:*) ]] && continue
2612fcef345Sderaadt		route -qn delete default >/dev/null 2>&1
2627c4030c5Stodd		route -qn add -host default $gw && break
2630408d58aStodddone
2647c4030c5Stodd[[ -z $rtsolif ]] && stripcom /etc/mygate | while read gw; do
2657c4030c5Stodd		[[ $gw == !(*:*) ]] && continue
2667c4030c5Stodd		route -qn delete -inet6 default >/dev/null 2>&1
2677c4030c5Stodd		route -qn add -host -inet6 default $gw && break
2687c4030c5Stodddone
269cf3860a5Sderaadt
270745634aaSniklas# Multicast routing.
271745634aaSniklas#
272745634aaSniklas# The routing to the 224.0.0.0/4 net is setup according to these rules:
273745634aaSniklas# multicast_host	multicast_router	route		comment
274745634aaSniklas# NO			NO			-reject		no multicast
275745634aaSniklas# NO			YES			none installed	daemon will run
276745634aaSniklas# YES/interface		NO			-interface	YES=def. iface
277745634aaSniklas#	   Any other combination		-reject		config error
278705fcffdSreykroute -qn delete 224.0.0.0/4 >/dev/null 2>&1
279745634aaSniklascase "$multicast_host:$multicast_router" in
280745634aaSniklasNO:NO)
281f4b4b73bSderaadt	route -qn add -net 224.0.0.0/4 -interface 127.0.0.1 -reject >/dev/null
282fe32e9eaSderaadt	;;
283745634aaSniklasNO:YES)
284745634aaSniklas	;;
285745634aaSniklas*:NO)
2860a295e45Srpe	maddr=$(if [[ $multicast_host == YES ]]; then
287f4b4b73bSderaadt		ed -s '!route -qn show -inet' <<EOF
288745634aaSniklas/^default/p
289745634aaSniklasEOF
290745634aaSniklas	else
291745634aaSniklas		ed -s "!ifconfig $multicast_host" <<EOF
292745634aaSniklas/^	inet /p
293745634aaSniklasEOF
2940a295e45Srpe	fi 2>/dev/null)
2950a295e45Srpe	if [[ -n $maddr ]]; then
296705fcffdSreyk		set $maddr
297f4b4b73bSderaadt		route -qn add -net 224.0.0.0/4 -interface $2 >/dev/null
298705fcffdSreyk	else
299705fcffdSreyk		route -qn add -net 224.0.0.0/4 -interface \
300705fcffdSreyk			127.0.0.1 -reject >/dev/null
301705fcffdSreyk	fi
302fe32e9eaSderaadt	;;
303745634aaSniklas*:*)
304745634aaSniklas	echo 'config error, multicasting disabled until rc.conf is fixed'
305f4b4b73bSderaadt	route -qn add -net 224.0.0.0/4 -interface 127.0.0.1 -reject >/dev/null
306fe32e9eaSderaadt	;;
307745634aaSniklasesac
308dfc209d0Smiod
309dfc209d0Smiod
310f002925aSflorian# Configure PPPoE, GIF, GRE, TUN and PFLOW interfaces, delayed because they
311f002925aSflorian# require routes to be set. TUN might depend on PPPoE, and GIF or GRE may
312f002925aSflorian# depend on either of them. PFLOW might bind to ip addresses configured
313f002925aSflorian# on either of them.
314c2c86627Sclaudioifmstart "pppoe tun tap gif gre bridge pflow"
315dfc209d0Smiod
316300d0407Srpe# Reject 127/8 other than 127.0.0.1.
3178f8fdbefSderaadtroute -qn add -net 127 127.0.0.1 -reject >/dev/null
3188f8fdbefSderaadt
3190a295e45Srpeif [[ $ip6kernel == YES ]]; then
320300d0407Srpe	# This is to make sure DAD is completed before going further.
321c653ce7bSmarkus	count=0
3220a295e45Srpe	while ((count++ < 10 && $(sysctl -n net.inet6.ip6.dad_pending) != 0)); do
323c653ce7bSmarkus		sleep 1
324c653ce7bSmarkus	done
325089287c3Sdavidfi
326