network.subr revision 168033
125184Sjkh#
2113674Smtm# Copyright (c) 2003 The FreeBSD Project. All rights reserved.
3113674Smtm#
4113674Smtm# Redistribution and use in source and binary forms, with or without
5113674Smtm# modification, are permitted provided that the following conditions
6113674Smtm# are met:
7113674Smtm# 1. Redistributions of source code must retain the above copyright
8113674Smtm#    notice, this list of conditions and the following disclaimer.
9113674Smtm# 2. Redistributions in binary form must reproduce the above copyright
10113674Smtm#    notice, this list of conditions and the following disclaimer in the
11113674Smtm#    documentation and/or other materials provided with the distribution.
12113674Smtm#
13113674Smtm# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
14113674Smtm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15113674Smtm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16113674Smtm# ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
17113674Smtm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18113674Smtm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19113674Smtm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20113674Smtm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21113674Smtm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22113674Smtm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23113674Smtm# SUCH DAMAGE.
24113674Smtm#
2550472Speter# $FreeBSD: head/etc/network.subr 168033 2007-03-29 21:42:19Z ache $
2666830Sobrien#
2725184Sjkh
28113674Smtm#
29113674Smtm# Subroutines commonly used from network startup scripts.
30113674Smtm# Requires that rc.conf be loaded first.
31113674Smtm#
3225184Sjkh
33113674Smtm# ifconfig_up if
34113674Smtm#	Evaluate ifconfig(8) arguments for interface $if and
35113674Smtm#	run ifconfig(8) with those arguments. It returns 0 if
36113674Smtm#	arguments were found and executed or 1 if the interface
37147088Sbrooks#	had no arguments.  Pseudo arguments DHCP and WPA are handled
38147088Sbrooks#	here.
39113674Smtm#
40113674Smtmifconfig_up()
41113674Smtm{
42147088Sbrooks	_cfg=1
43147088Sbrooks
44147088Sbrooks	ifconfig_args=`ifconfig_getargs $1`
45113674Smtm	if [ -n "${ifconfig_args}" ]; then
46149726Sbrooks		ifconfig $1 up
47157706Sbrooks		ifconfig $1 ${ifconfig_args}
48147088Sbrooks		_cfg=0
49113674Smtm	fi
50147088Sbrooks
51147088Sbrooks	if wpaif $1; then
52149726Sbrooks		if [ $_cfg -ne 0 ] ; then
53149726Sbrooks			ifconfig $1 up
54149726Sbrooks		fi
55147682Sbrooks		/etc/rc.d/wpa_supplicant start $1
56147088Sbrooks		_cfg=0		# XXX: not sure this should count
57147088Sbrooks	fi
58147088Sbrooks
59147088Sbrooks	if dhcpif $1; then
60149726Sbrooks		if [ $_cfg -ne 0 ] ; then
61149726Sbrooks			ifconfig $1 up
62149726Sbrooks		fi
63157706Sbrooks		if syncdhcpif $1; then
64157706Sbrooks			/etc/rc.d/dhclient start $1
65157706Sbrooks		fi
66147088Sbrooks		_cfg=0
67147088Sbrooks	fi
68147088Sbrooks
69147121Sbrooks	return $_cfg
70113674Smtm}
7125184Sjkh
72116029Smtm# ifconfig_down if
73161386Sbrooks#	returns 1 if wpa_supplicant or dhclient was stopped or
74161386Sbrooks#	the interface exists.
75116029Smtm#
76116029Smtmifconfig_down()
77116029Smtm{
78116029Smtm	[ -z "$1" ] && return 1
79147121Sbrooks	_cfg=1
80116029Smtm
81147088Sbrooks	if wpaif $1; then
82147682Sbrooks		/etc/rc.d/wpa_supplicant stop $1
83147121Sbrooks		_cfg=0
84147088Sbrooks	fi
85147088Sbrooks
86147088Sbrooks	if dhcpif $1; then
87147088Sbrooks		/etc/rc.d/dhclient stop $1
88147088Sbrooks		_cfg=0
89147088Sbrooks	fi
90147088Sbrooks
91161386Sbrooks	if ifexists $1; then
92161386Sbrooks		ifconfig $1 down
93161386Sbrooks		_cfg=0
94161386Sbrooks	fi
95157706Sbrooks
96147121Sbrooks	return $_cfg
97116029Smtm}
98116029Smtm
99157706Sbrooks# get_if_var if var [default]
100157706Sbrooks#       Return the value of the pseudo-hash corresponding to $if where
101157706Sbrooks#       $var is a string containg the sub-string "IF" which will be
102157706Sbrooks#       replaced with $if after the characters defined in _punct are
103157706Sbrooks#       replaced with '_'. If the variable is unset, replace it with
104157706Sbrooks#       $default if given.
105157706Sbrooksget_if_var()
106157706Sbrooks{
107157706Sbrooks	if [ $# -ne 2 -a $# -ne 3 ]; then
108157706Sbrooks		err 3 'USAGE: get_if_var name var [default]'
109157706Sbrooks	fi
110157706Sbrooks
111157706Sbrooks	_if=$1
112157706Sbrooks	_punct=". - / +"
113157736Sbrooks	for _punct_c in $_punct; do
114157706Sbrooks		_if=`ltr ${_if} ${_punct_c} '_'`
115157706Sbrooks	done
116157706Sbrooks	_var=$2
117157706Sbrooks	_default=$3
118157706Sbrooks
119157706Sbrooks	prefix=${_var%%IF*}
120157706Sbrooks	suffix=${_var##*IF}
121168033Sache	eval echo \${${prefix}${_if}${suffix}-${_default}}
122157706Sbrooks}
123157706Sbrooks
124147088Sbrooks# _ifconfig_getargs if
125147088Sbrooks#	Echos the arguments for the supplied interface to stdout.
126147088Sbrooks#	returns 1 if empty.  In general, ifconfig_getargs should be used
127147088Sbrooks#	outside this file.
128147088Sbrooks_ifconfig_getargs()
129147088Sbrooks{
130147088Sbrooks	_ifn=$1
131147088Sbrooks	if [ -z "$_ifn" ]; then
132147088Sbrooks		return 1
133147088Sbrooks	fi
134147088Sbrooks
135157706Sbrooks	get_if_var $_ifn ifconfig_IF "$ifconfig_DEFAULT"
136147088Sbrooks}
137147088Sbrooks
138147088Sbrooks# ifconfig_getargs if
139147088Sbrooks#	Takes the result from _ifconfig_getargs and removes pseudo
140147088Sbrooks#	args such as DHCP and WPA.
141147088Sbrooksifconfig_getargs()
142147088Sbrooks{
143147088Sbrooks	_tmpargs=`_ifconfig_getargs $1`
144147088Sbrooks	if [ $? -eq 1 ]; then
145147088Sbrooks		return 1
146147088Sbrooks	fi
147147088Sbrooks	_args=
148147088Sbrooks
149147088Sbrooks	for _arg in $_tmpargs; do
150147088Sbrooks		case $_arg in
151157706Sbrooks		[Dd][Hh][Cc][Pp]) ;;
152157706Sbrooks		[Nn][Oo][Aa][Uu][Tt][Oo]) ;;
153157706Sbrooks		[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;;
154157706Sbrooks		[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;;
155157706Sbrooks		[Ww][Pp][Aa]) ;;
156147088Sbrooks		*)
157147088Sbrooks			_args="$_args $_arg"
158147088Sbrooks			;;
159147088Sbrooks		esac
160147088Sbrooks	done
161147088Sbrooks
162147088Sbrooks	echo $_args
163147088Sbrooks}
164147088Sbrooks
165149401Sbrooks# autoif
166149401Sbrooks#	Returns 0 if the interface should be automaticly configured at
167149401Sbrooks#	boot time and 1 otherwise.
168149401Sbrooksautoif()
169149401Sbrooks{
170149401Sbrooks	_tmpargs=`_ifconfig_getargs $1`
171149401Sbrooks	for _arg in $_tmpargs; do
172149401Sbrooks		case $_arg in
173149401Sbrooks		[Nn][Oo][Aa][Uu][Tt][Oo])
174149401Sbrooks			return 1
175149401Sbrooks			;;
176149401Sbrooks		esac
177149401Sbrooks	done
178149401Sbrooks	return 0
179149401Sbrooks}
180149401Sbrooks
181147088Sbrooks# dhcpif if
182147088Sbrooks#	Returns 0 if the interface is a DHCP interface and 1 otherwise.
183147088Sbrooksdhcpif()
184147088Sbrooks{
185147088Sbrooks	_tmpargs=`_ifconfig_getargs $1`
186147088Sbrooks	for _arg in $_tmpargs; do
187147088Sbrooks		case $_arg in
188147088Sbrooks		[Dd][Hh][Cc][Pp])
189147088Sbrooks			return 0
190147088Sbrooks			;;
191157706Sbrooks		[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
192157706Sbrooks			return 0
193157706Sbrooks			;;
194157706Sbrooks		[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
195157706Sbrooks			return 0
196157706Sbrooks			;;
197147088Sbrooks		esac
198147088Sbrooks	done
199147088Sbrooks	return 1
200147088Sbrooks}
201147088Sbrooks
202157706Sbrooks# syncdhcpif
203157706Sbrooks#	Returns 0 if the interface should be configured synchronously and
204157706Sbrooks#	1 otherwise.
205157706Sbrookssyncdhcpif()
206157706Sbrooks{
207157706Sbrooks	_tmpargs=`_ifconfig_getargs $1`
208157706Sbrooks	for _arg in $_tmpargs; do
209157706Sbrooks		case $_arg in
210157706Sbrooks		[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
211157706Sbrooks			return 1
212157706Sbrooks			;;
213157706Sbrooks		[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
214157706Sbrooks			return 0
215157706Sbrooks			;;
216157706Sbrooks		esac
217157706Sbrooks	done
218157737Sbrooks	if checkyesno synchronous_dhclient; then
219157706Sbrooks		return 0
220157706Sbrooks	else
221157706Sbrooks		return 1
222157706Sbrooks	fi
223157706Sbrooks}
224157706Sbrooks
225147088Sbrooks# wpaif if
226147088Sbrooks#	Returns 0 if the interface is a WPA interface and 1 otherwise.
227147088Sbrookswpaif()
228147088Sbrooks{
229147088Sbrooks	_tmpargs=`_ifconfig_getargs $1`
230147088Sbrooks	for _arg in $_tmpargs; do
231147088Sbrooks		case $_arg in
232147088Sbrooks		[Ww][Pp][Aa])
233147088Sbrooks			return 0
234147088Sbrooks			;;
235147088Sbrooks		esac
236147088Sbrooks	done
237147088Sbrooks	return 1
238147088Sbrooks}
239147088Sbrooks
240162490Sbrooks# ipv6if if
241162490Sbrooks#	Returns 0 if the interface should be configured for IPv6 and
242162490Sbrooks#	1 otherwise.
243162490Sbrooksipv6if()
244162490Sbrooks{
245162490Sbrooks	if ! checkyesno ipv6_enable; then
246162490Sbrooks		return 1
247162490Sbrooks	fi
248162490Sbrooks	case "${ipv6_network_interfaces}" in
249162490Sbrooks	[Aa][Uu][Tt][Oo])
250162490Sbrooks		return 0
251162490Sbrooks		;;
252162490Sbrooks	''|[Nn][Oo][Nn][Ee])
253162490Sbrooks		return 1
254162490Sbrooks		;;
255162490Sbrooks	esac
256162490Sbrooks	for v6if in ${ipv6_network_interfaces}; do
257162490Sbrooks		if [ "${v6if}" = "${1}" ]; then
258162490Sbrooks			return 0
259162490Sbrooks		fi
260162490Sbrooks	done
261162490Sbrooks	return 1
262162490Sbrooks}
263162490Sbrooks
264161386Sbrooks# ifexists if
265161386Sbrooks#	Returns 0 if the interface exists and 1 otherwise.
266161386Sbrooksifexists()
267161386Sbrooks{
268161386Sbrooks	ifconfig $1 > /dev/null 2>&1
269161386Sbrooks}
270161386Sbrooks
271152441Sbrooks# ipv4_up if
272152441Sbrooks#  add IPv4 addresses to the interface $if 
273152441Sbrooksipv4_up()
274152441Sbrooks{
275152441Sbrooks	_if=$1
276152441Sbrooks	ifalias_up ${_if}
277152441Sbrooks	ipv4_addrs_common ${_if} alias
278152441Sbrooks}
279152441Sbrooks
280152441Sbrooks# ipv4_down if
281152441Sbrooks#  remove IPv4 addresses from the interface $if
282152441Sbrooksipv4_down()
283152441Sbrooks{
284152441Sbrooks	_if=$1
285161386Sbrooks	_ifs="^"
286161386Sbrooks	_ret=1
287161386Sbrooks
288161386Sbrooks	ifexists ${_if} || return 1
289161386Sbrooks
290161386Sbrooks	inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`"
291161386Sbrooks
292161386Sbrooks	oldifs="$IFS"
293161386Sbrooks	IFS="$_ifs"
294161386Sbrooks	for _inet in $inetList ; do
295161386Sbrooks		# get rid of extraneous line
296161386Sbrooks		[ -z "$_inet" ] && break
297161386Sbrooks
298161386Sbrooks		_inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'`
299161386Sbrooks
300161386Sbrooks		IFS="$oldifs"
301161386Sbrooks		ifconfig ${_if} ${_inet} delete
302161386Sbrooks		IFS="$_ifs"
303161386Sbrooks		_ret=0
304161386Sbrooks	done
305161386Sbrooks	IFS="$oldifs"
306161386Sbrooks
307161386Sbrooks	ifalias_down ${_if} && _ret=0
308161386Sbrooks	ipv4_addrs_common ${_if} -alias && _ret=0
309161386Sbrooks
310161386Sbrooks	return $_ret
311152441Sbrooks}
312152441Sbrooks
313152441Sbrooks# ipv4_addrs_common if action
314152441Sbrooks#   Evaluate the ifconfig_if_ipv4 arguments for interface $if
315152441Sbrooks#   and use $action to add or remove IPv4 addresses from $if.
316152441Sbrooksipv4_addrs_common()
317152441Sbrooks{  
318152441Sbrooks	_ret=1
319152441Sbrooks	_if=$1
320152441Sbrooks	_action=$2
321152441Sbrooks    
322152441Sbrooks	# get ipv4-addresses
323157706Sbrooks	cidr_addr=`get_if_var $_if ipv4_addrs_IF`
324152441Sbrooks    
325152441Sbrooks	for _cidr in ${cidr_addr}; do
326152441Sbrooks		_ipaddr=${_cidr%%/*}
327152441Sbrooks		_netmask="/"${_cidr##*/}
328152441Sbrooks		_range=${_ipaddr##*.}
329152441Sbrooks		_ipnet=${_ipaddr%.*}
330152441Sbrooks		_iplow=${_range%-*}
331152441Sbrooks		_iphigh=${_range#*-}
332152441Sbrooks
333152441Sbrooks		# clear netmask when removing aliases
334152441Sbrooks		if [ "${_action}" = "-alias" ]; then
335152441Sbrooks			_netmask=""
336152441Sbrooks		fi
337152441Sbrooks        
338152441Sbrooks		_ipcount=${_iplow}
339152441Sbrooks		while [ "${_ipcount}" -le "${_iphigh}" ]; do
340152441Sbrooks			eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}"
341152441Sbrooks			_ipcount=$((${_ipcount}+1))
342152441Sbrooks			_ret=0
343152441Sbrooks
344152441Sbrooks			# only the first ipaddr in a subnet need the real netmask
345152441Sbrooks			if [ "${_action}" != "-alias" ]; then
346152441Sbrooks				_netmask="/32"
347152441Sbrooks			fi
348152441Sbrooks		done
349152441Sbrooks	done
350152441Sbrooks	return $_ret
351152441Sbrooks}
352152441Sbrooks
353113674Smtm# ifalias_up if
354113674Smtm#	Configure aliases for network interface $if.
355113674Smtm#	It returns 0 if at least one alias was configured or
356113674Smtm#	1 if there were none.
357113674Smtm#
358113674Smtmifalias_up()
359113674Smtm{
360113674Smtm	_ret=1
361113674Smtm	alias=0
362113674Smtm	while : ; do
363157706Sbrooks		ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
364113674Smtm		if [ -n "${ifconfig_args}" ]; then
365113674Smtm			ifconfig $1 ${ifconfig_args} alias
366113674Smtm			alias=$((${alias} + 1))
367113674Smtm			_ret=0
368113674Smtm		else
369113674Smtm			break
370113674Smtm		fi
371113674Smtm	done
372113674Smtm	return $_ret
373113674Smtm}
374100280Sgordon
375116029Smtm#ifalias_down if
376116029Smtm#	Remove aliases for network interface $if.
377116029Smtm#	It returns 0 if at least one alias was removed or
378116029Smtm#	1 if there were none.
379116029Smtm#
380116029Smtmifalias_down()
381116029Smtm{
382116029Smtm	_ret=1
383116029Smtm	alias=0
384116029Smtm	while : ; do
385157706Sbrooks		ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
386116029Smtm		if [ -n "${ifconfig_args}" ]; then
387116029Smtm			ifconfig $1 ${ifconfig_args} -alias
388116029Smtm			alias=$((${alias} + 1))
389116029Smtm			_ret=0
390116029Smtm		else
391116029Smtm			break
392116029Smtm		fi
393116029Smtm	done
394116029Smtm	return $_ret
395116029Smtm}
396116029Smtm
397113674Smtm# ifscript_up if
398113674Smtm#	Evaluate a startup script for the $if interface.
399113674Smtm#	It returns 0 if a script was found and processed or
400113674Smtm#	1 if no script was found.
401113674Smtm#
402113674Smtmifscript_up()
403100280Sgordon{
404113674Smtm	if [ -r /etc/start_if.$1 ]; then
405113674Smtm		. /etc/start_if.$1
406113674Smtm		return 0
407113674Smtm	fi
408113674Smtm	return 1
409100280Sgordon}
410100280Sgordon
411116029Smtm# ifscript_down if
412116029Smtm#	Evaluate a shutdown script for the $if interface.
413116029Smtm#	It returns 0 if a script was found and processed or
414116029Smtm#	1 if no script was found.
415116029Smtm#
416116029Smtmifscript_down()
417116029Smtm{
418116029Smtm	if [ -r /etc/stop_if.$1 ]; then
419116029Smtm		. /etc/stop_if.$1
420116029Smtm		return 0
421116029Smtm	fi
422116029Smtm	return 1
423116029Smtm}
424116029Smtm
425113674Smtm# Create cloneable interfaces.
426113674Smtm#
427113674Smtmclone_up()
428100280Sgordon{
429113674Smtm	_prefix=
430113674Smtm	_list=
431113674Smtm	for ifn in ${cloned_interfaces}; do
432113674Smtm		ifconfig ${ifn} create
433116774Skuriyama		if [ $? -eq 0 ]; then
434113674Smtm			_list="${_list}${_prefix}${ifn}"
435113674Smtm			[ -z "$_prefix" ] && _prefix=' '
436113674Smtm		fi
437113674Smtm	done
438113674Smtm	debug "Cloned: ${_list}"
439113674Smtm}
440100280Sgordon
441113674Smtm# Destroy cloned interfaces. Destroyed interfaces are echoed
442113674Smtm# to standard output.
443113674Smtm#
444113674Smtmclone_down()
445113674Smtm{
446113674Smtm	_prefix=
447113674Smtm	_list=
448113674Smtm	for ifn in ${cloned_interfaces}; do
449113674Smtm		ifconfig ${ifn} destroy
450116774Skuriyama		if [ $? -eq 0 ]; then
451113674Smtm			_list="${_list}${_prefix}${ifn}"
452113674Smtm			[ -z "$_prefix" ] && _prefix=' '
453113674Smtm		fi
454113674Smtm	done
455113674Smtm	debug "Destroyed clones: ${_list}"
456100280Sgordon}
457100280Sgordon
458166583Sflz# Create netgraph nodes.
459166583Sflz#
460166583Sflzng_mkpeer() {
461166583Sflz	ngctl -f - 2> /dev/null <<EOF
462166583Sflzmkpeer $*
463166583Sflzmsg dummy nodeinfo
464166583SflzEOF
465166583Sflz}
466166583Sflz
467166583Sflzng_create_one() {
468166583Sflz	ng_mkpeer $* | while read line; do
469166583Sflz		t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'`
470166583Sflz		if [ -n "${t}" ]; then
471166583Sflz			echo ${t}
472166583Sflz			return
473166583Sflz		fi
474166583Sflz	done
475166583Sflz}
476166583Sflz
477113674Smtmgif_up() {
478166583Sflz	# The following must be removed once RELENG_7 is branched.
479100282Sdougb	case ${gif_interfaces} in
480166583Sflz	[Nn][Oo])
481166583Sflz		warn "gif_interfaces=\"NO\" is deprecated, use gif_interfaces=\"\" instead."
482166583Sflz		gif_interfaces=""
483100282Sdougb		;;
484166583Sflz	esac
485166583Sflz
486166583Sflz	for i in ${gif_interfaces}; do
487166583Sflz		peers=`get_if_var $i gifconfig_IF`
488166583Sflz		case ${peers} in
489166583Sflz		'')
490166583Sflz			continue
491166583Sflz			;;
492166583Sflz		*)
493166583Sflz			ifconfig $i create >/dev/null 2>&1
494166583Sflz			ifconfig $i tunnel ${peers}
495166583Sflz			ifconfig $i up
496166583Sflz			;;
497166583Sflz		esac
498166583Sflz	done
499166583Sflz}
500166583Sflz
501166583Sflz# ng_fec_create ifn
502166583Sflz# Configure Fast EtherChannel for interface $ifn. Returns 0 if FEC
503166583Sflz# arguments were found and configured; returns !0 otherwise.
504166583Sflzng_fec_create() {
505166583Sflz	 local req_iface iface bogus
506166583Sflz	 req_iface="$1"
507166583Sflz
508166583Sflz	 ngctl shutdown ${req_iface}: > /dev/null 2>&1
509166583Sflz
510166583Sflz	 bogus=""
511166583Sflz	 while true; do
512166583Sflz		 iface=`ng_create_one fec dummy fec`
513166583Sflz		 if [ -z "${iface}" ]; then
514166583Sflz			 exit 2
515166583Sflz		 fi
516166583Sflz		 if [ "${iface}" = "${req_iface}" ]; then
517166583Sflz			 break
518166583Sflz		 fi
519166583Sflz		 bogus="${bogus} ${iface}"
520166583Sflz	 done
521166583Sflz
522166583Sflz	 for iface in ${bogus}; do
523166583Sflz		 ngctl shutdown ${iface}:
524166583Sflz	 done
525166583Sflz}
526166583Sflz
527166583Sflzfec_up() {
528166583Sflz	for i in ${fec_interfaces}; do
529166583Sflz		ng_fec_create $i
530166583Sflz		for j in `get_if_var $i fecconfig_IF`; do
531166583Sflz			case ${j} in
532100282Sdougb			'')
533100282Sdougb				continue
534100282Sdougb				;;
535100282Sdougb			*)
536166583Sflz				ngctl msg ${i}: add_iface "\"${j}\""
537100282Sdougb				;;
538100282Sdougb			esac
539100282Sdougb		done
540166583Sflz	done
541100282Sdougb}
542100282Sdougb
543113674Smtm#
544113674Smtm# ipx_up ifn
545113674Smtm# Configure any IPX addresses for interface $ifn. Returns 0 if IPX
546113674Smtm# arguments were found and configured; returns 1 otherwise.
547113674Smtm#
548113674Smtmipx_up()
549100280Sgordon{
550113674Smtm	ifn="$1"
551157706Sbrooks	ifconfig_args=`get_if_var $ifn ifconfig_IF_ipx`
552113674Smtm	if [ -n "${ifconfig_args}" ]; then
553113674Smtm		ifconfig ${ifn} ${ifconfig_args}
554113674Smtm		return 0
55585831Sdes	fi
556113674Smtm	return 1
557113674Smtm}
55885831Sdes
559116029Smtm# ipx_down ifn
560116029Smtm#	Remove IPX addresses for interface $ifn. Returns 0 if IPX
561116029Smtm#	addresses were found and unconfigured. It returns 1, otherwise.
562113674Smtm#
563116029Smtmipx_down()
564116029Smtm{
565116100Smtm	[ -z "$1" ] && return 1
566116100Smtm	_ifs="^"
567116100Smtm	_ret=1
568116100Smtm
569161386Sbrooks	ifexists $1 || return 1
570161386Sbrooks
571116100Smtm	ipxList="`ifconfig $1 | grep 'ipx ' | tr "\n" "$_ifs"`"
572116100Smtm
573116100Smtm	oldifs="$IFS"
574116100Smtm	IFS="$_ifs"
575116100Smtm	for _ipx in $ipxList ; do
576116100Smtm		# get rid of extraneous line
577116100Smtm		[ -z "$_ipx" ] && break
578116100Smtm
579116100Smtm		_ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'`
580116100Smtm
581116100Smtm		IFS="$oldifs"
582116100Smtm		ifconfig $1 ${_ipx} delete
583116100Smtm		IFS="$_ifs"
584116100Smtm		_ret=0
585116100Smtm	done
586116100Smtm	IFS="$oldifs"
587116100Smtm
588116100Smtm	return $_ret
589116029Smtm}
590116029Smtm
591137070Spjd# ifnet_rename
592137070Spjd#	Rename all requested interfaces.
593116029Smtm#
594137070Spjdifnet_rename()
595137070Spjd{
596137070Spjd
597138386Srse	_ifn_list="`ifconfig -l`"
598137070Spjd	[ -z "$_ifn_list" ] && return 0
599137070Spjd	for _if in ${_ifn_list} ; do
600157706Sbrooks		_ifname=`get_if_var $_if ifconfig_IF_name`
601137070Spjd		if [ ! -z "$_ifname" ]; then
602137070Spjd			ifconfig $_if name $_ifname
603137070Spjd		fi
604137070Spjd	done
605137070Spjd	return 0
606137070Spjd}
607137070Spjd
608137070Spjd#
609113674Smtm# list_net_interfaces type
610113674Smtm#	List all network interfaces. The type of interface returned
611113674Smtm#	can be controlled by the type argument. The type
612113674Smtm#	argument can be any of the following:
613113674Smtm#		nodhcp - all interfaces, excluding DHCP configured interfaces
614113674Smtm#		dhcp   - list only DHCP configured interfaces
615113674Smtm#	If no argument is specified all network interfaces are output.
616134429Syar#	Note that the list will include cloned interfaces if applicable.
617134429Syar#	Cloned interfaces must already exist to have a chance to appear
618134429Syar#	in the list if ${network_interfaces} is set to `auto'.
619113674Smtm#
620113674Smtmlist_net_interfaces()
621113674Smtm{
622113674Smtm	type=$1
62365532Snectar
624149726Sbrooks	# Get a list of ALL the interfaces and make lo0 first if it's there.
62551231Ssheldonh	#
62651231Ssheldonh	case ${network_interfaces} in
62751231Ssheldonh	[Aa][Uu][Tt][Oo])
628149401Sbrooks		_prefix=''
629149401Sbrooks		_autolist="`ifconfig -l`"
630149726Sbrooks		_lo=
631149401Sbrooks		for _if in ${_autolist} ; do
632149401Sbrooks			if autoif $_if; then
633149726Sbrooks				if [ "$_if" = "lo0" ]; then
634149726Sbrooks					_lo="lo0 "
635149726Sbrooks				else
636149726Sbrooks					_tmplist="${_tmplist}${_prefix}${_if}"
637149726Sbrooks					[ -z "$_prefix" ] && _prefix=' '
638149726Sbrooks				fi
639149401Sbrooks			fi
640149401Sbrooks		done
641149726Sbrooks		_tmplist="${_lo}${_tmplist}"
64251231Ssheldonh		;;
64383677Sbrooks	*)
644149401Sbrooks		_tmplist="${network_interfaces} ${cloned_interfaces}"
64583677Sbrooks		;;
64651231Ssheldonh	esac
64749122Sbrian
648113674Smtm	if [ -z "$type" ]; then
649113674Smtm		echo $_tmplist
650113674Smtm		return 0
651113674Smtm	fi
65249122Sbrian
653138385Srse	# Separate out dhcp and non-dhcp interfaces
654113674Smtm	#
655113674Smtm	_aprefix=
656134376Syar	_bprefix=
657113674Smtm	for _if in ${_tmplist} ; do
658147684Sbrooks		if dhcpif $_if; then
659113674Smtm			_dhcplist="${_dhcplist}${_aprefix}${_if}"
660113674Smtm			[ -z "$_aprefix" ] && _aprefix=' '
661157706Sbrooks		elif [ -n "`_ifconfig_getargs $_if`" ]; then
662113674Smtm			_nodhcplist="${_nodhcplist}${_bprefix}${_if}"
663113674Smtm			[ -z "$_bprefix" ] && _bprefix=' '
664147684Sbrooks		fi
66554458Sobrien	done
66651231Ssheldonh
667113674Smtm	case "$type" in
668113674Smtm	nodhcp)
669113674Smtm		echo $_nodhcplist
670113674Smtm		;;
671113674Smtm	dhcp)
672113674Smtm		echo $_dhcplist
673113674Smtm		;;
674113674Smtm	esac
675130151Sschweikh	return 0
67625184Sjkh}
677114942Sume
678114942Sumehexdigit()
679114942Sume{
680114942Sume	if [ $1 -lt 10 ]; then
681114942Sume		echo $1
682114942Sume	else
683114942Sume		case $1 in
684114942Sume		10)	echo a ;;
685114942Sume		11)	echo b ;;
686114942Sume		12)	echo c ;;
687114942Sume		13)	echo d ;;
688114942Sume		14)	echo e ;;
689114942Sume		15)	echo f ;;
690114942Sume		esac
691114942Sume	fi
692114942Sume}
693114942Sume
694114942Sumehexprint()
695114942Sume{
696114942Sume	val=$1
697114942Sume	str=''
698114942Sume
699114942Sume	dig=`hexdigit $((${val} & 15))`
700114942Sume	str=${dig}${str}
701114942Sume	val=$((${val} >> 4))
702114942Sume	while [ ${val} -gt 0 ]; do
703114942Sume		dig=`hexdigit $((${val} & 15))`
704114942Sume		str=${dig}${str}
705114942Sume		val=$((${val} >> 4))
706114942Sume	done
707114942Sume
708114942Sume	echo ${str}
709114942Sume}
710114942Sume
711114942Sume# Setup the interfaces for IPv6
712114942Sumenetwork6_interface_setup()
713114942Sume{
714114942Sume	interfaces=$*
715114942Sume	rtsol_interfaces=''
716114942Sume	case ${ipv6_gateway_enable} in
717114942Sume	[Yy][Ee][Ss])
718114942Sume		rtsol_available=no
719114942Sume		;;
720114942Sume	*)
721114942Sume		rtsol_available=yes
722114942Sume		;;
723114942Sume	esac
724114942Sume	for i in $interfaces; do
725114942Sume		rtsol_interface=yes
726157706Sbrooks		prefix=`get_if_var $i ipv6_prefix_IF`
727114942Sume		if [ -n "${prefix}" ]; then
728114942Sume			rtsol_available=no
729114942Sume			rtsol_interface=no
730114942Sume			laddr=`network6_getladdr $i`
731114942Sume			hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'`
732114942Sume			for j in ${prefix}; do
733114942Sume				address=$j\:${hostid}
734114942Sume				ifconfig $i inet6 ${address} prefixlen 64 alias
735114942Sume
736114942Sume				case ${ipv6_gateway_enable} in
737114942Sume				[Yy][Ee][Ss])
738114942Sume					# subnet-router anycast address
739114942Sume					# (rfc2373)
740114942Sume					ifconfig $i inet6 $j:: prefixlen 64 \
741114942Sume						alias anycast
742114942Sume					;;
743114942Sume				esac
744114942Sume			done
745114942Sume		fi
746157706Sbrooks		ipv6_ifconfig=`get_if_var $i ipv6_ifconfig_IF`
747114942Sume		if [ -n "${ipv6_ifconfig}" ]; then
748114942Sume			rtsol_available=no
749114942Sume			rtsol_interface=no
750114942Sume			ifconfig $i inet6 ${ipv6_ifconfig} alias
751114942Sume		fi
752114942Sume
753114942Sume		if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ]
754114942Sume		then
755114942Sume			case ${i} in
756163759Smlaier			lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*|pflog[0-9]*|pfsync[0-9]*)
757114942Sume				;;
758114942Sume			*)
759114942Sume				rtsol_interfaces="${rtsol_interfaces} ${i}"
760114942Sume				;;
761114942Sume			esac
762114942Sume		else
763114942Sume			ifconfig $i inet6
764114942Sume		fi
765114942Sume	done
766114942Sume
767114942Sume	if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then
768114942Sume		# Act as endhost - automatically configured.
769114942Sume		# You can configure only single interface, as
770114942Sume		# specification assumes that autoconfigured host has
771114942Sume		# single interface only.
772114942Sume		sysctl net.inet6.ip6.accept_rtadv=1
773114942Sume		set ${rtsol_interfaces}
774114942Sume		ifconfig $1 up
775118666Sume		rtsol ${rtsol_flags} $1
776114942Sume	fi
777114942Sume
778114942Sume	for i in $interfaces; do
779114942Sume		alias=0
780114942Sume		while : ; do
781157706Sbrooks			ipv6_ifconfig=`get_if_var $i ipv6_ifconfig_IF_alias${alias}`
782114942Sume			if [ -z "${ipv6_ifconfig}" ]; then
783114942Sume				break;
784114942Sume			fi
785114942Sume			ifconfig $i inet6 ${ipv6_ifconfig} alias
786114942Sume			alias=$((${alias} + 1))
787114942Sume		done
788114942Sume	done
789114942Sume}
790114942Sume
791114942Sume# Setup IPv6 to IPv4 mapping
792114942Sumenetwork6_stf_setup()
793114942Sume{
794114942Sume	case ${stf_interface_ipv4addr} in
795114942Sume	[Nn][Oo] | '')
796114942Sume		;;
797114942Sume	*)
798114942Sume		# assign IPv6 addr and interface route for 6to4 interface
799114942Sume		stf_prefixlen=$((16+${stf_interface_ipv4plen:-0}))
800114942Sume		OIFS="$IFS"
801114942Sume		IFS=".$IFS"
802114942Sume		set ${stf_interface_ipv4addr}
803114942Sume		IFS="$OIFS"
804114942Sume		hexfrag1=`hexprint $(($1*256 + $2))`
805114942Sume		hexfrag2=`hexprint $(($3*256 + $4))`
806114942Sume		ipv4_in_hexformat="${hexfrag1}:${hexfrag2}"
807114942Sume		case ${stf_interface_ipv6_ifid} in
808114942Sume		[Aa][Uu][Tt][Oo] | '')
809114942Sume			for i in ${ipv6_network_interfaces}; do
810114942Sume				laddr=`network6_getladdr ${i}`
811114942Sume				case ${laddr} in
812114942Sume				'')
813114942Sume					;;
814114942Sume				*)
815114942Sume					break
816114942Sume					;;
817114942Sume				esac
818114942Sume			done
819114942Sume			stf_interface_ipv6_ifid=`expr "${laddr}" : \
820114942Sume						      'fe80::\(.*\)%\(.*\)'`
821114942Sume			case ${stf_interface_ipv6_ifid} in
822114942Sume			'')
823114942Sume				stf_interface_ipv6_ifid=0:0:0:1
824114942Sume				;;
825114942Sume			esac
826114942Sume			;;
827114942Sume		esac
828114942Sume		ifconfig stf0 create >/dev/null 2>&1
829114942Sume		ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \
830114942Sume			prefixlen ${stf_prefixlen}
831114942Sume		# disallow packets to malicious 6to4 prefix
832114942Sume		route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject
833114942Sume		route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject
834114942Sume		route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject
835114942Sume		route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject
836114942Sume		;;
837114942Sume	esac
838114942Sume}
839114942Sume
840114942Sume# Setup static routes
841114942Sumenetwork6_static_routes_setup()
842114942Sume{
843114942Sume	# Set up any static routes.
844114942Sume	case ${ipv6_defaultrouter} in
845114942Sume	[Nn][Oo] | '')
846114942Sume		;;
847114942Sume	*)
848114942Sume		ipv6_static_routes="default ${ipv6_static_routes}"
849114942Sume		ipv6_route_default="default ${ipv6_defaultrouter}"
850114942Sume		;;
851114942Sume	esac
852114942Sume	case ${ipv6_static_routes} in
853114942Sume	[Nn][Oo] | '')
854114942Sume		;;
855114942Sume	*)
856114942Sume		for i in ${ipv6_static_routes}; do
857157706Sbrooks			ipv6_route_args=`get_if_var $i ipv6_route_IF`
858114942Sume			route add -inet6 ${ipv6_route_args}
859114942Sume		done
860114942Sume		;;
861114942Sume	esac
862114942Sume}
863114942Sume
864114942Sume# Setup faith
865114942Sumenetwork6_faith_setup()
866114942Sume{
867114942Sume	case ${ipv6_faith_prefix} in
868114942Sume	[Nn][Oo] | '')
869114942Sume		;;
870114942Sume	*)
871114942Sume		sysctl net.inet6.ip6.keepfaith=1
872114942Sume		ifconfig faith0 create >/dev/null 2>&1
873114942Sume		ifconfig faith0 up
874114942Sume		for prefix in ${ipv6_faith_prefix}; do
875114942Sume			prefixlen=`expr "${prefix}" : ".*/\(.*\)"`
876114942Sume			case ${prefixlen} in
877114942Sume			'')
878114942Sume				prefixlen=96
879114942Sume				;;
880114942Sume			*)
881114942Sume				prefix=`expr "${prefix}" : \
882114942Sume					     "\(.*\)/${prefixlen}"`
883114942Sume				;;
884114942Sume			esac
885114942Sume			route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1
886114942Sume			route change -inet6 ${prefix} -prefixlen ${prefixlen} \
887114942Sume				-ifp faith0
888114942Sume		done
889114942Sume		;;
890114942Sume	esac
891114942Sume}
892114942Sume
893114942Sume# Install the "default interface" to kernel, which will be used
894114942Sume# as the default route when there's no router.
895114942Sumenetwork6_default_interface_setup()
896114942Sume{
897114942Sume	# Choose IPv6 default interface if it is not clearly specified.
898114942Sume	case ${ipv6_default_interface} in
899114942Sume	'')
900114942Sume		for i in ${ipv6_network_interfaces}; do
901114942Sume			case $i in
902114942Sume			lo0|faith[0-9]*)
903114942Sume				continue
904114942Sume				;;
905114942Sume			esac
906114942Sume			laddr=`network6_getladdr $i exclude_tentative`
907114942Sume			case ${laddr} in
908114942Sume			'')
909114942Sume				;;
910114942Sume			*)
911114942Sume				ipv6_default_interface=$i
912114942Sume				break
913114942Sume				;;
914114942Sume			esac
915114942Sume		done
916114942Sume		;;
917114942Sume	esac
918114942Sume
919114942Sume	# Disallow unicast packets without outgoing scope identifiers,
920114942Sume	# or route such packets to a "default" interface, if it is specified.
921114942Sume	route add -inet6 fe80:: -prefixlen 10 ::1 -reject
922114942Sume	case ${ipv6_default_interface} in
923114942Sume	[Nn][Oo] | '')
924114942Sume		route add -inet6 ff02:: -prefixlen 16 ::1 -reject
925114942Sume		;;
926114942Sume	*)
927114942Sume		laddr=`network6_getladdr ${ipv6_default_interface}`
928114942Sume		route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \
929114942Sume			-cloning
930114942Sume
931114942Sume		# Disable installing the default interface with the
932114942Sume		# case net.inet6.ip6.forwarding=0 and
933114942Sume		# net.inet6.ip6.accept_rtadv=0, due to avoid conflict
934114942Sume		# between the default router list and the manual
935114942Sume		# configured default route.
936114942Sume		case ${ipv6_gateway_enable} in
937114942Sume		[Yy][Ee][Ss])
938114942Sume			;;
939114942Sume		*)
940114942Sume			if [ `sysctl -n net.inet6.ip6.accept_rtadv` -eq 1 ]
941114942Sume			then
942114942Sume				ndp -I ${ipv6_default_interface}
943114942Sume			fi
944114942Sume			;;
945114942Sume		esac
946114942Sume		;;
947114942Sume	esac
948114942Sume}
949114942Sume
950114942Sumenetwork6_getladdr()
951114942Sume{
952114942Sume	ifconfig $1 2>/dev/null | while read proto addr rest; do
953114942Sume		case ${proto} in
954114942Sume		inet6)
955114942Sume			case ${addr} in
956114942Sume			fe80::*)
957114942Sume				if [ -z "$2" ]; then
958114942Sume					echo ${addr}
959114942Sume					return
960114942Sume				fi
961114942Sume				case ${rest} in
962114942Sume				*tentative*)
963114942Sume					continue
964114942Sume					;;
965114942Sume				*)
966114942Sume					echo ${addr}
967114942Sume					return
968114942Sume				esac
969114942Sume			esac
970114942Sume		esac
971114942Sume	done
972114942Sume}
973